diff options
-rw-r--r-- | src-qt5/core/libLumina/NativeEmbedWidget.cpp | 27 | ||||
-rw-r--r-- | src-qt5/core/libLumina/NativeEmbedWidget.h | 1 | ||||
-rw-r--r-- | src-qt5/core/libLumina/NativeWindow.cpp | 4 | ||||
-rw-r--r-- | src-qt5/core/libLumina/NativeWindow.h | 1 | ||||
-rw-r--r-- | src-qt5/core/libLumina/NativeWindowSystem.cpp | 4 | ||||
-rw-r--r-- | src-qt5/core/libLumina/RootSubWindow-animations.cpp | 21 | ||||
-rw-r--r-- | src-qt5/core/libLumina/RootSubWindow.cpp | 53 | ||||
-rw-r--r-- | src-qt5/core/libLumina/RootSubWindow.h | 2 | ||||
-rw-r--r-- | src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.cpp | 22 | ||||
-rw-r--r-- | src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.h | 2 |
10 files changed, 116 insertions, 21 deletions
diff --git a/src-qt5/core/libLumina/NativeEmbedWidget.cpp b/src-qt5/core/libLumina/NativeEmbedWidget.cpp index 6a420d25..21b4494f 100644 --- a/src-qt5/core/libLumina/NativeEmbedWidget.cpp +++ b/src-qt5/core/libLumina/NativeEmbedWidget.cpp @@ -55,7 +55,7 @@ inline void registerClientEvents(WId id){ | XCB_EVENT_MASK_BUTTON_MOTION | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY -// | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT + | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_ENTER_WINDOW) }; @@ -85,15 +85,17 @@ void NativeEmbedWidget::syncWidgetSize(QSize sz){ } void NativeEmbedWidget::hideWindow(){ - qDebug() << "Hide Embed Window"; + //qDebug() << "Hide Embed Window"; xcb_unmap_window(QX11Info::connection(), WIN->id()); } void NativeEmbedWidget::showWindow(){ - qDebug() << "Show Embed Window"; + //qDebug() << "Show Embed Window"; xcb_map_window(QX11Info::connection(), WIN->id()); reregisterEvents(); - QTimer::singleShot(0,this, SLOT(repaintWindow())); + if(!DISABLE_COMPOSITING){ + QTimer::singleShot(0,this, SLOT(repaintWindow())); + } } QImage NativeEmbedWidget::windowImage(QRect geom){ @@ -162,17 +164,17 @@ bool NativeEmbedWidget::embedWindow(NativeWindow *window){ connect(WIN, SIGNAL(VisualChanged()), this, SLOT(repaintWindow()) ); //make sure we repaint the widget on visual change }else{ xcb_reparent_window(QX11Info::connection(), WIN->id(), this->winId(), 0, 0); + registerClientEvents(this->winId()); //child events get forwarded through the frame - watch this for changes too } WIN->addFrameWinID(this->winId()); registerClientEvents(WIN->id()); - //registerClientEvents(this->winId()); //qDebug() << "Events Registered:" << WIN->id() << this->winId(); return true; } bool NativeEmbedWidget::detachWindow(){ xcb_reparent_window(QX11Info::connection(), WIN->id(), QX11Info::appRootWindow(), -1, -1); - WIN = 0; + //WIN = 0; return true; } @@ -197,15 +199,22 @@ void NativeEmbedWidget::lowerWindow(){ // ============== //Pause/resume void NativeEmbedWidget::pause(){ - if(winImage.isNull()){ repaintWindow(); } //make sure we have one image already cached first + if(DISABLE_COMPOSITING){ + this->setVisible(false); + }else{ + if(winImage.isNull()){ repaintWindow(); } //make sure we have one image already cached first + } paused = true; } void NativeEmbedWidget::resume(){ paused = false; syncWinSize(); - //showWindow(); - repaintWindow(); //update the cached image right away + if(DISABLE_COMPOSITING){ + this->setVisible(true); + }else{ + repaintWindow(); //update the cached image right away + } } void NativeEmbedWidget::resyncWindow(){ diff --git a/src-qt5/core/libLumina/NativeEmbedWidget.h b/src-qt5/core/libLumina/NativeEmbedWidget.h index 89d95a6f..5025f692 100644 --- a/src-qt5/core/libLumina/NativeEmbedWidget.h +++ b/src-qt5/core/libLumina/NativeEmbedWidget.h @@ -43,6 +43,7 @@ public: bool embedWindow(NativeWindow *window); bool detachWindow(); bool isEmbedded(); //status of the embed + bool isPaused(){ return paused; } public slots: void raiseWindow(); diff --git a/src-qt5/core/libLumina/NativeWindow.cpp b/src-qt5/core/libLumina/NativeWindow.cpp index 3c76ed00..02cc001e 100644 --- a/src-qt5/core/libLumina/NativeWindow.cpp +++ b/src-qt5/core/libLumina/NativeWindow.cpp @@ -106,6 +106,10 @@ QRect NativeWindow::geometry(){ return geom; } // ==== PUBLIC SLOTS === +void NativeWindow::toggleVisibility(){ + setProperty(NativeWindow::Visible, !property(NativeWindow::Visible).toBool() ); +} + void NativeWindow::requestClose(){ emit RequestClose(winid); } diff --git a/src-qt5/core/libLumina/NativeWindow.h b/src-qt5/core/libLumina/NativeWindow.h index d04815ce..67436259 100644 --- a/src-qt5/core/libLumina/NativeWindow.h +++ b/src-qt5/core/libLumina/NativeWindow.h @@ -78,6 +78,7 @@ public: QRect geometry(); //this returns the "full" geometry of the window (window + frame) public slots: + void toggleVisibility(); 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); diff --git a/src-qt5/core/libLumina/NativeWindowSystem.cpp b/src-qt5/core/libLumina/NativeWindowSystem.cpp index cd2459d3..9d04228d 100644 --- a/src-qt5/core/libLumina/NativeWindowSystem.cpp +++ b/src-qt5/core/libLumina/NativeWindowSystem.cpp @@ -479,7 +479,7 @@ void NativeWindowSystem::ChangeWindowProperties(NativeWindow* win, QList< Native } if(props.contains(NativeWindow::Size) || props.contains(NativeWindow::GlobalPos) ){ - xcb_configure_window_value_list_t valList; + /*xcb_configure_window_value_list_t valList; //valList.x = 0; //Note that this is the relative position - should always be 0,0 relative to the embed widget //valList.y = 0; QSize sz = win->property(NativeWindow::Size).toSize(); @@ -499,7 +499,7 @@ void NativeWindowSystem::ChangeWindowProperties(NativeWindow* win, QList< Native uint16_t mask = 0; mask = mask | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT | XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y; //qDebug() << "Configure window Geometry:" << sz; - xcb_configure_window_aux(QX11Info::connection(), win->id(), mask, &valList); + xcb_configure_window_aux(QX11Info::connection(), win->id(), mask, &valList);*/ } if(props.contains(NativeWindow::Name)){ diff --git a/src-qt5/core/libLumina/RootSubWindow-animations.cpp b/src-qt5/core/libLumina/RootSubWindow-animations.cpp index ac813e3a..b1489ad6 100644 --- a/src-qt5/core/libLumina/RootSubWindow-animations.cpp +++ b/src-qt5/core/libLumina/RootSubWindow-animations.cpp @@ -11,6 +11,9 @@ QStringList RootSubWindow::validAnimations(NativeWindow::Property prop){ QStringList valid; if(prop == NativeWindow::Visible){ valid << "zoom" << "wipe-center-vertical" << "wipe-center-horizontal" << "shade-top" << "shade-right" << "shade-left" << "shade-bottom"; + }else if(prop == NativeWindow::Size){ + //Note: this is used for pretty much all geometry changes to the window where it is visible both before/after animation + valid << "direct"; } return valid; } @@ -20,7 +23,7 @@ void RootSubWindow::loadAnimation(QString name, NativeWindow::Property prop, QVa //Special case - random animation each time if(name=="random"){ QStringList valid = validAnimations(prop); - name = valid.at(qrand()%valid.length()); + if(!valid.isEmpty()){ name = valid.at(qrand()%valid.length()); } } //Now setup the animation if(prop == NativeWindow::Visible){ @@ -68,6 +71,20 @@ void RootSubWindow::loadAnimation(QString name, NativeWindow::Property prop, QVa anim->start(); this->show(); } //end of Visibility animation + else if(prop == NativeWindow::Size){ + //This is pretty much all geometry animations where the window is visible->visible + animResetProp = QVariant(); //reset this - not needed here + anim->setPropertyName("geometry"); + anim->setStartValue(this->geometry()); + anim->setEndValue(nval.toRect()); + /*if(name==""){ + // TO-DO modify the path from beginning->end somehow + }*/ + // Now start the animation + WinWidget->pause(); + anim->start(); + this->show(); + } } void RootSubWindow::animFinished(){ @@ -92,6 +109,6 @@ void RootSubWindow::animFinished(){ } } animResetProp = QVariant(); //clear the variable - WinWidget->resume(); + QTimer::singleShot(10, WinWidget, SLOT(resume()) ); } diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp index cc1a1d2a..36da43c2 100644 --- a/src-qt5/core/libLumina/RootSubWindow.cpp +++ b/src-qt5/core/libLumina/RootSubWindow.cpp @@ -10,6 +10,7 @@ #include <QVBoxLayout> #include <QHBoxLayout> #include <QTimer> +#include <QScreen> #define WIN_BORDER 5 @@ -278,12 +279,44 @@ void RootSubWindow::LoadAllProperties(){ //Button Actions - public so they can be tied to key shortcuts and stuff as well void RootSubWindow::toggleMinimize(){ - WIN->setProperty(NativeWindow::Visible, false); - QTimer::singleShot(2000, this, SLOT(toggleMaximize()) ); + WIN->toggleVisibility(); } void RootSubWindow::toggleMaximize(){ - WIN->setProperty(NativeWindow::Visible, true); + //Get the current screen that this window is on + QList<QScreen*> screens = QApplication::screens(); + QRect rect; + int primaryscreen = 0; //fallback value + for(int i=0; i<screens.length(); i++){ + QRect intersect = screens[i]->geometry().intersected(this->geometry()); + if( (intersect.width()-rect.width() + intersect.height()-rect.height()) > 0){ + rect = intersect; + primaryscreen = i; + } + } + //Now that we have the screen dimensions, lets check/change the window + rect = screens[primaryscreen]->availableGeometry(); + QList< NativeWindow::State > states = WIN->property(NativeWindow::States).value< QList< NativeWindow::State> >(); + if(rect == this->geometry() || states.contains(NativeWindow::S_MAX_VERT) || states.contains(NativeWindow::S_MAX_HORZ)){ + //Already maximized - try to restore it to the previous size/location + if(!lastMaxGeom.isNull()){ + rect = lastMaxGeom; + }else{ + // no last geometry - started out maximized? + // make it half the screen size and centered on the screen + QPoint center = rect.center(); + rect.setWidth( rect.width()/2 ); + rect.setHeight( rect.height()/2 ); + rect.moveTopLeft( center - QPoint(rect.width()/2, rect.height()/2) ); + } + lastMaxGeom = QRect(); //clear this saved geom + }else{ + //Not maximized yet - go ahead and make it so + lastMaxGeom = this->geometry(); //save this for later; + } + qDebug() << "Toggle Maximize:" << this->geometry() << rect; + QString anim_type = DesktopSettings::instance()->value(DesktopSettings::Animation, "window/move", "random").toString(); + loadAnimation(anim_type, NativeWindow::Size, rect); } void RootSubWindow::triggerClose(){ @@ -291,7 +324,13 @@ void RootSubWindow::triggerClose(){ } void RootSubWindow::toggleSticky(){ - + QList< NativeWindow::State> states = WIN->property(NativeWindow::States).value< QList< NativeWindow::State > >(); + if(states.contains(NativeWindow::S_STICKY)){ + states.removeAll(NativeWindow::S_STICKY); + }else{ + states << NativeWindow::S_STICKY; + } + WIN->requestProperty(NativeWindow::States, QVariant::fromValue<QList <NativeWindow::State> >(states) ); } void RootSubWindow::activate(){ @@ -327,7 +366,7 @@ void RootSubWindow::propertiesChanged(QList<NativeWindow::Property> 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; @@ -347,9 +386,9 @@ void RootSubWindow::propertiesChanged(QList<NativeWindow::Property> props, QList props << props.takeAt(i); vals << vals.takeAt(i); i--; - }else if(anim->state() != QPropertyAnimation::Running ){ + }else if(anim->state() != QPropertyAnimation::Running && !WinWidget->isPaused()){ if(WIN->property(NativeWindow::Size).toSize() != WinWidget->size() && activeState==Normal ){ - qDebug() << "Got Direct Geometry Change:" << WIN->geometry(); + //qDebug() << "Got Direct Geometry Change:" << WIN->geometry(); this->setGeometry(WIN->geometry()); } } diff --git a/src-qt5/core/libLumina/RootSubWindow.h b/src-qt5/core/libLumina/RootSubWindow.h index f87d7733..c4dd2e0b 100644 --- a/src-qt5/core/libLumina/RootSubWindow.h +++ b/src-qt5/core/libLumina/RootSubWindow.h @@ -55,7 +55,7 @@ private: QPropertyAnimation *anim; QVariant animResetProp; QTimer *moveTimer; - QRect lastGeom; //frame coordinates + QRect lastGeom, lastMaxGeom; //frame coordinates void initWindowFrame(); void enableFrame(bool); 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 1b5512ff..143a3667 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.cpp +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.cpp @@ -64,6 +64,17 @@ void DesktopContextMenu::UpdateMenu(bool fast){ this->addAction(LXDG::findIcon("system-log-out",""), tr("Leave"), this, SIGNAL(showLeaveDialog()) ); } +// === PRIVATE === +void DesktopContextMenu::AddWindowToMenu(NativeWindow *win){ + QString label = win->property(NativeWindow::ShortTitle).toString(); + if(label.isEmpty()){ label = win->property(NativeWindow::Title).toString(); } + if(label.isEmpty()){ label = win->property(NativeWindow::Name).toString(); } + QAction *tmp = winMenu->addAction( win->property(NativeWindow::Icon).value<QIcon>(), label, win, SLOT(toggleVisibility()) ); + //Need to change the visual somehow to indicate whether it is visible or not + //bool visible = win->property(NativeWindow::Visible).toBool(); + // TODO +} + // === PUBLIC === DesktopContextMenu::DesktopContextMenu(QWidget *parent) : QMenu(parent){ if(parent!=0){ @@ -150,4 +161,15 @@ void DesktopContextMenu::updateWinMenu(){ winMenu = new QMenu(this); winMenu->setTitle( tr("Task Manager") ); } + winMenu->clear(); + QList<NativeWindow*> wins = Lumina::NWS->currentWindows(); + unsigned int wkspace = Lumina::NWS->currentWorkspace(); + for(int i=0; i<wins.length(); i++){ + //First check if this window is in the current workspace (or is "sticky") + if(wins.at(i)->property(NativeWindow::Workspace).toUInt() != wkspace + && wins.at(i)->property(NativeWindow::States).value< QList<NativeWindow::State> >().contains(NativeWindow::S_STICKY) ){ + continue; + } + AddWindowToMenu(wins.at(i)); + } } 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 ee6fdcc9..78756e8c 100644 --- a/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.h +++ b/src-qt5/core/lumina-desktop-unified/src-desktop/ContextMenu.h @@ -21,6 +21,8 @@ private: QMenu *appMenu, *winMenu; bool usewinmenu; + void AddWindowToMenu(NativeWindow*); + public: DesktopContextMenu(QWidget *parent = 0); ~DesktopContextMenu(); |