From c6ac1a490e8f7889d594b2641a4d4e8e8b8f5c60 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Wed, 30 Aug 2017 15:24:15 -0400 Subject: A bit more for Lumina2: 1) Get a simple "DISABLE_COMPOSITING" flag working in the NativeEmbedWidget class, and disable the compositing right now (still too many issues with using GPU-accellerated drivers) 2) Get a WM settings file created and add options for "focusFollowsMouse" (true by default) and "raiseOnFocus" (false by default). 3) Add a way for the root window to announce mouse cursor movements to the screensaver, bypassing the XCB event system (can't seem to get it to report those events anyway right now). Probably a better method anyway since moving the mouse won't cause billions of events in a short time then. With this, it seems like all the mouse cursor management systems are up and running. I have not tested using shortcuts combined with mouse buttons yet though.... --- src-qt5/core/libLumina/DesktopSettings.cpp | 5 ++- src-qt5/core/libLumina/DesktopSettings.h | 2 +- src-qt5/core/libLumina/NativeEmbedWidget.cpp | 66 ++++++++++++++-------------- src-qt5/core/libLumina/NativeWindow.pri | 3 +- src-qt5/core/libLumina/RootSubWindow.cpp | 5 ++- src-qt5/core/libLumina/RootSubWindow.h | 1 + src-qt5/core/libLumina/RootWindow.cpp | 19 ++++++-- src-qt5/core/libLumina/RootWindow.h | 3 ++ 8 files changed, 62 insertions(+), 42 deletions(-) diff --git a/src-qt5/core/libLumina/DesktopSettings.cpp b/src-qt5/core/libLumina/DesktopSettings.cpp index b051a4e8..d1a898b2 100644 --- a/src-qt5/core/libLumina/DesktopSettings.cpp +++ b/src-qt5/core/libLumina/DesktopSettings.cpp @@ -230,7 +230,7 @@ QList< DesktopSettings::File > DesktopSettings::filesForRunMode(RunMode mode){ // Note that the "System" file is always ignored here - that is specially loaded QList< DesktopSettings::File > tmp; if(mode == DesktopSettings::UserFull || mode == DesktopSettings::SystemFull){ - tmp << DesktopSettings::Favorites << DesktopSettings::Environment << DesktopSettings::Session << DesktopSettings::Desktop << DesktopSettings::Panels << DesktopSettings::Plugins << DesktopSettings::Keys << DesktopSettings::ContextMenu << DesktopSettings::Animation << DesktopSettings::ScreenSaver; + tmp << DesktopSettings::Favorites << DesktopSettings::Environment << DesktopSettings::Session << DesktopSettings::Desktop << DesktopSettings::Panels << DesktopSettings::Plugins << DesktopSettings::Keys << DesktopSettings::ContextMenu << DesktopSettings::Animation << DesktopSettings::ScreenSaver << DesktopSettings::WM; }else if(runmode == DesktopSettings::SystemInterface){ tmp << DesktopSettings::Favorites << DesktopSettings::Environment << DesktopSettings::Session; } @@ -262,7 +262,8 @@ QString DesktopSettings::rel_path(DesktopSettings::File file){ name="plugins"; break; case DesktopSettings::ScreenSaver: name="screensaver"; break; - + case DesktopSettings::WM: + name="windows"; break; } return FILEPREFIX+name+".conf"; } diff --git a/src-qt5/core/libLumina/DesktopSettings.h b/src-qt5/core/libLumina/DesktopSettings.h index 9bff6bc9..efb3776e 100644 --- a/src-qt5/core/libLumina/DesktopSettings.h +++ b/src-qt5/core/libLumina/DesktopSettings.h @@ -25,7 +25,7 @@ class DesktopSettings : public QObject{ Q_OBJECT public: - enum File{ System, Favorites, Environment, Session, Desktop, Panels, Plugins, ContextMenu, Keys, Animation, ScreenSaver}; + enum File{ System, Favorites, Environment, Session, Desktop, Panels, Plugins, ContextMenu, Keys, Animation, ScreenSaver, WM}; //Changes to this enum need to be added to the "filesForRunMode()" and "rel_path()" functions as well DesktopSettings(QObject *parent = 0); diff --git a/src-qt5/core/libLumina/NativeEmbedWidget.cpp b/src-qt5/core/libLumina/NativeEmbedWidget.cpp index 84b0473e..6a420d25 100644 --- a/src-qt5/core/libLumina/NativeEmbedWidget.cpp +++ b/src-qt5/core/libLumina/NativeEmbedWidget.cpp @@ -19,7 +19,7 @@ #include #include -#define DISABLE_COMPOSITING false +#define DISABLE_COMPOSITING true /*inline xcb_render_pictformat_t get_pictformat(){ static xcb_render_pictformat_t format = 0; @@ -85,10 +85,12 @@ void NativeEmbedWidget::syncWidgetSize(QSize sz){ } void NativeEmbedWidget::hideWindow(){ + qDebug() << "Hide Embed Window"; xcb_unmap_window(QX11Info::connection(), WIN->id()); } void NativeEmbedWidget::showWindow(){ + qDebug() << "Show Embed Window"; xcb_map_window(QX11Info::connection(), WIN->id()); reregisterEvents(); QTimer::singleShot(0,this, SLOT(repaintWindow())); @@ -209,37 +211,31 @@ void NativeEmbedWidget::resume(){ void NativeEmbedWidget::resyncWindow(){ if(WIN==0){ return; } - // Attempt 1 : spec says to send an artificial configure event to the window - /*QRect geom = WIN->geometry(); - //Send an artificial configureNotify event to the window with the global position/size included - xcb_configure_notify_event_t event; - event.x = geom.x() + this->pos().x(); - event.y = geom.y() + this->pos().y(); - event.width = this->width(); - event.height = this->height(); - event.border_width = 0; - event.above_sibling = XCB_NONE; - event.override_redirect = false; - event.window = WIN->id(); - event.event = WIN->id(); - event.response_type = XCB_CONFIGURE_NOTIFY; - xcb_send_event(QX11Info::connection(), false, WIN->id(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY, (const char *) &event); - */ - - // Attempt 2 : Just jitter the window size by 1 pixel really quick so the window knows to update it's geometry - /*QSize sz = this->size(); - uint32_t valList[2] = {(uint32_t) sz.width()-1, (uint32_t) sz.height()}; - uint32_t mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; - xcb_configure_window(QX11Info::connection(), WIN->id(), mask, valList); + if(DISABLE_COMPOSITING){ + // Specs say to send an artificial configure event to the window if the window was reparented into the frame + QPoint loc = this->mapToGlobal( QPoint(0,0)); + //Send an artificial configureNotify event to the window with the global position/size included + xcb_configure_notify_event_t *event = (xcb_configure_notify_event_t*) calloc(32,1); //always 32-byes long, even if we don't need all of it + event->x = loc.x(); + event->y = loc.y(); + event->width = this->width(); + event->height = this->height(); + event->border_width = 0; + event->above_sibling = XCB_NONE; + event->override_redirect = false; + event->window = WIN->id(); + event->event = WIN->id(); + event->response_type = XCB_CONFIGURE_NOTIFY; + xcb_send_event(QX11Info::connection(), false, WIN->id(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY, (char *) event); xcb_flush(QX11Info::connection()); - valList[0] = (uint32_t) sz.width(); - xcb_configure_window(QX11Info::connection(), WIN->id(), mask, valList); - xcb_flush(QX11Info::connection());*/ + free(event); + }else{ + //Window is floating invisibly - make sure it is in the right place + //Make sure the window size is syncronized and visual up to date + syncWinSize(); + QTimer::singleShot(10, this, SLOT(repaintWindow()) ); + } - //Make sure the window size is syncronized and visual up to date - syncWinSize(); - if(DISABLE_COMPOSITING){ showWindow(); } - else{ QTimer::singleShot(10, this, SLOT(repaintWindow()) ); } } void NativeEmbedWidget::repaintWindow(){ @@ -278,9 +274,15 @@ void NativeEmbedWidget::hideEvent(QHideEvent *ev){ } void NativeEmbedWidget::paintEvent(QPaintEvent *ev){ - if(WIN==0 || DISABLE_COMPOSITING){ QWidget::paintEvent(ev); return; } + if(WIN==0 || paused){ return; } //else if( winImage.isNull() ){return; } - else if(paused){ return; } + else if(DISABLE_COMPOSITING){ + // Just make it solid black (underneath the embedded window) + // - only visible when looking through the edge of another window) + QPainter P(this); + P.fillRect(ev->rect(), Qt::black); + return; + } //renderWindowToWidget(WIN->id(), this); //return; //else if(this->size()!=winSize){ QTimer::singleShot(0,this, SLOT(syncWinSize())); return; } //do not paint here - waiting to re-sync the sizes diff --git a/src-qt5/core/libLumina/NativeWindow.pri b/src-qt5/core/libLumina/NativeWindow.pri index e651ab50..c906d6fd 100644 --- a/src-qt5/core/libLumina/NativeWindow.pri +++ b/src-qt5/core/libLumina/NativeWindow.pri @@ -1,7 +1,8 @@ # Files QT *= x11extras -LIBS *= -lc -lxcb -lxcb-ewmh -lxcb-icccm -lxcb-image -lxcb-composite -lxcb-damage -lxcb-util -lxcb-keysyms -lXdamage -lxcb-render -lxcb-render-util +LIBS *= -lc -lxcb -lxcb-ewmh -lxcb-icccm -lxcb-image -lxcb-composite -lxcb-damage -lxcb-util -lxcb-keysyms -lXdamage +#QT *= -lxcb-render -lxcb-render-util SOURCES *= $${PWD}/NativeWindow.cpp \ $${PWD}/NativeWindowSystem.cpp \ diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 29c615c5..cc1a1d2a 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -327,7 +327,7 @@ void RootSubWindow::propertiesChanged(QList props, QList //qDebug() << "RootSubWindow: Property Changed:" << props[i] << vals[i]; switch(props[i]){ case NativeWindow::Visible: - //qDebug() << "Got Visibility Change:" << vals[i] << this->geometry() << WIN->geometry(); + qDebug() << "Got Visibility Change:" << vals[i] << this->geometry() << WIN->geometry(); if(vals[i].toBool()){ loadAnimation( DesktopSettings::instance()->value(DesktopSettings::Animation, "window/appear", "random").toString(), NativeWindow::Visible, vals[i]); } else{ loadAnimation( DesktopSettings::instance()->value(DesktopSettings::Animation, "window/disappear", "random").toString(), NativeWindow::Visible, vals[i]); } break; @@ -373,7 +373,7 @@ void RootSubWindow::propertiesChanged(QList props, QList WinWidget->setMaximumSize(vals[i].toSize()); break; case NativeWindow::Active: - //if(vals[i].toBool()){ WinWidget->raiseWindow(); } + if(vals[i].toBool()){ activate(); } //WinWidget->raiseWindow(); } break; /*case NativeWindow::FrameExtents: qDebug() << " - FRAME CHANGE"; @@ -385,6 +385,7 @@ void RootSubWindow::propertiesChanged(QList props, QList mainLayout->setContentsMargins( vals[i].value< QList >().at(0),vals[i].value< QList >().at(2) - titleLabel->height(),vals[i].value< QList >().at(1),vals[i].value< QList >().at(3)); break;*/ case NativeWindow::WinTypes: + qDebug() << "Got Window Types:" << vals[i].value< QList >(); enableFrame(vals[i].value< QList >().contains(NativeWindow::T_NORMAL) ); break; default: diff --git a/src-qt5/core/libLumina/RootSubWindow.h b/src-qt5/core/libLumina/RootSubWindow.h index d8b8fd33..f87d7733 100644 --- a/src-qt5/core/libLumina/RootSubWindow.h +++ b/src-qt5/core/libLumina/RootSubWindow.h @@ -67,6 +67,7 @@ private: public slots: void giveMouseFocus(){ WinWidget->raiseWindow(); } void removeMouseFocus(){ WinWidget->lowerWindow(); } + void giveKeyboardFocus(){ WIN->requestProperty(NativeWindow::Active, true); } void clientClosed(); void LoadAllProperties(); diff --git a/src-qt5/core/libLumina/RootWindow.cpp b/src-qt5/core/libLumina/RootWindow.cpp index ccda47e8..51e7b1f0 100644 --- a/src-qt5/core/libLumina/RootWindow.cpp +++ b/src-qt5/core/libLumina/RootWindow.cpp @@ -201,17 +201,28 @@ void RootWindow::ChangeWallpaper(QString id, RootWindow::ScaleType scale, QStrin } void RootWindow::checkMouseFocus(){ + QPoint cpos = QCursor::pos(); + if(lastCursorPos != cpos){ emit MouseMoved(); } + lastCursorPos = cpos; QWidget *child = this->childAt(QCursor::pos()); while(child!=0 && child->whatsThis()!="RootSubWindow"){ child = child->parentWidget(); if(child==this){ child = 0;} //end of the line } + if(child==lastActiveMouse){ return; } //nothing new to do //Make sure the child is actually a RootSubWindow if(lastActiveMouse!=0){ lastActiveMouse->removeMouseFocus(); lastActiveMouse = 0; } if(child!=0){ lastActiveMouse = static_cast(child); - lastActiveMouse->giveMouseFocus(); + + if(DesktopSettings::instance()->value(DesktopSettings::WM, "focusFollowsMouse", true).toBool()){ + lastActiveMouse->giveKeyboardFocus(); + if(DesktopSettings::instance()->value(DesktopSettings::WM, "raiseOnFocus", true).toBool()){ + lastActiveMouse->raise(); + } + } + lastActiveMouse->giveMouseFocus(); //always give mouse focus on mouseover } } @@ -228,9 +239,9 @@ void RootWindow::NewWindow(NativeWindow *win){ WINDOWS << subwin; } CheckWindowPosition(win->id(), true); //first-time run - //win->setProperty(NativeWindow::Visible, true); - //win->requestProperty( NativeWindow::Active, true); - win->requestProperties(QList() << NativeWindow::Visible << NativeWindow::Active, QList() << true << true); + win->setProperty(NativeWindow::Visible, true); + win->requestProperty( NativeWindow::Active, true); + //win->requestProperties(QList() << NativeWindow::Visible << NativeWindow::Active, QList() << true << true, true); if(!mouseFocusTimer->isActive()){ mouseFocusTimer->start(); } } diff --git a/src-qt5/core/libLumina/RootWindow.h b/src-qt5/core/libLumina/RootWindow.h index 725a0430..c5cd44a0 100644 --- a/src-qt5/core/libLumina/RootWindow.h +++ b/src-qt5/core/libLumina/RootWindow.h @@ -47,6 +47,7 @@ private: }; QTimer *autoResizeTimer, *mouseFocusTimer; RootSubWindow *lastActiveMouse; + QPoint lastCursorPos; QList WALLPAPERS; void updateScreenPixmap(screeninfo *info); //used for recalculating the wallpaper pixmap based on file/area/scale as needed @@ -83,6 +84,8 @@ signals: void RootResized(QRect); void NewScreens(QStringList); // [screen_id_1, screen_id_2, etc..] void RemovedScreens(QStringList); // [screen_id_1, screen_id_2, etc..] + void WorkspaceChanged(int); + void MouseMoved(); }; -- cgit