From 223e28da7a0c67b5ad1e844dbbbd6f4bd7557977 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 31 Jan 2017 14:12:29 -0500 Subject: Get a lot more of Lumina2 working. Now the window embed systems are functional, with 2-way create/show/hide/close detection. Windows do not detect/resize as needed yet though. --- src-qt5/core/lumina-desktop-unified/LSession.cpp | 11 +++--- .../core/lumina-desktop-unified/global-includes.h | 1 + .../core/lumina-desktop-unified/lumina-desktop.pro | 1 + .../src-desktop/ContextMenu.cpp | 7 ++-- .../src-desktop/ContextMenu.h | 1 - .../src-events/LXcbEventFilter.cpp | 41 ++++++++++++++++++---- .../src-events/LXcbEventFilter.h | 5 ++- .../src-screensaver/SSBaseWidget.cpp | 3 +- 8 files changed, 53 insertions(+), 17 deletions(-) (limited to 'src-qt5/core/lumina-desktop-unified') diff --git a/src-qt5/core/lumina-desktop-unified/LSession.cpp b/src-qt5/core/lumina-desktop-unified/LSession.cpp index cb0144d5..706c6006 100644 --- a/src-qt5/core/lumina-desktop-unified/LSession.cpp +++ b/src-qt5/core/lumina-desktop-unified/LSession.cpp @@ -41,7 +41,7 @@ LSession::LSession(int &argc, char ** argv) : LSingleApplication(argc, argv, "lu //this->setAttribute(Qt::AA_UseHighDpiPixmaps); //allow pixmaps to be scaled up as well as down //Now initialize the global objects (but do not start them yet) - Lumina::EFILTER = new EventFilter(); //Need the XCB Event filter + Lumina::EFILTER = new EventFilter(); //Need the XCB Event filter first Lumina::SETTINGS = new DesktopSettings(); Lumina::SS = new LScreenSaver(); //Lumina::WM = new LWindowManager(); @@ -60,7 +60,10 @@ LSession::LSession(int &argc, char ** argv) : LSingleApplication(argc, argv, "lu //Setup the various connections between the global classes // NOTE: Most of these connections will only become "active" as the global objects get started during the setupSession routine connect(Lumina::ROOTWIN, SIGNAL(RegisterVirtualRoot(WId)), Lumina::EFILTER, SLOT(RegisterVirtualRoot(WId)) ); - + connect(Lumina::EFILTER, SIGNAL(WindowCreated(WId)), Lumina::ROOTWIN, SLOT(NewWindow(WId)) ); + connect(Lumina::EFILTER, SIGNAL(WindowClosed(WId)), Lumina::ROOTWIN, SLOT(CloseWindow(WId)) ); + connect(Lumina::EFILTER, SIGNAL(WindowHidden(WId)), Lumina::ROOTWIN, SLOT(HideWindow(WId)) ); + connect(Lumina::EFILTER, SIGNAL(WindowShown(WId)), Lumina::ROOTWIN, SLOT(ShowWindow(WId)) ); } //end check for primary process } @@ -176,7 +179,7 @@ void LSession::setupSession(){ Lumina::SHORTCUTS->start(); //Startup the shortcut handler now //for(int i=0; i<4; i++){ LSession::processEvents(); } //Again, just a few event loops here so thing can settle before we close the splash screen //launchStartupApps(); - //QTimer::singleShot(500, this, SLOT(launchStartupApps()) ); + QTimer::singleShot(500, this, SLOT(launchStartupApps()) ); splash.hide(); LSession::processEvents(); splash.close(); @@ -279,7 +282,7 @@ void LSession::launchStartupApps(){ LOS::setScreenBrightness( tmp ); qDebug() << " - - Screen Brightness:" << QString::number(tmp)+"%"; } - QProcess::startDetached("nice lumina-open -autostart-apps"); + //ExternalProcess::launch("nice lumina-open -autostart-apps"); //Re-load the screen brightness and volume settings from the previous session // Wait until after the XDG-autostart functions, since the audio system might be started that way diff --git a/src-qt5/core/lumina-desktop-unified/global-includes.h b/src-qt5/core/lumina-desktop-unified/global-includes.h index 6a753cd1..ed687917 100644 --- a/src-qt5/core/lumina-desktop-unified/global-includes.h +++ b/src-qt5/core/lumina-desktop-unified/global-includes.h @@ -57,6 +57,7 @@ #include #include #include +#include // Standard C includes #include diff --git a/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro b/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro index 497ce635..1de8308d 100644 --- a/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro +++ b/src-qt5/core/lumina-desktop-unified/lumina-desktop.pro @@ -17,6 +17,7 @@ include(../libLumina/LuminaSingleApplication.pri) include(../libLumina/LuminaThemes.pri) include(../libLumina/DesktopSettings.pri) include(../libLumina/RootWindow.pri) +include(../libLumina/ExternalProcess.pri) #include all the main individual source groups include(src-screensaver/screensaver.pri) diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.cpp b/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.cpp index fa4af5ba..e363af01 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.cpp @@ -24,7 +24,7 @@ void DesktopContextMenu::UpdateMenu(){ for(int i=0; iaddAction(LXDG::findIcon("utilities-terminal",""), tr("Terminal"))->setWhatsThis("lumina-open -terminal"); } else if(items[i]=="lockdesktop"){ this->addAction(LXDG::findIcon("system-lock-screen",""), tr("Lock Session"), this, SIGNAL(LockSession()) ); } - else if(items[i]=="filemanager"){ this->addAction( LXDG::findIcon("user-home",""), tr("Browse Files"))->setWhatsThis("lumina-open ~"); } + else if(items[i]=="filemanager"){ this->addAction( LXDG::findIcon("user-home",""), tr("Browse Files"))->setWhatsThis("lumina-open \""+QDir::homePath()+"\""); } //else if(items[i]=="applications"){ this->addMenu( LSession::handle()->applicationMenu() ); } else if(items[i]=="line"){ this->addSeparator(); } //else if(items[i]=="settings"){ this->addMenu( LSession::handle()->settingsMenu() ); } @@ -34,7 +34,7 @@ void DesktopContextMenu::UpdateMenu(){ QString file = items[i].section("::::",1,1).simplified(); XDGDesktop xdgf(file);// = LXDG::loadDesktopFile(file, ok); if(xdgf.type!=XDGDesktop::BAD){ - this->addAction( LXDG::findIcon(xdgf.icon,""), xdgf.name)->setWhatsThis(file); + this->addAction( LXDG::findIcon(xdgf.icon,""), xdgf.name)->setWhatsThis("lumina-open \""+file+"\""); }else{ qDebug() << "Could not load application file:" << file; } @@ -86,8 +86,9 @@ void DesktopContextMenu::start(){ // === PRIVATE SLOTS === void DesktopContextMenu::LaunchAction(QAction *act){ if(act->whatsThis().isEmpty() || act->parent()!=this ){ return; } + qDebug() << "Launch Menu Action:" << act->whatsThis(); QString cmd = act->whatsThis(); - emit LaunchApplication(cmd); + ExternalProcess::launch(cmd); } void DesktopContextMenu::showMenu(const QPoint &pt){ diff --git a/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.h b/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.h index 1a4befc9..8b0509fb 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.h +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.h @@ -30,7 +30,6 @@ private slots: void showMenu(const QPoint&); signals: - void LaunchApplication(QString); //cmd to run void LockSession(); void showLeaveDialog(); }; diff --git a/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp b/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp index 4a192aa4..6660e41e 100644 --- a/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp @@ -132,13 +132,13 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag //============================== case XCB_KEY_PRESS: //This is a keyboard key press - qDebug() << "Key Press Event"; + //qDebug() << "Key Press Event"; stopevent = BlockInputEvent( ((xcb_key_press_event_t *) ev)->root ); //use the main "root" window - not the child widget if(!stopevent){ obj->emit KeyPressed( InputWindow(((xcb_key_press_event_t *) ev)->root), ((xcb_key_press_event_t *) ev)->detail ); } break; case XCB_KEY_RELEASE: //This is a keyboard key release - qDebug() << "Key Release Event"; + //qDebug() << "Key Release Event"; stopevent = BlockInputEvent( ((xcb_key_release_event_t *) ev)->root ); //use the main "root" window - not the child widget if(!stopevent){ obj->emit KeyReleased( InputWindow(((xcb_key_release_event_t *) ev)->root), ((xcb_key_release_event_t *) ev)->detail ); } break; @@ -183,24 +183,27 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag break; //============================== case XCB_MAP_NOTIFY: + qDebug() << "Window Map Event:" << ((xcb_map_notify_event_t *)ev)->window; + obj->emit WindowShown( ((xcb_map_notify_event_t *)ev)->window); break; //This is just a notification that a window was mapped - nothing needs to change here case XCB_MAP_REQUEST: qDebug() << "Window Map Request Event"; - obj->emit ModifyWindow( ((xcb_map_request_event_t *) ev)->window, Lumina::Show); + SetupNewWindow( ((xcb_map_request_event_t *) ev) ); break; //============================== case XCB_CREATE_NOTIFY: - qDebug() << "Window Create Event"; + //qDebug() << "Window Create Event"; break; //============================== case XCB_UNMAP_NOTIFY: - qDebug() << "Window Unmap Event"; - obj->emit ModifyWindow( ((xcb_unmap_notify_event_t *)ev)->window, Lumina::Hide); + qDebug() << "Window Unmap Event:" << ((xcb_unmap_notify_event_t *)ev)->window; + obj->emit WindowHidden( ((xcb_unmap_notify_event_t *)ev)->window); break; //============================== case XCB_DESTROY_NOTIFY: - qDebug() << "Window Closed Event"; + qDebug() << "Window Closed Event:" << ((xcb_destroy_notify_event_t *)ev)->window; if( !rmTrayApp( ((xcb_destroy_notify_event_t *) ev)->window ) ){ + qDebug() <<" - Non-tray window"; obj->emit WindowClosed( ((xcb_destroy_notify_event_t *) ev)->window ); } break; @@ -389,3 +392,27 @@ void XCBEventFilter::checkDamageID(WId id){ //Could check for window damage ID's - but we should not need this } } + +// WINDOW HANDLING FUNCTIONS +void XCBEventFilter::SetupNewWindow(xcb_map_request_event_t *ev){ + WId win = ev->window; + + bool ok = obj->XCB->WM_ManageWindow(win, true); + //Quick check if this is a transient window if we could not manage it directly + if(!ok){ + WId tran = obj->XCB->WM_ICCCM_GetTransientFor(win); + if(tran!=win && tran!=0){ + win = tran; + ok = obj->XCB->WM_ManageWindow(win); + } + } + qDebug() << "New Window:" << win << obj->XCB->WM_ICCCM_GetClass(win) << " Managed:" << ok; + obj->XCB->WM_Set_Active_Window(win); + //Determing the requested geometry/location/management within the event, + // and forward that on to the graphical embedding side of the WM + + + obj->emit WindowCreated(win); + //TEMPORARY FOR DEBUGGING + //obj->XCB->WM_ShowWindow(win); +} diff --git a/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.h b/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.h index 9e76ba53..30dc925d 100644 --- a/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.h +++ b/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.h @@ -69,7 +69,9 @@ public slots: signals: void NewInputEvent(); - void NewManagedWindow(WId); + void WindowCreated(WId); + void WindowShown(WId); + void WindowHidden(WId); void WindowClosed(WId); void ModifyWindow(WId win, Lumina::WindowAction); @@ -120,6 +122,7 @@ private: void checkDamageID(WId); //Longer Event handling functions + void SetupNewWindow(xcb_map_request_event_t *ev); //bool ParseKeyPressEvent(); //bool ParseKeyReleaseEvent(); //bool ParseButtonPressEvent(); diff --git a/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp b/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp index 83b82ff8..9ad31f5c 100644 --- a/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-screensaver/SSBaseWidget.cpp @@ -19,6 +19,7 @@ SSBaseWidget::SSBaseWidget(QWidget *parent, QSettings *set) : QWidget(parent){ this->setObjectName("LuminaBaseSSWidget"); ANIM = 0; this->setMouseTracking(true); + plugType="none"; } SSBaseWidget::~SSBaseWidget(){ @@ -51,7 +52,7 @@ void SSBaseWidget::startPainting(){ //Now list all the various plugins and start them appropriately QString style; if(cplug=="none"){ - style = "background: transparent;"; //show the underlying black parent widget + style = "background: black;"; //show the underlying black parent widget }else{ style = "background: black;"; } -- cgit From 11918f54e194807c8ed6988c70306d883c8e9054 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Wed, 1 Feb 2017 11:52:09 -0500 Subject: Add a new "NativeWindow" class to the library. This is a pure Qt container class for setting/announcing changes to native windows on the system. This allows the WM class (XCB/Wayland-specific) to simply adjust each window object as needed, and the interface (pure Qt) will automatically adjust as needed. NOTE: Still need to adjust the LXCBEventFilter to use this new class, but the root window and rootsubwindow classes are all setup to use it. --- src-qt5/core/lumina-desktop-unified/LSession.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src-qt5/core/lumina-desktop-unified') diff --git a/src-qt5/core/lumina-desktop-unified/LSession.cpp b/src-qt5/core/lumina-desktop-unified/LSession.cpp index 706c6006..ea72bc7b 100644 --- a/src-qt5/core/lumina-desktop-unified/LSession.cpp +++ b/src-qt5/core/lumina-desktop-unified/LSession.cpp @@ -24,7 +24,7 @@ RootWindow* Lumina::ROOTWIN = 0; XDGDesktopList* Lumina::APPLIST = 0; LShortcutEvents* Lumina::SHORTCUTS = 0; -LSession::LSession(int &argc, char ** argv) : LSingleApplication(argc, argv, "lumina-desktop"){ +LSession::LSession(int &argc, char ** argv) : LSingleApplication(argc, argv, "lumina-desktop-unified"){ //Initialize the global objects to null pointers mediaObj = 0; //private object used for playing login/logout chimes if(this->isPrimaryProcess()){ -- cgit From 014ce3d9363b15912a53cc8885358b0436b3bb27 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Wed, 1 Feb 2017 16:13:52 -0500 Subject: Another large batch of work on Lumina2: The NativeWindow intermediary seems to be working really well, now just to start adding the the various event detection parsing in to modify that object on-demand. There is still a window focus issue too - the setActive routine is not properly setting that window to have focus yet - need to examine further. --- src-qt5/core/lumina-desktop-unified/LSession.cpp | 6 +- .../core/lumina-desktop-unified/global-includes.h | 1 + .../src-events/LXcbEventFilter.cpp | 95 +++++++++++++++++++--- .../src-events/LXcbEventFilter.h | 21 +++-- 4 files changed, 100 insertions(+), 23 deletions(-) (limited to 'src-qt5/core/lumina-desktop-unified') diff --git a/src-qt5/core/lumina-desktop-unified/LSession.cpp b/src-qt5/core/lumina-desktop-unified/LSession.cpp index ea72bc7b..1c8d3c45 100644 --- a/src-qt5/core/lumina-desktop-unified/LSession.cpp +++ b/src-qt5/core/lumina-desktop-unified/LSession.cpp @@ -29,6 +29,7 @@ LSession::LSession(int &argc, char ** argv) : LSingleApplication(argc, argv, "lu mediaObj = 0; //private object used for playing login/logout chimes if(this->isPrimaryProcess()){ //Setup the global registrations + qsrand(QDateTime::currentMSecsSinceEpoch()); this->setApplicationName("Lumina Desktop Environment"); this->setApplicationVersion( LDesktopUtils::LuminaDesktopVersion() ); this->setOrganizationName("LuminaDesktopEnvironment"); @@ -60,10 +61,7 @@ LSession::LSession(int &argc, char ** argv) : LSingleApplication(argc, argv, "lu //Setup the various connections between the global classes // NOTE: Most of these connections will only become "active" as the global objects get started during the setupSession routine connect(Lumina::ROOTWIN, SIGNAL(RegisterVirtualRoot(WId)), Lumina::EFILTER, SLOT(RegisterVirtualRoot(WId)) ); - connect(Lumina::EFILTER, SIGNAL(WindowCreated(WId)), Lumina::ROOTWIN, SLOT(NewWindow(WId)) ); - connect(Lumina::EFILTER, SIGNAL(WindowClosed(WId)), Lumina::ROOTWIN, SLOT(CloseWindow(WId)) ); - connect(Lumina::EFILTER, SIGNAL(WindowHidden(WId)), Lumina::ROOTWIN, SLOT(HideWindow(WId)) ); - connect(Lumina::EFILTER, SIGNAL(WindowShown(WId)), Lumina::ROOTWIN, SLOT(ShowWindow(WId)) ); + connect(Lumina::EFILTER, SIGNAL(WindowCreated(NativeWindow*)), Lumina::ROOTWIN, SLOT(NewWindow(NativeWindow*)) ); } //end check for primary process } diff --git a/src-qt5/core/lumina-desktop-unified/global-includes.h b/src-qt5/core/lumina-desktop-unified/global-includes.h index ed687917..867076db 100644 --- a/src-qt5/core/lumina-desktop-unified/global-includes.h +++ b/src-qt5/core/lumina-desktop-unified/global-includes.h @@ -58,6 +58,7 @@ #include #include #include +#include // Standard C includes #include diff --git a/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp b/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp index 6660e41e..27e94737 100644 --- a/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp @@ -71,11 +71,22 @@ unsigned int EventFilter::currentWorkspace(){ return XCB->CurrentWorkspace(); } +QList EventFilter::currentWindows(){ + return static_cast(EF)->windowList(); +} + // === PUBLIC SLOTS === void EventFilter::RegisterVirtualRoot(WId id){ XCB->WM_Set_Virtual_Roots( QList() << id ); } +void EventFilter::TryCloseWindow(WId id){ + XCB->WM_CloseWindow(id, false); //do not force close +} + +void EventFilter::TryActivateWindow(WId id){ + XCB->WM_Set_Active_Window(id); +} //============================= // XCBEventFilter Class //============================= @@ -183,11 +194,16 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag break; //============================== case XCB_MAP_NOTIFY: - qDebug() << "Window Map Event:" << ((xcb_map_notify_event_t *)ev)->window; - obj->emit WindowShown( ((xcb_map_notify_event_t *)ev)->window); + //qDebug() << "Window Map Event:" << ((xcb_map_notify_event_t *)ev)->window; + if(Lumina::SS->isLocked()){ waitingToShow << ((xcb_map_notify_event_t *)ev)->window ; } + else{ + for(int i=0; iid() == ((xcb_map_notify_event_t *)ev)->window){ windows[i]->setProperty(NativeWindow::Visible, true); break; } + } + } break; //This is just a notification that a window was mapped - nothing needs to change here case XCB_MAP_REQUEST: - qDebug() << "Window Map Request Event"; + //qDebug() << "Window Map Request Event"; SetupNewWindow( ((xcb_map_request_event_t *) ev) ); break; //============================== @@ -196,15 +212,24 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag break; //============================== case XCB_UNMAP_NOTIFY: - qDebug() << "Window Unmap Event:" << ((xcb_unmap_notify_event_t *)ev)->window; - obj->emit WindowHidden( ((xcb_unmap_notify_event_t *)ev)->window); + //qDebug() << "Window Unmap Event:" << ((xcb_unmap_notify_event_t *)ev)->window; + if(waitingToShow.contains(((xcb_unmap_notify_event_t *)ev)->window)){ waitingToShow.removeAll(((xcb_unmap_notify_event_t *)ev)->window); } + for(int i=0; iid() == ((xcb_unmap_notify_event_t *)ev)->window){ windows[i]->setProperty(NativeWindow::Visible, false); break; } + } break; //============================== case XCB_DESTROY_NOTIFY: - qDebug() << "Window Closed Event:" << ((xcb_destroy_notify_event_t *)ev)->window; + //qDebug() << "Window Closed Event:" << ((xcb_destroy_notify_event_t *)ev)->window; if( !rmTrayApp( ((xcb_destroy_notify_event_t *) ev)->window ) ){ - qDebug() <<" - Non-tray window"; - obj->emit WindowClosed( ((xcb_destroy_notify_event_t *) ev)->window ); + //qDebug() <<" - Non-tray window"; + for(int i=0; iid() == ((xcb_destroy_notify_event_t *)ev)->window){ + windows[i]->emit WindowClosed(windows[i]->id()); + QTimer::singleShot(500, windows.takeAt(i), SLOT(deleteLater()) ); //give a few moments first, then clean up the object + break; + } + } } break; //============================== @@ -218,7 +243,7 @@ bool XCBEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag //============================== case XCB_PROPERTY_NOTIFY: //qDebug() << "Property Notify Event:"; - //qDebug() << " - Given Window:" << ((xcb_property_notify_event_t*)ev)->window; + ParsePropertyEvent((xcb_property_notify_event_t*)ev); break; //============================== case XCB_CLIENT_MESSAGE: @@ -308,6 +333,10 @@ bool XCBEventFilter::stopSystemTray(){ return true; } +QList XCBEventFilter::windowList(){ + return windows; +} + //========= // PRIVATE //========= @@ -409,10 +438,50 @@ void XCBEventFilter::SetupNewWindow(xcb_map_request_event_t *ev){ qDebug() << "New Window:" << win << obj->XCB->WM_ICCCM_GetClass(win) << " Managed:" << ok; obj->XCB->WM_Set_Active_Window(win); //Determing the requested geometry/location/management within the event, - // and forward that on to the graphical embedding side of the WM + NativeWindow *nwin = new NativeWindow(win); + QObject::connect(nwin, SIGNAL(RequestClose(WId)), obj, SLOT(TryCloseWindow(WId)) ); + QObject::connect(nwin, SIGNAL(RequestActivate(WId)), obj, SLOT(TryActivateWindow(WId)) ); + windows << nwin; + bool show_now = !Lumina::SS->isLocked(); + if(!show_now){ waitingToShow << win; } //add to the list to get set visible later + //populate the native window settings as they are right now + nwin->setProperty(NativeWindow::Active, true); + nwin->setProperty(NativeWindow::Visible, show_now); + nwin->setProperty(NativeWindow::Workspace, obj->XCB->CurrentWorkspace()); + icccm_size_hints hints = obj->XCB->WM_ICCCM_GetNormalHints(win); + if(!hints.isValid()){ hints = obj->XCB->WM_ICCCM_GetSizeHints(win); } + if(hints.validMinSize()){ nwin->setProperty(NativeWindow::MinSize, QSize(hints.min_width,hints.min_height)); } + if(hints.validMaxSize()){ nwin->setProperty(NativeWindow::MaxSize, QSize(hints.max_width,hints.max_height)); } + if(hints.validBaseSize()){ nwin->setProperty(NativeWindow::Size, QSize(hints.base_width,hints.base_height)); } + else if(hints.validSize()){ nwin->setProperty(NativeWindow::Size, QSize(hints.width, hints.height)); } + nwin->setProperty(NativeWindow::Icon, obj->XCB->WM_Get_Icon(win)); + QString title = obj->XCB->WM_Get_Name(win); + if(title.isEmpty()){ title = obj->XCB->WM_Get_Visible_Name(win); } + if(title.isEmpty()){ title = obj->XCB->WM_ICCCM_GetName(win); } + nwin->setProperty(NativeWindow::Title, title); + title = obj->XCB->WM_Get_Icon_Name(win); + if(title.isEmpty()){ title = obj->XCB->WM_Get_Visible_Icon_Name(win); } + if(title.isEmpty()){ title = obj->XCB->WM_ICCCM_GetIconName(win); } + nwin->setProperty(NativeWindow::ShortTitle, title); + obj->emit WindowCreated(nwin); +} - obj->emit WindowCreated(win); - //TEMPORARY FOR DEBUGGING - //obj->XCB->WM_ShowWindow(win); +void XCBEventFilter::ParsePropertyEvent(xcb_property_notify_event_t *ev){ + //First find the NativeWindow associated with the event + NativeWindow *nwin = 0; + for(int i=0; iid() == ev->window){ nwin = windows[i]; } + } + if(nwin==0){ return; } //unmanaged window - ignore this event + qDebug() << "Got Property Event:" << ev->window << ev->atom; + //Now determine which properties are getting changed, and update the native window as appropriate + if(ev->atom == obj->XCB->EWMH._NET_WM_NAME){ + qDebug() << " - Found _NET_WM_NAME atom"; + nwin->setProperty(NativeWindow::Title, obj->XCB->WM_Get_Name(nwin->id())); + }else if(ev->atom == obj->XCB->EWMH._NET_WM_ICON){ + qDebug() << " - Found _NET_WM_ICON atom"; + nwin->setProperty(NativeWindow::Icon, obj->XCB->WM_Get_Icon(nwin->id())); + } + } diff --git a/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.h b/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.h index 30dc925d..9f2530e8 100644 --- a/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.h +++ b/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.h @@ -60,20 +60,21 @@ public: //Public Session Interaction Functions unsigned int currentWorkspace(); + + //Public Window Management Lists + QList currentWindows(); //always returned in creation-order (oldest first) //Variables/Functions needed by the XCBEventFilter class only (not really needed by anything else) LXCB *XCB; //used to interact with the X11 graphics subsystem public slots: void RegisterVirtualRoot(WId); + void TryCloseWindow(WId); + void TryActivateWindow(WId); signals: void NewInputEvent(); - void WindowCreated(WId); - void WindowShown(WId); - void WindowHidden(WId); - void WindowClosed(WId); - void ModifyWindow(WId win, Lumina::WindowAction); + void WindowCreated(NativeWindow*); // Session Signals void WorkspaceChanged(unsigned int); @@ -101,6 +102,9 @@ public: bool startSystemTray(); bool stopSystemTray(); + //Window List Functions + QList windowList(); + private: EventFilter *obj; QList WinNotifyAtoms, SysNotifyAtoms; @@ -121,14 +125,19 @@ private: bool rmTrayApp(WId); //returns "true" if the tray app was found and removed void checkDamageID(WId); + //Window List Variables + QList windows; + QList waitingToShow; + //Longer Event handling functions void SetupNewWindow(xcb_map_request_event_t *ev); + //bool ParseKeyPressEvent(); //bool ParseKeyReleaseEvent(); //bool ParseButtonPressEvent(); //bool ParseButtonReleaseEvent(); //bool ParseMotionEvent(); - //bool ParsePropertyEvent(); + void ParsePropertyEvent(xcb_property_notify_event_t *ev); //bool ParseClientMessageEvent(); //bool ParseDestroyEvent(); //bool ParseConfigureEvent(); -- cgit From 5597b2a289a8bea9ddae94b699afa370f3b0300c Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Fri, 3 Feb 2017 13:40:36 -0500 Subject: Commit my work-in-progress on a new NativeWindowSystem class. This will be a replacement for the current LuminaX11 class usage in the desktop, with a generic Qt5 API that talks to the X11/Wayland subsystems in the background. --- .../lumina-desktop-unified/src-events/LXcbEventFilter.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src-qt5/core/lumina-desktop-unified') diff --git a/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp b/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp index 27e94737..7031f3df 100644 --- a/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-events/LXcbEventFilter.cpp @@ -53,6 +53,7 @@ void EventFilter::start(){ XCB->setupEventsForRoot(WMFlag); XCB->WM_Set_Supporting_WM(WMFlag); + XCB->WM_Set_Root_Supported(); //announce all the various options that the WM supports static_cast(EF)->startSystemTray(); QCoreApplication::instance()->flush(); @@ -482,6 +483,18 @@ void XCBEventFilter::ParsePropertyEvent(xcb_property_notify_event_t *ev){ }else if(ev->atom == obj->XCB->EWMH._NET_WM_ICON){ qDebug() << " - Found _NET_WM_ICON atom"; nwin->setProperty(NativeWindow::Icon, obj->XCB->WM_Get_Icon(nwin->id())); + }else if(ev->atom == obj->XCB->EWMH._NET_WM_ICON_NAME){ + qDebug() << " - Found _NET_WM_ICON_NAME atom"; + nwin->setProperty(NativeWindow::ShortTitle, obj->XCB->WM_Get_Icon_Name(nwin->id())); + }else if(ev->atom == obj->XCB->EWMH._NET_WM_DESKTOP){ + qDebug() << " - Found _NET_WM_DESKTOP atom"; + nwin->setProperty(NativeWindow::Workspace, obj->XCB->WM_Get_Desktop(nwin->id())); + }else if(ev->atom == obj->XCB->EWMH._NET_WM_WINDOW_TYPE ){ + qDebug() << " - Found _NET_WM_WINDOW_TYPE atom"; + + }else if( ev->atom == obj->XCB->EWMH._NET_WM_STATE){ + qDebug() << " - Found _NET_WM_STATE atom"; + } } -- cgit