diff options
author | Ken Moore <ken@ixsystems.com> | 2017-03-03 14:25:29 -0500 |
---|---|---|
committer | Ken Moore <ken@ixsystems.com> | 2017-03-03 14:25:29 -0500 |
commit | e51eb7f9b51dc29be83a00abf2ebf95cc17d0ba7 (patch) | |
tree | 65276d138bec55ca4a37e5788269aaf027eb0a9f /src-qt5/core/libLumina | |
parent | Update the .gitignore file a bit. (diff) | |
download | lumina-e51eb7f9b51dc29be83a00abf2ebf95cc17d0ba7.tar.gz lumina-e51eb7f9b51dc29be83a00abf2ebf95cc17d0ba7.tar.bz2 lumina-e51eb7f9b51dc29be83a00abf2ebf95cc17d0ba7.zip |
Another large batch of updates to the Native Window "plumbing":
1) Handle all property changes in bulk groups for efficiency
2) Add simplification functions for changing single properties.
3) Automatically prune redundant property settings from signals
4) Add another property or two, and simplify the number of "extra" signals/functions for non-property changes/requests.
5) Starting cleaning up the new NativeWindowSystem class to use the new plumbing, and get it ready for the XCB "guts" to be copied in.
Diffstat (limited to 'src-qt5/core/libLumina')
-rw-r--r-- | src-qt5/core/libLumina/NativeWindow.cpp | 39 | ||||
-rw-r--r-- | src-qt5/core/libLumina/NativeWindow.h | 28 | ||||
-rw-r--r-- | src-qt5/core/libLumina/NativeWindowSystem.cpp | 20 | ||||
-rw-r--r-- | src-qt5/core/libLumina/NativeWindowSystem.h | 21 | ||||
-rw-r--r-- | src-qt5/core/libLumina/RootSubWindow.cpp | 43 | ||||
-rw-r--r-- | src-qt5/core/libLumina/RootSubWindow.h | 2 | ||||
-rw-r--r-- | src-qt5/core/libLumina/RootWindow.cpp | 4 | ||||
-rw-r--r-- | src-qt5/core/libLumina/RootWindow.h | 4 |
8 files changed, 112 insertions, 49 deletions
diff --git a/src-qt5/core/libLumina/NativeWindow.cpp b/src-qt5/core/libLumina/NativeWindow.cpp index bcdc30d0..97131b52 100644 --- a/src-qt5/core/libLumina/NativeWindow.cpp +++ b/src-qt5/core/libLumina/NativeWindow.cpp @@ -31,12 +31,43 @@ QVariant NativeWindow::property(NativeWindow::Property prop){ } void NativeWindow::setProperty(NativeWindow::Property prop, QVariant val){ - if(prop == NativeWindow::None){ return; } + if(prop == NativeWindow::None || hash.value(prop)==val){ return; } hash.insert(prop, val); - emit PropertyChanged(prop, val); + emit PropertiesChanged(QList<NativeWindow::Property>() << prop, QList<QVariant>() << val); +} + +void NativeWindow::setProperties(QList<NativeWindow::Property> props, QList<QVariant> vals){ + for(int i=0; i<props.length(); i++){ + if(i>=vals.length()){ props.removeAt(i); i--; continue; } //no corresponding value for this propertu + if(props[i] == NativeWindow::None || (hash.value(props[i]) == vals[i]) ){ props.removeAt(i); vals.removeAt(i); i--; continue; } //Invalid property or identical value + hash.insert(props[i], vals[i]); + } + emit PropertiesChanged(props, vals); } void NativeWindow::requestProperty(NativeWindow::Property prop, QVariant val){ - if(prop == NativeWindow::None){ return; } - emit RequestPropertyChange(winid, prop, val); + if(prop == NativeWindow::None || hash.value(prop)==val ){ return; } + emit RequestPropertiesChange(winid, QList<NativeWindow::Property>() << prop, QList<QVariant>() << val); +} + +void NativeWindow::requestProperties(QList<NativeWindow::Property> props, QList<QVariant> vals){ + //Verify/adjust inputs as needed + for(int i=0; i<props.length(); i++){ + if(i>=vals.length()){ props.removeAt(i); i--; continue; } //no corresponding value for this property + if(props[i] == NativeWindow::None || hash.value(props[i])==vals[i] ){ props.removeAt(i); vals.removeAt(i); i--; continue; } //Invalid property or identical value + } + emit RequestPropertiesChange(winid, props, vals); +} + +// ==== PUBLIC SLOTS === +void NativeWindow::requestClose(){ + emit RequestClose(winid); +} + +void NativeWindow::requestKill(){ + emit RequestKill(winid); +} + +void NativeWindow::requestPing(){ + emit RequestPing(winid); } diff --git a/src-qt5/core/libLumina/NativeWindow.h b/src-qt5/core/libLumina/NativeWindow.h index 03d7e27d..fbdf9e1b 100644 --- a/src-qt5/core/libLumina/NativeWindow.h +++ b/src-qt5/core/libLumina/NativeWindow.h @@ -42,10 +42,18 @@ public: States, /*QList<NativeWindow::State> : Current state of the window */ WinTypes, /*QList<NativeWindow::Type> : Current type of window (typically does not change)*/ WinActions, /*QList<NativeWindow::Action> : Current actions that the window allows (Managed/set by the WM)*/ + FrameExtents, /*QList<int> : [Left, Right, Top, Bottom] in pixels */ Active, /*bool*/ Visible /*bool*/ }; + static QList<NativeWindow::Property> allProperties(){ + //Return all the available properties (excluding "None") + QList<NativeWindow::Property> props; + props << MinSize << MaxSize << Size << GlobalPos << Title << ShortTitle << Icon << Name << Workspace \ + << States << WinTypes << WinActions << Active << Visible; + return props; + }; NativeWindow(WId id); ~NativeWindow(); @@ -55,7 +63,14 @@ public: QVariant property(NativeWindow::Property); void setProperty(NativeWindow::Property, QVariant); + void setProperties(QList<NativeWindow::Property>, QList<QVariant>); void requestProperty(NativeWindow::Property, QVariant); + void requestProperties(QList<NativeWindow::Property>, QList<QVariant>); + +public slots: + void requestClose(); //ask the app to close the window (may/not depending on activity) + void requestKill(); //ask the WM to kill the app associated with this window (harsh - only use if not responding) + void requestPing(); //ask the app if it is still active (a WindowNotResponding signal will get sent out if there is no reply); private: QHash <NativeWindow::Property, QVariant> hash; @@ -64,18 +79,17 @@ private: signals: //General Notifications - void PropertyChanged(NativeWindow::Property, QVariant); - void RequestPropertyChange(WId, NativeWindow::Property, QVariant); + void PropertiesChanged(QList<NativeWindow::Property>, QList<QVariant>); + void RequestPropertiesChange(WId, QList<NativeWindow::Property>, QList<QVariant>); void WindowClosed(WId); + void WindowNotResponding(WId); //will be sent out if a window does not respond to a ping request //Action Requests (not automatically emitted - typically used to ask the WM to do something) //Note: "WId" should be the NativeWindow id() - void RequestActivate(WId); //Activate the window void RequestClose(WId); //Close the window - void RequestSetVisible(WId, bool); //Minimize/restore visiblility - void RequestSetGeometry(WId, QRect); //Register the location/size of the window - void RequestSetFrameExtents(WId, QList<int>); //Register the size of the frame around the window [Left,Right, Top,Bottom] in pixels - + void RequestKill(WId); //Kill the window/app (usually from being unresponsive) + void RequestPing(WId); //Verify that the window is still active (such as not closing after a request + // System Tray Icon Embed/Unembed Requests //void RequestEmbed(WId, QWidget*); //void RequestUnEmbed(WId, QWidget*); diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index c8e6d483..c2af0560 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -152,8 +152,9 @@ bool NativeWindowSystem::start(){ //Initialize all the extra atoms that the EWMH object does not have if( !obj->init_ATOMS() ){ return false; } } //Done with private object init - - return true; + bool ok = obj->register_wm(); + if(ok){ ok = obj->startSystemTray(); } + return ok; } void NativeWindowSystem::stop(){ @@ -165,6 +166,7 @@ void NativeWindowSystem::UpdateWindowProperties(NativeWindow* win, QList< Native } + // === PUBLIC SLOTS === //These are the slots which are only used by the desktop system itself or the NativeWindowEventFilter void NativeWindowSystem::RegisterVirtualRoot(WId){ @@ -176,6 +178,10 @@ void NativeWindowSystem::NewWindowDetected(WId){ } +void NativeWindowSystem::NewTrayWindowDetected(WId){ + +} + void NativeWindowSystem::WindowCloseDetected(WId){ } @@ -202,6 +208,16 @@ void NativeWindowSystem::NewMouseRelease(int buttoncode){ // === PRIVATE SLOTS === //These are the slots which are built-in and automatically connected when a new NativeWindow is created +void NativeWindowSystem::RequestPropertiesChange(WId win, QList<NativeWindow::Property> props, QList<QVariant> vals){ + //Find the window object associated with this id + bool istraywin = false; //just in case we care later if it is a tray window or a regular window + NativeWindow *WIN = findWindow(win); + if(WIN==0){ istraywin = true; WIN = findTrayWindow(win); } + if(WIN==0){ return; } //invalid window ID - no longer available + //Now make any changes as needed + +} + void NativeWindowSystem::RequestActivate(WId){ } diff --git a/src-qt5/core/libLumina/NativeWindowSystem.h b/src-qt5/core/libLumina/NativeWindowSystem.h index ef169059..b26400a6 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.h +++ b/src-qt5/core/libLumina/NativeWindowSystem.h @@ -33,7 +33,7 @@ private: } //Now define a simple private_objects class so that each implementation - // has a storage container for placing private objects as needed + // has a storage container for defining/placing private objects as needed class p_objects; p_objects* obj; @@ -51,6 +51,7 @@ public: //General-purpose listing functions QList<NativeWindow*> currentWindows(){ return NWindows; } + QList<NativeWindow*> currentTrayWindows(){ return TWindows; } public slots: //These are the slots which are typically only used by the desktop system itself or the NativeWindowEventFilter @@ -64,21 +65,21 @@ public slots: //NativeWindowEventFilter interactions void NewWindowDetected(WId); //will automatically create the new NativeWindow object + void NewTrayWindowDetected(WId); //will automatically create the new NativeWindow object void WindowCloseDetected(WId); //will update the lists and make changes if needed - void WindowPropertyChanged(WId, NativeWindow::Property); //will rescan the window and update the object as needed - void NewKeyPress(int keycode); - void NewKeyRelease(int keycode); - void NewMousePress(int buttoncode); - void NewMouseRelease(int buttoncode); + void WindowPropertiesChanged(WId, NativeWindow::Property); //will rescan the window and update the object as needed + void NewKeyPress(int keycode, WId win = 0); + void NewKeyRelease(int keycode, WId win = 0); + void NewMousePress(int buttoncode, WId win = 0); + void NewMouseRelease(int buttoncode, WId win = 0); void CheckDamageID(WId); private slots: //These are the slots which are built-in and automatically connected when a new NativeWindow is created - void RequestActivate(WId); + void RequestPropertiesChange(WId, QList<NativeWindow::Property>, QList<QVariant>); void RequestClose(WId); - void RequestSetVisible(WId, bool); - void RequestSetGeometry(WId, QRect); - void RequestSetFrameExtents(WId, QList<int>); //[Left,Right,Top,Bottom] in pixels + void RequestKill(WId); + void RequestPing(WId); signals: void NewWindowAvailable(NativeWindow*); diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index 7ec25a71..ba682077 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -21,12 +21,9 @@ RootSubWindow::RootSubWindow(QWidget *root, NativeWindow *win) : QFrame(root){ closing = false; WinWidget = QWidget::createWindowContainer( WIN->window(), this); initWindowFrame(); - LoadProperties( QList< NativeWindow::Property>() << NativeWindow::Title << NativeWindow::Icon \ - << NativeWindow::MinSize << NativeWindow::MaxSize << NativeWindow::Size ); + LoadProperties( NativeWindow::allProperties() ); //Hookup the signals/slots - connect(WIN, SIGNAL(PropertyChanged(NativeWindow::Property, QVariant)), this, SLOT(propertyChanged(NativeWindow::Property, QVariant))); - //Make sure the visibily property only gets loaded after it is added to the root area - propertyChanged(NativeWindow::Visible, WIN->property(NativeWindow::Visible)); + connect(WIN, SIGNAL(PropertiesChanged(QList<NativeWindow::Property>, QList<QVariant>)), this, SLOT(PropertiesChanged(QList<NativeWindow::Property>, QList<QVariant>))); } RootSubWindow::~RootSubWindow(){ @@ -167,9 +164,11 @@ void RootSubWindow::initWindowFrame(){ } void RootSubWindow::LoadProperties( QList< NativeWindow::Property> list){ + QList<QVariant> vals; for(int i=0; i<list.length(); i++){ - propertyChanged( list[i], WIN->property(list[i]) ); + vals << WIN->property(list[i]); } + propertiesChanged(list, vals); } // === PUBLIC SLOTS === @@ -189,7 +188,7 @@ void RootSubWindow::toggleMaximize(){ } void RootSubWindow::triggerClose(){ - WIN->emit RequestClose(WIN->id()); + WIN->requestClose(); } void RootSubWindow::toggleSticky(){ @@ -197,7 +196,7 @@ void RootSubWindow::toggleSticky(){ } void RootSubWindow::activate(){ - WIN->emit RequestActivate(WIN->id()); + WIN->requestProperty(NativeWindow::Active, true); } //Mouse Interactivity @@ -223,37 +222,39 @@ void RootSubWindow::startResizing(){ // === PRIVATE SLOTS === -void RootSubWindow::propertyChanged(NativeWindow::Property prop, QVariant val){ - if(val.isNull()){ return; } //not the same as a default/empty value - the property has just not been set yet - qDebug() << "Set Window Property:" << prop << val; - switch(prop){ +void RootSubWindow::propertiesChanged(QList<NativeWindow::Property> props, QList<QVariant> vals){ + for(int i=0; i<props.length() && i<vals.length(); i++){ + if(vals[i].isNull()){ return; } //not the same as a default/empty value - the property has just not been set yet + //qDebug() << "Set Window Property:" << props[i] << vals[i]; + switch(props[i]){ case NativeWindow::Visible: - if(val.toBool()){ this->show(); } + if(vals[i].toBool()){ this->show(); } else{ this->hide(); } break; case NativeWindow::Title: - titleLabel->setText(val.toString()); + titleLabel->setText(vals[i].toString()); break; case NativeWindow::Icon: - otherB->setIcon(val.value< QIcon>()); + otherB->setIcon(vals[i].value< QIcon>()); break; case NativeWindow::Size: - WinWidget->resize(val.toSize()); + WinWidget->resize(vals[i].toSize()); break; case NativeWindow::MinSize: - WinWidget->setMinimumSize(val.toSize()); + WinWidget->setMinimumSize(vals[i].toSize()); break; case NativeWindow::MaxSize: - WinWidget->setMaximumSize(val.toSize()); + WinWidget->setMaximumSize(vals[i].toSize()); break; case NativeWindow::Active: - WinWidget->setFocus(); + if(vals[i].toBool()){ WinWidget->setFocus(); } break; /*case NativeWindow::WindowFlags: this->setWindowFlags( val.value< Qt::WindowFlags >() ); break;*/ default: - qDebug() << "Window Property Unused:" << prop << val; + qDebug() << "Window Property Unused:" << props[i] << vals[i]; + } } } @@ -358,7 +359,7 @@ void RootSubWindow::mouseMoveEvent(QMouseEvent *ev){ void RootSubWindow::mouseReleaseEvent(QMouseEvent *ev){ //Check for a right-click event - qDebug() << "Frame Mouse Release Event"; + //qDebug() << "Frame Mouse Release Event"; ev->accept(); if( (activeState==Normal) && (titleBar->geometry().contains(ev->pos())) && (ev->button()==Qt::RightButton) ){ otherM->popup(ev->globalPos()); diff --git a/src-qt5/core/libLumina/RootSubWindow.h b/src-qt5/core/libLumina/RootSubWindow.h index 12feaea6..8c5ef2b8 100644 --- a/src-qt5/core/libLumina/RootSubWindow.h +++ b/src-qt5/core/libLumina/RootSubWindow.h @@ -66,7 +66,7 @@ public slots: void startResizing(); private slots: - void propertyChanged(NativeWindow::Property, QVariant); + void propertiesChanged(QList<NativeWindow::Property>, QList<QVariant>); protected: void mousePressEvent(QMouseEvent*); diff --git a/src-qt5/core/libLumina/RootWindow.cpp b/src-qt5/core/libLumina/RootWindow.cpp index 0758653b..b1f740d3 100644 --- a/src-qt5/core/libLumina/RootWindow.cpp +++ b/src-qt5/core/libLumina/RootWindow.cpp @@ -11,7 +11,7 @@ #include <QDebug> // === PUBLIC === -RootWindow::RootWindow() : QMdiArea(0){ //QWidget(0, Qt::Window | Qt::BypassWindowManagerHint | Qt::WindowStaysOnBottomHint){ +RootWindow::RootWindow() : QWidget(0, Qt::Window | Qt::BypassWindowManagerHint | Qt::WindowStaysOnBottomHint){ qRegisterMetaType<WId>("WId"); autoResizeTimer = 0; } @@ -191,7 +191,7 @@ void RootWindow::CloseWindow(WId win){ void RootWindow::paintEvent(QPaintEvent *ev){ //qDebug() << "RootWindow: PaintEvent:" << ev->rect(); //<< QDateTime::currentDateTime()->toString(QDateTime::ShortDate); bool found = false; - QPainter painter(this->viewport()); + QPainter painter(this); for(int i=0; i<WALLPAPERS.length(); i++){ if(WALLPAPERS[i].area.intersects(ev->rect()) ){ found = true; diff --git a/src-qt5/core/libLumina/RootWindow.h b/src-qt5/core/libLumina/RootWindow.h index 5d3bc963..0ae248b5 100644 --- a/src-qt5/core/libLumina/RootWindow.h +++ b/src-qt5/core/libLumina/RootWindow.h @@ -18,12 +18,12 @@ #include <QTimer> #include <QApplication> #include <QPaintEvent> -#include <QMdiArea> +//#include <QMdiArea> #include "RootSubWindow.h" #include "NativeWindow.h" -class RootWindow : public QMdiArea{ +class RootWindow : public QWidget{ Q_OBJECT public: enum ScaleType{ SolidColor, Stretch, Full, Fit, Center, Tile, BottomLeft, BottomRight, BottomCenter, \ |