From 57db757ce2399000f84bf45ea1a3ea22a443a5c5 Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Thu, 29 Dec 2016 15:26:44 +0200 Subject: [PATCH 01/46] fix #11, and some old glitches during dragging --- containment/contents/code/LayoutManager.js | 20 +++++++++++++++----- containment/contents/ui/main.qml | 2 +- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/containment/contents/code/LayoutManager.js b/containment/contents/code/LayoutManager.js index 98c9677c6..72c42e4ff 100644 --- a/containment/contents/code/LayoutManager.js +++ b/containment/contents/code/LayoutManager.js @@ -151,6 +151,7 @@ function insertBefore(item1, item2) { for (var j = removed.length - 1; j >= 0; --j) { removed[j].parent = layout; } + return i; } @@ -188,6 +189,7 @@ function insertAfter(item1, item2) { for (var j = removed.length - 1; j >= 0; --j) { removed[j].parent = layout; } + return i; } @@ -254,18 +256,26 @@ function insertAtCoordinates(item, x, y) { } } } + //already in position if (child === item) { return; } + if (!child) { - child = layout.children[0]; + // check if dragging takes place after the end of the layout + if ( ((root.isVertical && y > layout.height)||(root.Horizontal && x > layout.width)) + && layout.children.length>0 ){ + child = layout.children[layout.children.length-1]; + } else { + child = layout.children[0]; + } + } else { + item.parent = root; } - item.parent = root; - //PlasmaCore.Types.Vertical = 3 - if ((plasmoid.formFactor === 3 && y < child.y + child.height/2) || - (plasmoid.formFactor !== 3 && x < child.x + child.width/2)) { + if ((root.isVertical && y < child.y + child.height/2) || + (root.isHorizontal && x < child.x + child.width/2)) { return insertBefore(child, item); } else { return insertAfter(child, item); diff --git a/containment/contents/ui/main.qml b/containment/contents/ui/main.qml index 9136d6607..d89d0f868 100644 --- a/containment/contents/ui/main.qml +++ b/containment/contents/ui/main.qml @@ -993,7 +993,7 @@ DragDrop.DropArea { Item { id: dndSpacer - property int normalSize: root.statesLineSizeOriginal + plasmoid.configuration.iconSize + root.iconMarginOriginal - 1 + property int normalSize: visibilityManager.statesLineSizeOriginal + plasmoid.configuration.iconSize + visibilityManager.iconMarginOriginal - 1 width: normalSize height: normalSize From 973c6c2536641d5e5dce2e4fd780dc91e82a1063 Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Thu, 29 Dec 2016 15:41:00 +0200 Subject: [PATCH 02/46] restore Double Layout functionality --- app/nowdockview.h | 2 ++ containment/contents/ui/main.qml | 11 +++++++---- .../configuration/LatteDockConfiguration.qml.cmake | 10 ++++------ 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/app/nowdockview.h b/app/nowdockview.h index 6df93990f..bd4c00724 100644 --- a/app/nowdockview.h +++ b/app/nowdockview.h @@ -123,6 +123,7 @@ protected: signals: // void visibilityChanged(); + void addInternalViewSplitter(); void alignmentChanged(); void compositingChanged(); void heightChanged(); @@ -131,6 +132,7 @@ signals: void maxLengthChanged(); void maxThicknessChanged(); void offsetChanged(); + void removeInternalViewSplitter(); void visibilityChanged(); void widthChanged(); diff --git a/containment/contents/ui/main.qml b/containment/contents/ui/main.qml index d89d0f868..4943f39e7 100644 --- a/containment/contents/ui/main.qml +++ b/containment/contents/ui/main.qml @@ -390,6 +390,9 @@ DragDrop.DropArea { onDockChanged: { if (dock) { + dock.onAddInternalViewSplitter.connect(addInternalViewSplitter); + dock.onRemoveInternalViewSplitter.connect(removeInternalViewSplitter); + dock.visibility.onDisableHidingChanged.connect(visibilityManager.slotDisableHidingChanged); dock.visibility.onIsHoveredChanged.connect(visibilityManager.slotIsHoveredChanged); dock.visibility.onMustBeLowered.connect(visibilityManager.slotMustBeLowered); @@ -1066,14 +1069,14 @@ DragDrop.DropArea { x: (plasmoid.configuration.panelPosition === Latte.Dock.Double) && root.isHorizontal && plasmoid.immutable && windowSystem.compositingActive ? - (dock.width/2) - (dock.visibility.maxLength/2): 0 + (dock.width/2) - (dock.maxLength/2): 0 y: (plasmoid.configuration.panelPosition === Latte.Dock.Double) && root.isVertical && plasmoid.immutable && windowSystem.compositingActive ? - (dock.height/2) - (dock.visibility.maxLength/2): 0 + (dock.height/2) - (dock.maxLength/2): 0 width: (plasmoid.configuration.panelPosition === Latte.Dock.Double) && root.isHorizontal && plasmoid.immutable ? - dock.visibility.maxLength : parent.width + dock.maxLength : parent.width height: (plasmoid.configuration.panelPosition === Latte.Dock.Double) && root.isVertical && plasmoid.immutable ? - dock.visibility.maxLength : parent.height + dock.maxLength : parent.height Component.onCompleted: { if(plasmoid.immutable) { diff --git a/shell/contents/configuration/LatteDockConfiguration.qml.cmake b/shell/contents/configuration/LatteDockConfiguration.qml.cmake index 9fc7573cb..e0bb4431a 100644 --- a/shell/contents/configuration/LatteDockConfiguration.qml.cmake +++ b/shell/contents/configuration/LatteDockConfiguration.qml.cmake @@ -19,8 +19,6 @@ PlasmaCore.FrameSvgItem { property bool panelIsVertical: plasmoid.formFactor === PlasmaCore.Types.Vertical signal updateThickness(); - signal removeInternalViewSplitter(); - signal addInternalViewSplitter(); Column{ id:mainColumn @@ -70,21 +68,21 @@ PlasmaCore.FrameSvgItem { centerPosition.checked = false; lastPosition.checked = false; splitTwoPosition.checked = false; - removeInternalViewSplitter(); + dock.removeInternalViewSplitter(); } else if(panelPosition == Latte.Dock.Center){ firstPosition.checked = false; centerPosition.checked = true; lastPosition.checked = false; splitTwoPosition.checked = false; - removeInternalViewSplitter(); + dock.removeInternalViewSplitter(); } else if((panelPosition == Latte.Dock.Right)||(panelPosition == Latte.Dock.Bottom)){ firstPosition.checked = false; centerPosition.checked = false; lastPosition.checked = true; splitTwoPosition.checked = false; - removeInternalViewSplitter(); + dock.removeInternalViewSplitter(); } else if (panelPosition == Latte.Dock.Double){ firstPosition.checked = false; @@ -92,7 +90,7 @@ PlasmaCore.FrameSvgItem { lastPosition.checked = false; splitTwoPosition.checked = true; //add the splitter visual - addInternalViewSplitter(-1); + dock.addInternalViewSplitter(); } } From cdfe0c02d999671299ce1dd79fe637399a307bf7 Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Thu, 29 Dec 2016 15:46:56 +0200 Subject: [PATCH 03/46] fix #10, alignments are updated correctly --- containment/contents/ui/main.qml | 36 ++++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/containment/contents/ui/main.qml b/containment/contents/ui/main.qml index 4943f39e7..0f7665260 100644 --- a/containment/contents/ui/main.qml +++ b/containment/contents/ui/main.qml @@ -73,13 +73,13 @@ DragDrop.DropArea { property int realPanelSize property int themePanelSize: plasmoid.configuration.panelSize - ///FIXME: I can't remember why this is needed, maybe for the anchorings!!! In order for the Double Layout to not mess the anchorings... - property int mainLayoutPosition: !plasmoid.immutable ? Latte.Dock.Center : (root.isVertical ? Latte.Dock.Top : Latte.Dock.Left) - ///FIXME: + ///FIXME: I can't remember why this is needed, maybe for the anchorings!!! In order for the Double Layout to not mess the anchorings... + //property int mainLayoutPosition: !plasmoid.immutable ? Latte.Dock.Center : (root.isVertical ? Latte.Dock.Top : Latte.Dock.Left) //property int panelAlignment: plasmoid.configuration.panelPosition !== Latte.Dock.Double ? plasmoid.configuration.panelPosition : mainLayoutPosition - property int panelAlignment: plasmoid.immutable ? plasmoid.configuration.panelPosition : Latte.Dock.Center - // property int panelAlignment: plasmoid.configuration.panelPosition + property int panelAlignment: plasmoid.immutable ? plasmoid.configuration.panelPosition : + ( plasmoid.configuration.panelPosition === Latte.Dock.Double ? + Latte.Dock.Center :plasmoid.configuration.panelPosition ) property real zoomFactor: windowSystem.compositingActive ? ( 1 + (plasmoid.configuration.zoomLevel / 20) ) : 1 @@ -107,7 +107,7 @@ DragDrop.DropArea { property int tasksCount: nowDock ? nowDock.tasksCount : 0 ///END properties from nowDock - /* Layout.preferredWidth: plasmoid.immutable ? + /* Layout.preferredWidth: plasmoid.immutable ? (plasmoid.configuration.panelPosition === Latte.Dock.Double ? layoutsContainer.width + 0.5*iconMargin : mainLayout.width + iconMargin) : Screen.width //on unlocked state use the maximum @@ -513,7 +513,7 @@ DragDrop.DropArea { } LayoutManager.save(); - // magicWin.removeAppletItem(applet); + // magicWin.removeAppletItem(applet); } Plasmoid.onUserConfiguringChanged: { @@ -566,10 +566,10 @@ DragDrop.DropArea { if (plasmoid.immutable) { if(root.isHorizontal) { root.Layout.preferredWidth = (plasmoid.configuration.panelPosition === Latte.Dock.Double ? - layoutsContainer.width + 0.5*iconMargin : mainLayout.width + iconMargin); + layoutsContainer.width + 0.5*iconMargin : mainLayout.width + iconMargin); } else { root.Layout.preferredHeight = (plasmoid.configuration.panelPosition === Latte.Dock.Double ? - layoutsContainer.height + 0.5*iconMargin : mainLayout.height + iconMargin); + layoutsContainer.height + 0.5*iconMargin : mainLayout.height + iconMargin); } } else { if (root.isHorizontal) { @@ -581,7 +581,7 @@ DragDrop.DropArea { if (plasmoid.immutable) { if (windowSystem.compositingActive) { - // magicWin.initialize(); + // magicWin.initialize(); } dock.visibility.disableHiding = false; @@ -594,7 +594,7 @@ DragDrop.DropArea { visibilityManager.updateMaskArea(); // console.log(magicWin.visible + " - "+magicWin.x+" - " + magicWin.y+" - "+magicWin.width+" - "+magicWin.height); - /* if (magicWin) { + /* if (magicWin) { if (plasmoid.immutable) { if (windowSystem.compositingActive) { magicWin.initialize(); @@ -632,7 +632,7 @@ DragDrop.DropArea { // adding the AppletQuickItem to the Now Dock in order to be // used for right clicking events - // magicWin.addAppletItem(applet); + // magicWin.addAppletItem(applet); } function addContainerInLayout(container, applet, x, y){ @@ -1021,7 +1021,7 @@ DragDrop.DropArea { } } - /* MouseArea{ + /* MouseArea{ id: wholeArea anchors.fill: parent hoverEnabled: true @@ -1053,14 +1053,14 @@ DragDrop.DropArea { VisibilityManager{ id: visibilityManager - // window: dock + // window: dock } Item{ id: layoutsContainer signal updateScale(int delegateIndex, real newScale, real step) - // property bool parentMagicWinFlag: plasmoid.immutable && magicWin && !root.inStartup && windowSystem.compositingActive + // property bool parentMagicWinFlag: plasmoid.immutable && magicWin && !root.inStartup && windowSystem.compositingActive //&& !(root.inStartup && magicWin.panelVisibility === Latte.Dock.AutoHide) property int allCount: root.nowDock ? mainLayout.count-1+nowDock.tasksCount : mainLayout.count @@ -1086,7 +1086,7 @@ DragDrop.DropArea { } } - /* onParentChanged: { + /* onParentChanged: { if (magicWin && magicWin.contentItem && (parent === magicWin.contentItem)) { magicWin.updateMaskArea(); } @@ -1255,8 +1255,8 @@ DragDrop.DropArea { id: animatedLengthTimer interval: 150 onTriggered: { - // if (!magicWin.isHovered && (appletsAnimations === 0) - // && (root.animationsNeedLength === 0) && (root.animationsNeedBothAxis === 0)) { + // if (!magicWin.isHovered && (appletsAnimations === 0) + // && (root.animationsNeedLength === 0) && (root.animationsNeedBothAxis === 0)) { if ((appletsAnimations === 0) && (root.animationsNeedLength === 0) && (root.animationsNeedBothAxis === 0)) { mainLayout.animatedLength = false; visibilityManager.updateMaskArea(); From 6dbaccd0656aa0139624b0ad9d6ef4965e7a80f6 Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Thu, 29 Dec 2016 19:46:04 +0200 Subject: [PATCH 04/46] support change edge from configuration window --- containment/contents/ui/main.qml | 5 + .../LatteDockConfiguration.qml.cmake | 115 +++++++++++++++++- 2 files changed, 118 insertions(+), 2 deletions(-) diff --git a/containment/contents/ui/main.qml b/containment/contents/ui/main.qml index 0f7665260..1e1ee4fad 100644 --- a/containment/contents/ui/main.qml +++ b/containment/contents/ui/main.qml @@ -393,6 +393,11 @@ DragDrop.DropArea { dock.onAddInternalViewSplitter.connect(addInternalViewSplitter); dock.onRemoveInternalViewSplitter.connect(removeInternalViewSplitter); + dock.onXChanged.connect(visibilityManager.updateMaskArea); + dock.onYChanged.connect(visibilityManager.updateMaskArea); + dock.onWidthChanged.connect(visibilityManager.updateMaskArea); + dock.onHeightChanged.connect(visibilityManager.updateMaskArea); + dock.visibility.onDisableHidingChanged.connect(visibilityManager.slotDisableHidingChanged); dock.visibility.onIsHoveredChanged.connect(visibilityManager.slotIsHoveredChanged); dock.visibility.onMustBeLowered.connect(visibilityManager.slotMustBeLowered); diff --git a/shell/contents/configuration/LatteDockConfiguration.qml.cmake b/shell/contents/configuration/LatteDockConfiguration.qml.cmake index e0bb4431a..65a4dbf6b 100644 --- a/shell/contents/configuration/LatteDockConfiguration.qml.cmake +++ b/shell/contents/configuration/LatteDockConfiguration.qml.cmake @@ -26,6 +26,117 @@ PlasmaCore.FrameSvgItem { spacing: 1.5*theme.defaultFont.pointSize width: parent.width - 10 + //////////// Location //////////////// + + Column{ + width:parent.width + spacing: 0.8*theme.defaultFont.pointSize + PlasmaComponents.Label{ + text: i18n("Location") + font.pointSize: 1.5 * theme.defaultFont.pointSize + } + + Flow{ + width: parent.width + spacing: 2 + + property bool inStartup: true + property int dockLocation: dock.location + + onDockLocationChanged: updateDockLocationVisual(); + + Component.onCompleted: { + updateDockLocationVisual(); + inStartup = false; + } + + function updateDockLocationVisual(){ + if(dockLocation === PlasmaCore.Types.BottomEdge){ + firstLocation.checked = true; + secondLocation.checked = false; + thirdLocation.checked = false; + fourthLocation.checked = false; + } + else if(dockLocation === PlasmaCore.Types.LeftEdge){ + firstLocation.checked = false; + secondLocation.checked = true; + thirdLocation.checked = false; + fourthLocation.checked = false; + } + else if(dockLocation === PlasmaCore.Types.TopEdge){ + firstLocation.checked = false; + secondLocation.checked = false; + thirdLocation.checked = true; + fourthLocation.checked = false; + } + else if(dockLocation === PlasmaCore.Types.RightEdge){ + firstLocation.checked = false; + secondLocation.checked = false; + thirdLocation.checked = false; + fourthLocation.checked = true; + } + } + + + PlasmaComponents.Button{ + id: firstLocation + checkable: true + text: i18n("Bottom") + width: (parent.width / 4) - 2 + + onCheckedChanged: { + if(checked && !parent.inStartup){ + dock.location = PlasmaCore.Types.BottomEdge + } + } + onClicked: checked=true; + } + PlasmaComponents.Button{ + id: secondLocation + checkable: true + text: i18n("Left") + width: (parent.width / 4) - 2 + + onCheckedChanged: { + if(checked && !parent.inStartup){ + dock.location = PlasmaCore.Types.LeftEdge + } + } + onClicked: checked=true; + } + PlasmaComponents.Button{ + id: thirdLocation + checkable: true + text: i18n("Top") + width: (parent.width / 4) - 2 + + onCheckedChanged: { + if(checked && !parent.inStartup){ + dock.location = PlasmaCore.Types.TopEdge + } + } + onClicked: checked=true; + } + + PlasmaComponents.Button{ + id: fourthLocation + checkable: true + text: i18n("Right") + width: (parent.width/4) - 1 + + onCheckedChanged: { + if(checked && !parent.inStartup){ + dock.location = PlasmaCore.Types.RightEdge + } + } + onClicked: checked=true; + } + } + } + + + /////////// Applets Alignment ////////////////// + Column{ width:parent.width spacing: 0.8*theme.defaultFont.pointSize @@ -214,7 +325,7 @@ PlasmaCore.FrameSvgItem { else fifthState.checked = false; - /* if (panelVisibility === 5) + /* if (panelVisibility === 5) sixthState.checked = true; else sixthState.checked = false;*/ @@ -294,7 +405,7 @@ PlasmaCore.FrameSvgItem { } onClicked: checked=true; } - /* PlasmaComponents.Button{ + /* PlasmaComponents.Button{ id: sixthState checkable: true text: i18n("Always Visible") From 94f05844368849415b1e0334b0d5fe123b7dcfed Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Thu, 29 Dec 2016 20:34:21 +0200 Subject: [PATCH 05/46] lock edges that are reserved --show only one configuration window every time in case there are more docks set --- app/nowdockconfigview.cpp | 24 +++++++++++++++++ app/nowdockconfigview.h | 1 + app/nowdockcorona.cpp | 4 +-- app/nowdockcorona.h | 3 +++ app/nowdockview.cpp | 11 ++++++++ app/nowdockview.h | 2 ++ .../LatteDockConfiguration.qml.cmake | 26 +++++++++++++++++++ 7 files changed, 69 insertions(+), 2 deletions(-) diff --git a/app/nowdockconfigview.cpp b/app/nowdockconfigview.cpp index d6811bb65..06f0486bb 100644 --- a/app/nowdockconfigview.cpp +++ b/app/nowdockconfigview.cpp @@ -19,6 +19,7 @@ #include "nowdockconfigview.h" #include "nowdockview.h" +#include "nowdockcorona.h" #include #include @@ -52,6 +53,13 @@ NowDockConfigView::NowDockConfigView(Plasma::Containment *containment, NowDockVi }); connect(containment, &Plasma::Containment::immutabilityChanged, this, &NowDockConfigView::immutabilityChanged); + + NowDockCorona *corona = dynamic_cast(m_containment->corona()); + + if (corona) { + connect(corona, &NowDockCorona::configurationShown, this, &NowDockConfigView::configurationShown); + } + /* connect(containment, &Plasma::Containment::immutabilityChanged , [&](Plasma::Types::ImmutabilityType type) { if (type != Plasma::Types::Mutable && this && isVisible()) @@ -177,7 +185,16 @@ void NowDockConfigView::showEvent(QShowEvent *ev) // m_dockView->visibility()->showImmediately(); m_screenSyncTimer.start(); m_deleterTimer.stop(); + ConfigView::showEvent(ev); + + //trigger showing configuration window through corona + //in order to hide all alternative configuration windows + NowDockCorona *corona = dynamic_cast(m_containment->corona()); + + if (corona) { + emit corona->configurationShown(this); + } } void NowDockConfigView::hideEvent(QHideEvent *ev) @@ -207,6 +224,13 @@ void NowDockConfigView::focusOutEvent(QFocusEvent *ev) // hide(); } +void NowDockConfigView::configurationShown(PlasmaQuick::ConfigView *configView) +{ + if ((configView != this) && isVisible()) { + hide(); + } +} + void NowDockConfigView::immutabilityChanged(Plasma::Types::ImmutabilityType type) { if (type != Plasma::Types::Mutable && isVisible()) { diff --git a/app/nowdockconfigview.h b/app/nowdockconfigview.h index a0ea591a2..168fce542 100644 --- a/app/nowdockconfigview.h +++ b/app/nowdockconfigview.h @@ -56,6 +56,7 @@ protected: private Q_SLOTS: void immutabilityChanged(Plasma::Types::ImmutabilityType type); + void configurationShown(PlasmaQuick::ConfigView *configView); private: Plasma::Containment *m_containment{nullptr}; diff --git a/app/nowdockcorona.cpp b/app/nowdockcorona.cpp index a05269236..8633b4fa7 100644 --- a/app/nowdockcorona.cpp +++ b/app/nowdockcorona.cpp @@ -122,8 +122,8 @@ QRect NowDockCorona::availableScreenRect(int id) const QList NowDockCorona::freeEdges(int screen) const { using Plasma::Types; - QList edges{Types::TopEdge, Types::BottomEdge - , Types::LeftEdge, Types::RightEdge}; + QList edges{Types::BottomEdge, Types::LeftEdge, + Types::TopEdge, Types::RightEdge}; for (const NowDockView *cont : m_containments) { if (cont && cont->containment()->screen() == screen) diff --git a/app/nowdockcorona.h b/app/nowdockcorona.h index cb3c4d8ea..c3ff452b6 100644 --- a/app/nowdockcorona.h +++ b/app/nowdockcorona.h @@ -53,6 +53,9 @@ public: public slots: void loadDefaultLayout() override; + +signals: + void configurationShown(PlasmaQuick::ConfigView *configView); private: void qmlRegisterTypes() const; diff --git a/app/nowdockview.cpp b/app/nowdockview.cpp index 2da4fb75e..ddb756aef 100644 --- a/app/nowdockview.cpp +++ b/app/nowdockview.cpp @@ -527,7 +527,18 @@ QPointF NowDockView::positionAdjustedForContainment(const QPointF &point) const qBound(containmentRect.top() + 2, point.y(), containmentRect.bottom() - 2)); } +QList NowDockView::freeEdges() const +{ + QList edges = m_corona->freeEdges(containment()->screen()); + + QList edgesInt; + foreach (Plasma::Types::Location edge, edges) { + edgesInt.append((int)edge); + } + + return edgesInt; +} void NowDockView::saveConfig() { diff --git a/app/nowdockview.h b/app/nowdockview.h index bd4c00724..f58f6af77 100644 --- a/app/nowdockview.h +++ b/app/nowdockview.h @@ -107,6 +107,8 @@ public: public slots: Q_INVOKABLE void addNewDock(); + //used from the configuration window + Q_INVOKABLE QList freeEdges() const; Q_INVOKABLE void initialize(); Q_INVOKABLE void removeDock(); void resizeWindow(); diff --git a/shell/contents/configuration/LatteDockConfiguration.qml.cmake b/shell/contents/configuration/LatteDockConfiguration.qml.cmake index 65a4dbf6b..e3a1bea36 100644 --- a/shell/contents/configuration/LatteDockConfiguration.qml.cmake +++ b/shell/contents/configuration/LatteDockConfiguration.qml.cmake @@ -46,12 +46,35 @@ PlasmaCore.FrameSvgItem { onDockLocationChanged: updateDockLocationVisual(); Component.onCompleted: { + lockReservedEdges(); updateDockLocationVisual(); inStartup = false; } + function lockReservedEdges() { + var edges = dock.freeEdges(); + + firstLocation.enabled = false; + secondLocation.enabled = false; + thirdLocation.enabled = false; + fourthLocation.enabled = false; + + for (var i=0; i Date: Thu, 29 Dec 2016 20:50:47 +0200 Subject: [PATCH 06/46] fix #9, edge priority bottom,left,top,right -- disable add dock if all edges are reserved in the current screen --- app/nowdockcorona.cpp | 26 +++++-------------- .../LatteDockConfiguration.qml.cmake | 7 +++++ 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/app/nowdockcorona.cpp b/app/nowdockcorona.cpp index 8633b4fa7..642c1612b 100644 --- a/app/nowdockcorona.cpp +++ b/app/nowdockcorona.cpp @@ -203,27 +203,13 @@ void NowDockCorona::loadDefaultLayout() auto config = defaultContainment->config(); defaultContainment->restore(config); - switch (containments().size()) { - case 1: - defaultContainment->setLocation(Plasma::Types::LeftEdge); - break; - - case 2: - defaultContainment->setLocation(Plasma::Types::RightEdge); - break; - - case 3: - defaultContainment->setLocation(Plasma::Types::TopEdge); - break; - - default: - defaultContainment->setLocation(Plasma::Types::BottomEdge); - break; + QList edges = freeEdges(defaultContainment->screen()); + + if (edges.count() > 0) { + defaultContainment->setLocation(edges.at(0)); + } else { + defaultContainment->setLocation(Plasma::Types::BottomEdge); } - - //config.writeEntry("dock", "initial"); - //config.writeEntry("alignment", (int)Dock::Center); - //config.deleteEntry("wallpaperplugin"); defaultContainment->updateConstraints(Plasma::Types::StartupCompletedConstraint); defaultContainment->save(config); diff --git a/shell/contents/configuration/LatteDockConfiguration.qml.cmake b/shell/contents/configuration/LatteDockConfiguration.qml.cmake index e3a1bea36..4956d3d94 100644 --- a/shell/contents/configuration/LatteDockConfiguration.qml.cmake +++ b/shell/contents/configuration/LatteDockConfiguration.qml.cmake @@ -733,6 +733,13 @@ PlasmaCore.FrameSvgItem { text: i18n("Add New Dock") onClicked: dock.addNewDock(); + + Component.onCompleted: { + var edges = dock.freeEdges(); + if (edges.length === 0) { + enabled = false; + } + } } PlasmaComponents.Button{ enabled: true From ba68acd12929e04f1eb1c0fe8dfc6bfbc722639d Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Thu, 29 Dec 2016 21:31:08 +0200 Subject: [PATCH 07/46] improve configuration visual --disabled also the visual debug mode --- containment/contents/ui/main.qml | 2 +- .../LatteDockConfiguration.qml.cmake | 53 ++++++++++--------- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/containment/contents/ui/main.qml b/containment/contents/ui/main.qml index 1e1ee4fad..db21dab5e 100644 --- a/containment/contents/ui/main.qml +++ b/containment/contents/ui/main.qml @@ -40,7 +40,7 @@ DragDrop.DropArea { //// ////BEGIN properties - property bool debugMode: true + property bool debugMode: false property bool automaticSize: plasmoid.configuration.automaticIconSize property bool immutable: plasmoid.immutable diff --git a/shell/contents/configuration/LatteDockConfiguration.qml.cmake b/shell/contents/configuration/LatteDockConfiguration.qml.cmake index 4956d3d94..b85e9dcd8 100644 --- a/shell/contents/configuration/LatteDockConfiguration.qml.cmake +++ b/shell/contents/configuration/LatteDockConfiguration.qml.cmake @@ -14,26 +14,45 @@ PlasmaCore.FrameSvgItem { imagePath: "dialogs/background" width: Math.max(420,noneShadow.width + lockedAppletsShadow.width + allAppletsShadow.width) - height: mainColumn.height+10 + height: mainColumn.height+2*windowSpace property bool panelIsVertical: plasmoid.formFactor === PlasmaCore.Types.Vertical + property int windowSpace:8 + signal updateThickness(); Column{ id:mainColumn anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter spacing: 1.5*theme.defaultFont.pointSize - width: parent.width - 10 + width: parent.width - 2*windowSpace //////////// Location //////////////// Column{ width:parent.width spacing: 0.8*theme.defaultFont.pointSize - PlasmaComponents.Label{ - text: i18n("Location") - font.pointSize: 1.5 * theme.defaultFont.pointSize + + RowLayout{ + width: parent.width + PlasmaComponents.Label{ + text: i18n("Location") + font.pointSize: 1.5 * theme.defaultFont.pointSize + Layout.alignment: Qt.AlignLeft + } + + PlasmaComponents.Label{ + font.pointSize: theme.defaultFont.pointSize + font.italic: true + opacity: 0.6 + + Layout.alignment: Qt.AlignRight + horizontalAlignment: Text.AlignRight + + text: i18n("ver: ") +"@VERSION@" + } } Flow{ @@ -167,26 +186,10 @@ PlasmaCore.FrameSvgItem { width:parent.width spacing: 0.8*theme.defaultFont.pointSize - RowLayout{ - width: parent.width - PlasmaComponents.Label{ - text: i18n("Applets Alignment") - font.pointSize: 1.5 * theme.defaultFont.pointSize - Layout.alignment: Qt.AlignLeft - } - - PlasmaComponents.Label{ - font.pointSize: theme.defaultFont.pointSize - font.italic: true - opacity: 0.6 - - Layout.alignment: Qt.AlignRight - horizontalAlignment: Text.AlignRight - // width: parent.width - - text: i18n("ver: ") +"@VERSION@" - - } + PlasmaComponents.Label{ + text: i18n("Applets Alignment") + font.pointSize: 1.5 * theme.defaultFont.pointSize + Layout.alignment: Qt.AlignLeft } //user set Panel Positions From df2e3a152993ee21d1140de95d5086b09a2adf91 Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Thu, 29 Dec 2016 23:27:29 +0200 Subject: [PATCH 08/46] added edit mode blueprint visual --- containment/contents/icons/blueprint.jpg | Bin 0 -> 46429 bytes containment/contents/ui/EditModeVisual.qml | 10 ++++++++++ containment/contents/ui/main.qml | 10 ++++++++++ 3 files changed, 20 insertions(+) create mode 100644 containment/contents/icons/blueprint.jpg create mode 100644 containment/contents/ui/EditModeVisual.qml diff --git a/containment/contents/icons/blueprint.jpg b/containment/contents/icons/blueprint.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ad415d44365d47a0cc1d46784e635c5714779568 GIT binary patch literal 46429 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

wYTPpFM8kO0JkaQgefe%gR_uHP-pv=DBr$3 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 U5K9$GRO Date: Sun, 25 Dec 2016 15:31:57 -0500 Subject: [PATCH 09/46] more rules added --- .gitignore | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 3d3e4d19b..1b095e120 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,34 @@ *~ .* !.gitignore -build -corona/build -*.kdev4 +# Ignore hidden files +.directory + +# build directory +build/ + +# backup files +*.desktop~ +*.gitignore~ +*.js~ +*.kate-swp +*.qml~ +*.sh~ +*.xml~ +.*.cpp~ +.*.h~ +.*.js~ +.*.pot~ +.*.po~ +.*.qml~ +.*.txt~ +.*.xml~ +.*~ +*.*.user +# locale files +*.mo + +# KDevelop Project files +*.kdev4 +.kdev4/ From 44f9cfc01a0511ad0dedddd922903df6a01c51da Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Sun, 25 Dec 2016 15:37:12 -0500 Subject: [PATCH 10/46] fake custom target, and qmllint It is a small trap for that qtcreator show qml|js files, and we can use qmllint before the each build, and avoid some syntax errors. --- FakeTarget.cmake | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 FakeTarget.cmake diff --git a/FakeTarget.cmake b/FakeTarget.cmake new file mode 100644 index 000000000..3de61ee63 --- /dev/null +++ b/FakeTarget.cmake @@ -0,0 +1,34 @@ +execute_process(COMMAND find plasmoid containment -name "*.qml" -o -name "*.js" + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE QML_SRCS_STRING) + +string(REPLACE "\n" ";" QML_SRCS ${QML_SRCS_STRING}) + +# fake target for QtCreator project +add_custom_target(fake-target + SOURCES ${QML_SRCS} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) + +# qmllint: qml static syntax checker +if(${CMAKE_BUILD_TYPE} MATCHES "Debug") + find_program(QMLLINT qmllint) + + if(EXISTS "${QMLLINT}") + message("-- Found qmllint: ${QMLLINT}") + add_custom_command(TARGET candil PRE_BUILD + COMMAND ${QMLLINT} ${QML_SRCS} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMENT "Running qmllint") + else() + message("-- qmllint: QML Syntax verifier not found") + endif() + + message("-- Enabling QML debugging and profiling") + add_definitions(-DQT_QML_DEBUG) + add_definitions(-DQT_FATAL_WARNINGS) + +elseif(${CMAKE_BUILD_TYPE} MATCHES "Release") + message("-- Disabling debug info") + add_definitions(-DQT_NO_DEBUG) + +endif() From 433ac70dbf8ae2eb29368777daf07a3182c64d66 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Sun, 25 Dec 2016 15:51:15 -0500 Subject: [PATCH 11/46] update CMakeLists.txt --- CMakeLists.txt | 2 ++ FakeTarget.cmake | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f232aec31..7c7c79935 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,8 @@ find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS Plasma PlasmaQuick WindowSystem Declarative I18n CoreAddons XmlGui DBusAddons Notifications) +include(FakeTarget.cmake) + FIND_PROGRAM(GETTEXT_MSGFMT_EXECUTABLE msgfmt) IF(NOT GETTEXT_MSGFMT_EXECUTABLE) diff --git a/FakeTarget.cmake b/FakeTarget.cmake index 3de61ee63..a42dac188 100644 --- a/FakeTarget.cmake +++ b/FakeTarget.cmake @@ -1,4 +1,4 @@ -execute_process(COMMAND find plasmoid containment -name "*.qml" -o -name "*.js" +execute_process(COMMAND find shell containment plasmoid -name "*.qml" -o -name "*.js" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE QML_SRCS_STRING) From 78a504998bfd005992d875071f0a58eb5b4b1a59 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Sun, 25 Dec 2016 18:09:56 -0500 Subject: [PATCH 12/46] utilities functions --- liblattedock/extras.cpp | 1 + liblattedock/extras.h | 73 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 liblattedock/extras.cpp create mode 100644 liblattedock/extras.h diff --git a/liblattedock/extras.cpp b/liblattedock/extras.cpp new file mode 100644 index 000000000..2ae40bff2 --- /dev/null +++ b/liblattedock/extras.cpp @@ -0,0 +1 @@ +#include "extras.h" diff --git a/liblattedock/extras.h b/liblattedock/extras.h new file mode 100644 index 000000000..9d7417be0 --- /dev/null +++ b/liblattedock/extras.h @@ -0,0 +1,73 @@ +#ifndef EXTRAS_H +#define EXTRAS_H + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#if __GLIBCXX__ <= 20150623 +namespace std { +template +unique_ptr make_unique(Args &&... args) +{ + return std::unique_ptr(new T(std::forward(args)...)); +} +} +#endif + +/*! + * @brief convert a QRect to a QString with format `(, ) x` + */ +inline QString qRectToStr(const QRect &r) +{ + return "(" % QString::number(r.x()) % ", " % QString::number(r.y()) % ") " + % QString::number(r.width()) % "x" % QString::number(r.height()); +} + +/*! + * @brief convert a `Q_ENUM` to c-string + */ +template +inline const char *qEnumToStr(EnumType value) +{ + return QMetaEnum::fromType().valueToKey(value); +} + +/*! + * @brief convert a `Q_ENUMS` of `Plasma::Types::Location` to c-string + */ +inline const char *qEnumToStr(Plasma::Types::Location Enum) +{ + static const int Index = Plasma::Types::staticMetaObject.indexOfEnumerator("Location"); + return Plasma::Types::staticMetaObject.enumerator(Index).valueToKey(Enum); +} + +/*! + * @brief convert a `Q_ENUMS` of `Plasma::Types::FormFactor` to c-string + */ +inline const char *qEnumToStr(Plasma::Types::FormFactor Enum) +{ + static const int Index = Plasma::Types::staticMetaObject.indexOfEnumerator("FormFactor"); + return Plasma::Types::staticMetaObject.enumerator(Index).valueToKey(Enum); +} + +/*! + * @brief machine epsilon + */ +template +typename std::enable_if(), bool>::type almost_equal(T x, T y, int ulp) +{ + return std::abs(x - y) < std::numeric_limits::epsilon() * std::abs(x + y) * ulp + || std::abs(x - y) < std::numeric_limits::min(); +} + +#endif // EXTRAS_H From d7ca91728abe09342774dbecf408db8121116bd3 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Sun, 25 Dec 2016 18:12:31 -0500 Subject: [PATCH 13/46] New tentative interface --- app/visibilitymanager.h | 144 ++++++++++++++++------------------------ 1 file changed, 59 insertions(+), 85 deletions(-) diff --git a/app/visibilitymanager.h b/app/visibilitymanager.h index 6f0dd467e..20f9f0110 100644 --- a/app/visibilitymanager.h +++ b/app/visibilitymanager.h @@ -1,11 +1,11 @@ #ifndef VISIBILITYMANAGER_H #define VISIBILITYMANAGER_H -#include -#include "../liblattedock/dock.h" #include "abstractinterface.h" #include "plasmaquick/containmentview.h" +#include "../liblattedock/dock.h" +#include #include #include @@ -13,90 +13,64 @@ class VisibilityManager : public QObject { Q_OBJECT - Q_PROPERTY(bool disableHiding READ disableHiding WRITE setDisableHiding NOTIFY disableHidingChanged) - //Q_PROPERTY(bool immutable READ immutable WRITE setImmutable NOTIFY immutableChanged) - Q_PROPERTY(bool isAutoHidden READ isAutoHidden WRITE setIsAutoHidden NOTIFY isAutoHiddenChanged) - Q_PROPERTY(bool isDockWindowType READ isDockWindowType WRITE setIsDockWindowType NOTIFY isDockWindowTypeChanged) - Q_PROPERTY(bool isHovered READ isHovered NOTIFY isHoveredChanged) - Q_PROPERTY(bool windowInAttention READ windowInAttention WRITE setWindowInAttention NOTIFY windowInAttentionChanged) - - Q_PROPERTY(Latte::Dock::Visibility panelVisibility READ panelVisibility WRITE setPanelVisibility NOTIFY panelVisibilityChanged) + Q_PROPERTY(Latte::Dock::Visibility mode READ mode WRITE setMode NOTIFY modeChanged) + Q_PROPERTY(int timerShow READ timerShow WRITE setTimerShow NOTIFY timerShowChanged) + Q_PROPERTY(int timerHide READ timerHide WRITE setTimerHide NOTIFY timerHideChanged) + Q_PROPERTY(Latte::Dock::VisibilityState state READ state WRITE setState NOTIFY stateChanged) public: explicit VisibilityManager(PlasmaQuick::ContainmentView *view); - ~VisibilityManager(); - - bool disableHiding() const; - void setDisableHiding(bool state); - - bool isAutoHidden() const; - void setIsAutoHidden(bool state); - - bool isDockWindowType() const; - void setIsDockWindowType(bool state); - - bool isHovered() const; - - bool windowInAttention() const; - - Latte::Dock::Visibility panelVisibility() const; - void setContainment(Plasma::Containment *contaiment); - void setMaskArea(QRect area); - void setPanelVisibility(Latte::Dock::Visibility state); - -public slots: - Q_INVOKABLE void initialize(); - Q_INVOKABLE void showNormal(); - Q_INVOKABLE void showOnTop(); - Q_INVOKABLE void showOnTopCheck(); - Q_INVOKABLE void showOnBottom(); - bool event(QEvent *event); - void setWindowInAttention(bool state); - void updateVisibilityFlags(); - -Q_SIGNALS: - void disableHidingChanged(); - void isAutoHiddenChanged(); - void isDockWindowTypeChanged(); - void isHoveredChanged(); - void mustBeLowered(); //are used to triger the sliding animations from the qml part - void mustBeRaised(); - void mustBeRaisedImmediately(); - void panelVisibilityChanged(); - void windowInAttentionChanged(); - -private Q_SLOTS: - void activeWindowChanged(); - //void compositingChanged(); - void updateState(); - void initWindow(); - void setIsHovered(bool state); - //void screenChanged(QScreen *screen); - //void setScreenGeometry(QRect geometry); - //void updateWindowPosition(); - -private: - bool m_disableHiding; - bool m_isAutoHidden; - bool m_isDockWindowType; - bool m_isHovered; - //second pass of the initialization - bool m_secondInitPass; - bool m_windowIsInAttention; - - int m_childrenLength; - QRect m_maskArea; - - QTimer m_initTimer; - QTimer m_updateStateTimer; - - Plasma::Containment *m_containment; - PlasmaQuick::ContainmentView *m_view; - - NowDock::AbstractInterface *m_interface; - Latte::Dock::Visibility m_panelVisibility; - + virtual ~VisibilityManager(); + + Latte::Dock::Visibility mode() const; + void setMode(Latte::Dock::Visibility mode); + + int timerShow() const; + void setTimerShow(int msec); + + int timerHide() const; + void setTimerHide(int msec); + + /** + * @brief show, change state to Dock::Visible when show timer is triggered. + */ + Q_INVOKABLE void show(); + + /** + * @brief showImmediately, same that show, but without timer + */ + Q_INVOKABLE void showImmediately(); + + /** + * @brief restore, change to last state, respecting the timers. + */ + Q_INVOKABLE void restore(); + + /** + * @brief showTemporarily, same that show but restores last state automatically + * @param msec, timeout before restoring + */ + Q_INVOKABLE void showTemporarily(int msec); + + /** + * @brief updateDockGeometry, the geometry should be inside screen, not into window. + */ + void updateDockGeometry(QRect &geometry); + +signals: + /** + * @brief mouseEntered, emitted when mouse enters the dock + */ + void mouseEntered(); + + /** + * @brief mouseExited, emitted when mouse leaves the dock + */ + void mouseExited(); + + void modeChanged(); + void timerShowChanged(); + void timerHideChanged(); + void stateChanged(); }; - - -#endif +#endif // VISIBILITYMANAGER_H From 665f39ff56792c6b1636cefb1be706dd4ad0894e Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Sun, 25 Dec 2016 18:13:05 -0500 Subject: [PATCH 14/46] update file mode. +x --- formatter.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 formatter.sh diff --git a/formatter.sh b/formatter.sh old mode 100644 new mode 100755 From 9aa43f14b0c1a0c25a589507293c56a79b447e81 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Sun, 25 Dec 2016 19:10:52 -0500 Subject: [PATCH 15/46] fixed, screenForContainment --- app/nowdockcorona.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/app/nowdockcorona.cpp b/app/nowdockcorona.cpp index 642c1612b..49b54383b 100644 --- a/app/nowdockcorona.cpp +++ b/app/nowdockcorona.cpp @@ -135,16 +135,10 @@ QList NowDockCorona::freeEdges(int screen) const int NowDockCorona::screenForContainment(const Plasma::Containment *containment) const { - return 0; - - while (const auto *parentCont = qobject_cast(containment->parent())) { - if (parentCont->isContainment()) - containment = qobject_cast(parentCont); - } - for (auto *view : m_containments) { - if (view && view->containment() == containment) - return containment->screen(); + if (view && view->containment() && view->containment()->id() == containment->id()) + if (view->screen()) + return qGuiApp->screens().indexOf(view->screen()); } return -1; From 1e733ee82876b2aee50eabe45e5c2fa347ed8c32 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Wed, 28 Dec 2016 02:32:23 -0500 Subject: [PATCH 16/46] gitignore update --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 1b095e120..f7beacd37 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ build/ .*.xml~ .*~ *.*.user +*.*.orig # locale files *.mo From 08bfa477094a98963e907e5bd0b29522c57260d3 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Wed, 28 Dec 2016 02:45:21 -0500 Subject: [PATCH 17/46] abstractinterface was renamed to abstractwindowinterface and cleaned AbstractWindowInterface will hide windows details. --- app/CMakeLists.txt | 3 +- app/abstractinterface.cpp | 42 ------------------------- app/abstractinterface.h | 56 --------------------------------- app/abstractwindowinterface.cpp | 21 +++++++++++++ app/abstractwindowinterface.h | 44 ++++++++++++++++++++++++++ 5 files changed, 67 insertions(+), 99 deletions(-) delete mode 100644 app/abstractinterface.cpp delete mode 100644 app/abstractinterface.h create mode 100644 app/abstractwindowinterface.cpp create mode 100644 app/abstractwindowinterface.h diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 29049d47d..355a1a0a6 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -14,8 +14,9 @@ include(KDEPackageAppTemplates) set(lattedock-app_SRCS ../liblattedock/dock.cpp - abstractinterface.cpp + abstractwindowinterface.cpp xwindowinterface.cpp + windowinfowrap.cpp visibilitymanager.cpp nowdockconfigview.cpp nowdockview.cpp diff --git a/app/abstractinterface.cpp b/app/abstractinterface.cpp deleted file mode 100644 index 3153160b7..000000000 --- a/app/abstractinterface.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include "abstractinterface.h" - -#include -#include - -namespace NowDock { - -AbstractInterface::AbstractInterface(QQuickWindow *dock) : - QObject(dock), - m_isDockWindowType(false), - m_dockNumber(0) -{ - m_dockWindow = dock; -} - -void AbstractInterface::setDockNumber(unsigned int no) -{ - if (m_dockNumber == no) { - return; - } - - m_dockNumber = no; - - emit dockNumberChanged(m_dockNumber); -} - -unsigned int AbstractInterface::dockNumber() const -{ - return m_dockNumber; -} - - -void AbstractInterface::setMaskArea(QRect area) -{ - if (m_maskArea == area) { - return; - } - - m_maskArea = area; -} - -} diff --git a/app/abstractinterface.h b/app/abstractinterface.h deleted file mode 100644 index df2b30d7b..000000000 --- a/app/abstractinterface.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef ABSTRACTINTERFACE_H -#define ABSTRACTINTERFACE_H - -#include -#include - -namespace NowDock { - -class AbstractInterface : public QObject { - Q_OBJECT - -public: - explicit AbstractInterface(QQuickWindow *dock); - - virtual bool activeIsDialog() const = 0; - virtual bool activeIsMaximized() const = 0; - virtual bool desktopIsActive() const = 0; - virtual bool dockIntersectsActiveWindow() const = 0; - virtual bool dockIsCovered(bool totally = false) const = 0; - virtual bool dockIsCovering() const = 0; - virtual bool dockIsOnTop() const = 0; - virtual bool dockInNormalState() const = 0; - virtual bool dockIsBelow() const = 0; - - //FIXME: This may not be needed, it would be better to investigate in KWindowSystem - //its behavior when setting the window type to NET::Dock - virtual void setDockDefaultFlags(bool dock = false) = 0; - virtual void setDockToAllDesktops() = 0; - virtual void showDockAsNormal() = 0; - virtual void showDockOnBottom() = 0; - virtual void showDockOnTop() = 0; - - void setDockNumber(unsigned int no); - unsigned int dockNumber() const; - - void setMaskArea(QRect area); - -Q_SIGNALS: - void activeWindowChanged(); - void dockNumberChanged(unsigned int no); - void windowInAttention(bool); - //FIXME: there is a chance that this signal is not needed at all - void windowChanged(); - -protected: - bool m_isDockWindowType; - int m_dockNumber; - - QRect m_maskArea; - - QQuickWindow *m_dockWindow; -}; - -} - -#endif diff --git a/app/abstractwindowinterface.cpp b/app/abstractwindowinterface.cpp new file mode 100644 index 000000000..edf970246 --- /dev/null +++ b/app/abstractwindowinterface.cpp @@ -0,0 +1,21 @@ +#include "abstractwindowinterface.h" + +#include +#include + +namespace Latte { + +AbstractWindowInterface::AbstractWindowInterface(QQuickWindow *const view, QObject *parent) + : QObject(parent), m_view(view) +{ + +} + +AbstractWindowInterface::~AbstractWindowInterface() +{ + +} + + + +} diff --git a/app/abstractwindowinterface.h b/app/abstractwindowinterface.h new file mode 100644 index 000000000..76f65b61e --- /dev/null +++ b/app/abstractwindowinterface.h @@ -0,0 +1,44 @@ +#ifndef ABSTRACTWINDOWINTERFACE_H +#define ABSTRACTWINDOWINTERFACE_H + +#include "windowinfowrap.h" +#include "../liblattedock/dock.h" + +#include +#include +#include + +#include +#include + +namespace Latte { + +class AbstractWindowInterface : public QObject { + Q_OBJECT + +public: + explicit AbstractWindowInterface(QQuickWindow *const view, QObject *parent = nullptr); + virtual ~AbstractWindowInterface(); + + virtual void setDockDefaultFlags() = 0; + + virtual WId activeWindow() const = 0; + virtual WindowInfoWrap requestInfo(WId wid) = 0; + virtual WindowInfoWrap requestInfoActive() = 0; + virtual const std::list &windows() = 0; + +signals: + void activeWindowChanged(WId wid); + void windowChanged(const WindowInfoWrap &winfo); + void windowAdded(WId wid); + void windowRemoved(WId wid); + void currentDesktopChanged(int desktop); + +protected: + QQuickWindow *const m_view; + std::list m_windows; +}; + +} + +#endif // ABSTRACTWINDOWINTERFACE_H From ed9870b62405c1673887857b882dc2e8a01c0969 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Wed, 28 Dec 2016 02:54:26 -0500 Subject: [PATCH 18/46] The new interface as we agreed. also VisibilityManager will perform the logic of the visibility as it corresponds through a class d-pointer using AbstractWindowInterface. --- app/visibilitymanager.h | 49 +++++++++++++---------------------------- 1 file changed, 15 insertions(+), 34 deletions(-) diff --git a/app/visibilitymanager.h b/app/visibilitymanager.h index 20f9f0110..aa8c7adb6 100644 --- a/app/visibilitymanager.h +++ b/app/visibilitymanager.h @@ -14,9 +14,14 @@ class VisibilityManager : public QObject { Q_OBJECT Q_PROPERTY(Latte::Dock::Visibility mode READ mode WRITE setMode NOTIFY modeChanged) + + Q_PROPERTY(bool isHidden READ isHidden WRITE isHidden NOTIFY isHiddenChanged) + + Q_PROPERTY(bool containsMouse READ containsMouse NOTIFY containsMouseChanged) + Q_PROPERTY(int timerShow READ timerShow WRITE setTimerShow NOTIFY timerShowChanged) + Q_PROPERTY(int timerHide READ timerHide WRITE setTimerHide NOTIFY timerHideChanged) - Q_PROPERTY(Latte::Dock::VisibilityState state READ state WRITE setState NOTIFY stateChanged) public: explicit VisibilityManager(PlasmaQuick::ContainmentView *view); @@ -32,45 +37,21 @@ public: void setTimerHide(int msec); /** - * @brief show, change state to Dock::Visible when show timer is triggered. - */ - Q_INVOKABLE void show(); - - /** - * @brief showImmediately, same that show, but without timer - */ - Q_INVOKABLE void showImmediately(); - - /** - * @brief restore, change to last state, respecting the timers. - */ - Q_INVOKABLE void restore(); - - /** - * @brief showTemporarily, same that show but restores last state automatically - * @param msec, timeout before restoring - */ - Q_INVOKABLE void showTemporarily(int msec); - - /** - * @brief updateDockGeometry, the geometry should be inside screen, not into window. + * @brief updateDockGeometry, the window geometry in absolute coordinates. */ void updateDockGeometry(QRect &geometry); - + signals: - /** - * @brief mouseEntered, emitted when mouse enters the dock - */ - void mouseEntered(); + void mustBeShown(); + void mustBeHide(); - /** - * @brief mouseExited, emitted when mouse leaves the dock - */ - void mouseExited(); - void modeChanged(); + void isHiddenChanged(); + void containsMouseChanged(); void timerShowChanged(); void timerHideChanged(); - void stateChanged(); + +private: + VisibilityManagerPrivate *const d; }; #endif // VISIBILITYMANAGER_H From 3d030c0d02228a6bae6db3d46af55ccc81571e06 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Wed, 28 Dec 2016 02:55:54 -0500 Subject: [PATCH 19/46] wrapper for window information. --- corona/windowinfowrap.cpp | 130 ++++++++++++++++++++++++++++++++++++++ corona/windowinfowrap.h | 59 +++++++++++++++++ 2 files changed, 189 insertions(+) create mode 100644 corona/windowinfowrap.cpp create mode 100644 corona/windowinfowrap.h diff --git a/corona/windowinfowrap.cpp b/corona/windowinfowrap.cpp new file mode 100644 index 000000000..aa772bcce --- /dev/null +++ b/corona/windowinfowrap.cpp @@ -0,0 +1,130 @@ +#include "windowinfowrap.h" + +using namespace Latte; + +WindowInfoWrap::WindowInfoWrap() + : m_isValid(false) + , m_isActive(false) + , m_isMinimized(false) + , m_isMaximized(false) + , m_isFullscreen(false) + , m_isOnCurrentDesktop(false) + , m_wid(0) +{ + +} + +WindowInfoWrap::WindowInfoWrap(const WindowInfoWrap &other) +{ + *this = other; +} + +WindowInfoWrap &WindowInfoWrap::operator=(const WindowInfoWrap &rhs) +{ + m_isValid = rhs.m_isValid; + m_isActive = rhs.m_isActive; + m_isMinimized = rhs.m_isMinimized; + m_isMaximized = rhs.m_isMaximized; + m_isFullscreen = rhs.m_isFullscreen; + m_isOnCurrentDesktop = rhs.m_isOnCurrentDesktop; + m_geometry = rhs.m_geometry; + m_wid = rhs.m_wid; + + return *this; +} + +inline bool WindowInfoWrap::operator==(const WindowInfoWrap &rhs) const +{ + return m_wid == rhs.m_wid; +} + +inline bool WindowInfoWrap::operator<(const WindowInfoWrap &rhs) const +{ + return m_wid < rhs.m_wid; +} + +inline bool WindowInfoWrap::operator>(const WindowInfoWrap &rhs) const +{ + return m_wid > rhs.m_wid; +} + +inline bool WindowInfoWrap::isValid() const +{ + return m_isValid; +} + +inline void WindowInfoWrap::setIsValid(bool isValid) +{ + m_isValid = isValid; +} + +inline bool WindowInfoWrap::isActive() const +{ + return m_isActive; +} + +inline void WindowInfoWrap::setIsActive(bool isActive) +{ + m_isActive = isActive; +} + +inline bool WindowInfoWrap::isMinimized() const +{ + return m_isMinimized; +} + +inline void WindowInfoWrap::setIsMinimized(bool isMinimized) +{ + m_isMinimized = isMinimized; +} + +inline bool WindowInfoWrap::isMaximized() const +{ + return m_isMaximized; +} + +inline void WindowInfoWrap::setIsMaximized(bool isMaximized) +{ + m_isMaximized = isMaximized; +} + +inline bool WindowInfoWrap::isFullscreen() const +{ + return m_isFullscreen; +} + +inline void WindowInfoWrap::setIsFullscreen(bool isFullscreen) +{ + m_isFullscreen = isFullscreen; +} + +inline bool WindowInfoWrap::isOnCurrentDesktop() const +{ + return m_isOnCurrentDesktop; +} + +inline void WindowInfoWrap::setIsOnCurrentDesktop(bool isOnCurrentDesktop) +{ + m_isOnCurrentDesktop = isOnCurrentDesktop; +} + +inline QRect WindowInfoWrap::geometry() const +{ + return m_geometry; +} + +inline void WindowInfoWrap::setGeometry(const QRect &geometry) +{ + m_geometry = geometry; +} + +inline WId WindowInfoWrap::wid() const +{ + return m_wid; +} + +inline void WindowInfoWrap::setWid(WId wid) +{ + m_wid = wid; +} + diff --git a/corona/windowinfowrap.h b/corona/windowinfowrap.h new file mode 100644 index 000000000..ca193e752 --- /dev/null +++ b/corona/windowinfowrap.h @@ -0,0 +1,59 @@ +#ifndef WINDOWINFO_H +#define WINDOWINFO_H + +#include +#include +#include + +namespace Latte { + +class WindowInfoWrap { + +public: + explicit WindowInfoWrap(); + WindowInfoWrap(const WindowInfoWrap &other); + + WindowInfoWrap &operator=(const WindowInfoWrap &rhs); + + bool operator==(const WindowInfoWrap &rhs) const; + bool operator<(const WindowInfoWrap &rhs) const; + bool operator>(const WindowInfoWrap &rhs) const; + + bool isValid() const; + void setIsValid(bool isValid); + + bool isActive() const; + void setIsActive(bool isActive); + + bool isMinimized() const; + void setIsMinimized(bool isMinimized); + + bool isMaximized() const; + void setIsMaximized(bool isMaximized); + + bool isFullscreen() const; + void setIsFullscreen(bool isFullscreen); + + bool isOnCurrentDesktop() const; + void setIsOnCurrentDesktop(bool isOnCurrentDesktop); + + QRect geometry() const; + void setGeometry(const QRect &geometry); + + WId wid() const; + void setWid(WId wid); + +private: + bool m_isValid : 1; + bool m_isActive : 1; + bool m_isMinimized : 1; + bool m_isMaximized : 1; + bool m_isFullscreen : 1; + bool m_isOnCurrentDesktop : 1; + QRect m_geometry; + WId m_wid; +}; + +} + +#endif // WINDOWINFO_H From 1b468a02e10cce6f95f3155f02cd5523089376a6 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Wed, 28 Dec 2016 02:57:31 -0500 Subject: [PATCH 20/46] XWindowInterface has been implemented --- app/xwindowinterface.cpp | 395 ++++++++------------------------------- app/xwindowinterface.h | 51 ++--- 2 files changed, 93 insertions(+), 353 deletions(-) diff --git a/app/xwindowinterface.cpp b/app/xwindowinterface.cpp index 530695c21..37d712e9c 100644 --- a/app/xwindowinterface.cpp +++ b/app/xwindowinterface.cpp @@ -1,361 +1,124 @@ #include "xwindowinterface.h" -#include +#include -#include #include +#include -namespace NowDock { +namespace Latte { -XWindowInterface::XWindowInterface(QQuickWindow *parent) : - AbstractInterface(parent), - m_demandsAttention(0) +XWindowInterface::XWindowInterface(QQuickWindow *const view, QObject *parent) + : AbstractWindowInterface(view, parent) { - m_activeWindow = KWindowSystem::activeWindow(); + Q_ASSERT(view != nullptr); - connect(KWindowSystem::self(), SIGNAL(activeWindowChanged(WId)), this, SLOT(activeWindowChanged(WId))); - connect(KWindowSystem::self(), SIGNAL(windowChanged(WId, NET::Properties, NET::Properties2)), this, SLOT(windowChanged(WId, NET::Properties, NET::Properties2))); - connect(KWindowSystem::self(), SIGNAL(windowRemoved(WId)), this, SLOT(windowRemoved(WId))); + connect(KWindowSystem::self(), &KWindowSystem::activeWindowChanged + , this, &AbstractWindowInterface::activeWindowChanged); + + connect(KWindowSystem::self() + , static_cast + (&KWindowSystem::windowChanged) + , this, &XWindowInterface::windowChangedProxy); + + connect(KWindowSystem::self(), &KWindowSystem::windowAdded, [this](WId wid) { + if (std::find(m_windows.cbegin(), m_windows.cend(), wid) != m_windows.cend()) { + m_windows.push_back(wid); + } + + emit windowAdded(wid); + }); + + connect(KWindowSystem::self(), &KWindowSystem::windowAdded, [this](WId wid) { + m_windows.remove(wid); + emit windowRemoved(wid); + }); - connect(this, SIGNAL(dockNumberChanged(uint)), this, SLOT(dockNumberChanged(uint))); + connect(KWindowSystem::self(), &KWindowSystem::currentDesktopChanged + , this, &AbstractWindowInterface::currentDesktopChanged); } XWindowInterface::~XWindowInterface() { -} -void XWindowInterface::dockNumberChanged(unsigned int no) -{ - if (no == 1) { - m_dockWindow->setFlags(Qt::Tool | Qt::WindowDoesNotAcceptFocus | Qt::FramelessWindowHint); - } } -void XWindowInterface::setDockToAllDesktops() +void XWindowInterface::setDockDefaultFlags() { - KWindowSystem::setOnAllDesktops(m_dockWindow->winId(), true); + NETWinInfo winfo(QX11Info::connection() + , static_cast(m_view->winId()) + , static_cast(m_view->winId()) + , 0, 0); + + winfo.setAllowedActions(NET::ActionChangeDesktop); + KWindowSystem::setType(m_view->winId(), NET::Dock); + KWindowSystem::setOnAllDesktops(m_view->winId(), true); } -void XWindowInterface::setDockDefaultFlags(bool dock) +WId XWindowInterface::activeWindow() const { - //Notice: the Qt::Tool flag even though it works perfectly for a single Now Dock - //it creates a strange situation when there are two and more Now Dock's - //in that case it is used only for the first created Now Dock - m_isDockWindowType = dock; - - if ((m_dockNumber == 1) && (!m_isDockWindowType)) { - m_dockWindow->setFlags(Qt::Tool | Qt::WindowDoesNotAcceptFocus | Qt::FramelessWindowHint); - } else { - KWindowSystem::setType(m_dockWindow->winId(), NET::Dock); - KWindowSystem::setState(m_dockWindow->winId(), NET::SkipTaskbar | NET::SkipPager); - } + return KWindowSystem::self()->activeWindow(); } -void XWindowInterface::showDockOnTop() +const std::list &XWindowInterface::windows() { - //this is the only way in order to not break the case of two and more NowDocks - //there is a small issue that the pop ups from locked plasmoids are opened - //on the maximum thickness - - //qDebug() << "Docknumber:" << m_dockNumber; - if (m_isDockWindowType) { - return; - } - - if (m_dockNumber != 1) { - KWindowSystem::setType(m_dockWindow->winId(), NET::Dock); - } - - KWindowSystem::clearState(m_dockWindow->winId(), NET::KeepBelow); - KWindowSystem::setState(m_dockWindow->winId(), NET::KeepAbove); + return m_windows; } -void XWindowInterface::showDockAsNormal() +WindowInfoWrap XWindowInterface::requestInfoActive() { - // qDebug() << "reached make normal..."; - if (m_isDockWindowType) { - return; - } - - if (m_dockNumber != 1) { - m_dockWindow->setFlags(Qt::Tool | Qt::WindowDoesNotAcceptFocus | Qt::FramelessWindowHint); - } - - KWindowSystem::clearState(m_dockWindow->winId(), NET::KeepAbove); - KWindowSystem::clearState(m_dockWindow->winId(), NET::KeepBelow); -} - -void XWindowInterface::showDockOnBottom() -{ - // qDebug() << "reached make bottom..."; - if (m_isDockWindowType) { - return; - } - - if (m_dockNumber != 1) { - m_dockWindow->setFlags(Qt::Tool | Qt::WindowDoesNotAcceptFocus | Qt::FramelessWindowHint); - } - - KWindowSystem::clearState(m_dockWindow->winId(), NET::KeepAbove); - KWindowSystem::setState(m_dockWindow->winId(), NET::KeepBelow); + return requestInfo(KWindowSystem::activeWindow()); } - -bool XWindowInterface::isDesktop(WId id) const +WindowInfoWrap XWindowInterface::requestInfo(WId wid) { - KWindowInfo info(id, NET::WMWindowType); - - if (!info.valid()) { - return false; - } + const KWindowInfo winfo{wid, NET::WMDesktop | NET::WMFrameExtents | NET::WMWindowType | NET::WMState}; - NET::WindowType type = info.windowType(NET::DesktopMask | NET::DockMask | NET::DialogMask); - - return type == NET::Desktop; -} - -bool XWindowInterface::isDialog(WId id) const -{ - KWindowInfo info(id, NET::WMWindowType); + WindowInfoWrap winfoWrap; - if (!info.valid()) { - return false; - } - - NET::WindowType type = info.windowType(NET::DesktopMask | NET::DockMask | NET::DialogMask); - - return type == NET::Dialog; -} - -bool XWindowInterface::isMaximized(WId id) const -{ - KWindowInfo info(id, NET::WMState); - - if (!info.valid()) { - return false; - } - - return (info.hasState(NET::Max)); -} - -bool XWindowInterface::isNormal(WId id) const -{ - return (!isOnBottom(id) && !isOnTop(id)); -} - -bool XWindowInterface::isOnBottom(WId id) const -{ - KWindowInfo info(id, NET::WMState); - - if (!info.valid()) { - return false; - } - - return (info.hasState(NET::KeepBelow)); -} - -bool XWindowInterface::isOnTop(WId id) const -{ - KWindowInfo info(id, NET::WMState); - - if (!info.valid()) { - return false; - } - - return (info.hasState(NET::KeepAbove)); -} - -bool XWindowInterface::activeIsDialog() const -{ - return isDialog(m_activeWindow); -} - -bool XWindowInterface::activeIsMaximized() const -{ - return isMaximized(m_activeWindow); -} - - -bool XWindowInterface::desktopIsActive() const -{ - return isDesktop(m_activeWindow); -} - -bool XWindowInterface::dockIsOnTop() const -{ - return isOnTop(m_dockWindow->winId()); - -} - -bool XWindowInterface::dockInNormalState() const -{ - return isNormal(m_dockWindow->winId()); -} - -bool XWindowInterface::dockIsBelow() const -{ - return isOnBottom(m_dockWindow->winId()); -} - -bool XWindowInterface::dockIntersectsActiveWindow() const -{ - KWindowInfo activeInfo(m_activeWindow, NET::WMGeometry); - - if (activeInfo.valid()) { - QRect maskSize; - - if (!m_maskArea.isNull()) { - maskSize = QRect(m_dockWindow->x() + m_maskArea.x(), m_dockWindow->y() + m_maskArea.y(), m_maskArea.width(), m_maskArea.height()); - } else { - maskSize = QRect(m_dockWindow->x(), m_dockWindow->y(), m_dockWindow->width(), m_dockWindow->height()); - } + if (!winfo.valid() || !isValidWindow(winfo)) + return winfoWrap; - return maskSize.intersects(activeInfo.geometry()); - } else { + winfoWrap.setIsValid(true); + winfoWrap.setWid(wid); + winfoWrap.setIsActive(KWindowSystem::activeWindow() == wid); + winfoWrap.setIsMinimized(winfo.hasState(NET::Hidden)); + winfoWrap.setIsMaximized(winfo.hasState(NET::Max)); + winfoWrap.setIsFullscreen(winfo.hasState(NET::FullScreen)); + winfoWrap.setIsOnCurrentDesktop(winfo.isOnCurrentDesktop()); + winfoWrap.setGeometry(winfo.geometry()); + + return winfoWrap; +} + +bool XWindowInterface::isValidWindow(const KWindowInfo &winfo) +{ + const auto winType = winfo.windowType(NET::DesktopMask | NET::DockMask + | NET::MenuMask | NET::SplashMask + | NET::NormalMask); + + if (winType == -1 || (winType & NET::Desktop) || (winType & NET::Menu) + || (winType & NET::Dock) || (winType & NET::Splash)) { return false; } -} - - -bool XWindowInterface::dockIsCovered(bool totally) const -{ - int currentDockPos = -1; - - QList windows = KWindowSystem::stackingOrder(); - int size = windows.count(); - - for (int i = size - 1; i >= 0; --i) { - WId window = windows.at(i); - - if (window == m_dockWindow->winId()) { - currentDockPos = i; - break; - } - } - - if (currentDockPos >= 0) { - QRect maskSize; - - if (!m_maskArea.isNull()) { - maskSize = QRect(m_dockWindow->x() + m_maskArea.x(), m_dockWindow->y() + m_maskArea.y(), m_maskArea.width(), m_maskArea.height()); - } else { - maskSize = QRect(m_dockWindow->x(), m_dockWindow->y(), m_dockWindow->width(), m_dockWindow->height()); - } - - WId transient = 0; - - if (m_dockWindow->transientParent()) { - transient = m_dockWindow->transientParent()->winId(); - } - - for (int j = size - 1; j > currentDockPos; --j) { - WId window = windows.at(j); - - KWindowInfo info(window, NET::WMState | NET::XAWMState | NET::WMGeometry); - - if (info.valid() && !isDesktop(window) && transient != window && !info.isMinimized()) { - if (totally) { - QRect winGeometry = info.geometry(); - - if ((maskSize.left() >= winGeometry.left()) && (maskSize.top() >= winGeometry.top()) - && (maskSize.right() <= winGeometry.right()) && (maskSize.bottom() <= winGeometry.bottom())) { - return true; - } - } else { - if (maskSize.intersects(info.geometry())) { - return true; - } - } - } - } - } - return false; + return true; } -bool XWindowInterface::dockIsCovering() const +void XWindowInterface::windowChangedProxy(WId wid, NET::Properties prop1, NET::Properties2 prop2) { - int currentDockPos = -1; - - QList windows = KWindowSystem::stackingOrder(); - int size = windows.count(); - - for (int i = size - 1; i >= 0; --i) { - WId window = windows.at(i); - - if (window == m_dockWindow->winId()) { - currentDockPos = i; - break; - } - } - - if (currentDockPos >= 0) { - QRect maskSize; - - if (!m_maskArea.isNull()) { - maskSize = QRect(m_dockWindow->x() + m_maskArea.x(), m_dockWindow->y() + m_maskArea.y(), m_maskArea.width(), m_maskArea.height()); - } else { - maskSize = QRect(m_dockWindow->x(), m_dockWindow->y(), m_dockWindow->width(), m_dockWindow->height()); - } + //! if the dock changed is ignored + if (wid == m_view->winId()) + return; - WId transient = 0; + //! ignore when, eg: the user presses a key + if (prop1 == 0 && prop2 == NET::WM2UserTime) + return; - if (m_dockWindow->transientParent()) { - transient = m_dockWindow->transientParent()->winId(); - } + if (prop1 && !(prop1 & NET::WMState || prop1 & NET::WMGeometry || prop1 & NET::ActiveWindow)) + return; - for (int j = currentDockPos - 1; j >= 0; --j) { - WId window = windows.at(j); - - KWindowInfo info(window, NET::WMState | NET::XAWMState | NET::WMGeometry); - - if (info.valid() && !isDesktop(window) && transient != window && !info.isMinimized() && maskSize.intersects(info.geometry())) { - return true; - } - } - } - - return false; -} - -/* - * SLOTS - */ - -void XWindowInterface::activeWindowChanged(WId win) -{ - m_activeWindow = win; - - emit AbstractInterface::activeWindowChanged(); -} - -void XWindowInterface::windowChanged(WId id, NET::Properties properties, NET::Properties2 properties2) -{ - KWindowInfo info(id, NET::WMState | NET::CloseWindow); - - if (info.valid()) { - if ((m_demandsAttention == 0) && info.hasState(NET::DemandsAttention)) { - m_demandsAttention = id; - emit windowInAttention(true); - } else if ((m_demandsAttention == id) && !info.hasState(NET::DemandsAttention)) { - m_demandsAttention = 0; - emit windowInAttention(false); - } - } - - // emit AbstractInterface::windowChanged(); - - if (id == m_activeWindow) { - emit AbstractInterface::activeWindowChanged(); - } + emit windowChanged(requestInfo(wid)); } -void XWindowInterface::windowRemoved(WId id) -{ - if (id == m_demandsAttention) { - m_demandsAttention = 0; - emit AbstractInterface::windowInAttention(false); - } } -} diff --git a/app/xwindowinterface.h b/app/xwindowinterface.h index 178687e77..4fd3f51d9 100644 --- a/app/xwindowinterface.h +++ b/app/xwindowinterface.h @@ -1,59 +1,36 @@ -#ifndef XWINDOWINTERFACE_H +#ifndef XWINDOWINTERFACE_H #define XWINDOWINTERFACE_H #include #include -#include "abstractinterface.h" +#include "abstractwindowinterface.h" -namespace NowDock { +namespace Latte { -class XWindowInterface : public AbstractInterface { +class XWindowInterface : public AbstractWindowInterface { Q_OBJECT public: - explicit XWindowInterface(QQuickWindow *parent); - ~XWindowInterface(); + XWindowInterface(QQuickWindow *const view, QObject *parent); + virtual ~XWindowInterface(); - bool activeIsDialog() const; - bool activeIsMaximized() const; - bool dockIntersectsActiveWindow() const; - bool desktopIsActive() const; - bool dockIsCovered(bool totally = false) const; - bool dockIsCovering() const; - bool dockIsOnTop() const; - bool dockInNormalState() const; - bool dockIsBelow() const; + void setDockDefaultFlags() override; - void setDockDefaultFlags(bool dock = false); - void setDockToAllDesktops(); - void setDockToAlwaysVisible(); - void showDockAsNormal(); - void showDockOnBottom(); - void showDockOnTop(); - -private Q_SLOTS: - void activeWindowChanged(WId win); - void dockNumberChanged(unsigned int no); - void windowChanged(WId id, NET::Properties properties, NET::Properties2 properties2); - void windowRemoved(WId id); + WId activeWindow() const override; + WindowInfoWrap requestInfo(WId wid) override; + WindowInfoWrap requestInfoActive() override; + const std::list &windows() override; private: - WId m_activeWindow; - WId m_demandsAttention; - - bool isDesktop(WId id) const; - bool isDialog(WId id) const; - bool isMaximized(WId id) const; - bool isNormal(WId id) const; - bool isOnBottom(WId id) const; - bool isOnTop(WId id) const; + bool isValidWindow(const KWindowInfo &winfo); + void windowChangedProxy(WId wid, NET::Properties prop1, NET::Properties2 prop2); }; } -#endif +#endif // XWINDOWINTERFACE_H From 333f1e506cdbc935a4bf19ae22f4f2f7c98b1a3f Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Wed, 28 Dec 2016 03:00:01 -0500 Subject: [PATCH 21/46] some methods were missing. --- app/visibilitymanager.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/visibilitymanager.h b/app/visibilitymanager.h index aa8c7adb6..7a7308bbd 100644 --- a/app/visibilitymanager.h +++ b/app/visibilitymanager.h @@ -1,7 +1,6 @@ #ifndef VISIBILITYMANAGER_H #define VISIBILITYMANAGER_H -#include "abstractinterface.h" #include "plasmaquick/containmentview.h" #include "../liblattedock/dock.h" @@ -14,13 +13,9 @@ class VisibilityManager : public QObject { Q_OBJECT Q_PROPERTY(Latte::Dock::Visibility mode READ mode WRITE setMode NOTIFY modeChanged) - Q_PROPERTY(bool isHidden READ isHidden WRITE isHidden NOTIFY isHiddenChanged) - Q_PROPERTY(bool containsMouse READ containsMouse NOTIFY containsMouseChanged) - Q_PROPERTY(int timerShow READ timerShow WRITE setTimerShow NOTIFY timerShowChanged) - Q_PROPERTY(int timerHide READ timerHide WRITE setTimerHide NOTIFY timerHideChanged) public: @@ -30,6 +25,11 @@ public: Latte::Dock::Visibility mode() const; void setMode(Latte::Dock::Visibility mode); + bool isHidden() const; + void setHidden(bool isHidden); + + bool containsMouse() const; + int timerShow() const; void setTimerShow(int msec); From c128c42c03787c4a61fa03f426425236c7af2172 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Wed, 28 Dec 2016 21:11:29 -0500 Subject: [PATCH 22/46] formatted. --- liblattedock/extras.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liblattedock/extras.h b/liblattedock/extras.h index 9d7417be0..3d0cf87db 100644 --- a/liblattedock/extras.h +++ b/liblattedock/extras.h @@ -64,7 +64,7 @@ inline const char *qEnumToStr(Plasma::Types::FormFactor Enum) * @brief machine epsilon */ template -typename std::enable_if(), bool>::type almost_equal(T x, T y, int ulp) +typename std::enable_if < !std::is_integral(), bool >::type almost_equal(T x, T y, int ulp) { return std::abs(x - y) < std::numeric_limits::epsilon() * std::abs(x + y) * ulp || std::abs(x - y) < std::numeric_limits::min(); From 2c6ab968bd1b8182d0d41649f75948f9e6dc3c72 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Wed, 28 Dec 2016 22:27:55 -0500 Subject: [PATCH 23/46] corona/ has been renamed to app/ --- app/CMakeLists.txt | 1 + {corona => app}/windowinfowrap.cpp | 0 {corona => app}/windowinfowrap.h | 0 3 files changed, 1 insertion(+) rename {corona => app}/windowinfowrap.cpp (100%) rename {corona => app}/windowinfowrap.h (100%) diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 355a1a0a6..4f74aa69f 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -14,6 +14,7 @@ include(KDEPackageAppTemplates) set(lattedock-app_SRCS ../liblattedock/dock.cpp + windowinfowrap.cpp abstractwindowinterface.cpp xwindowinterface.cpp windowinfowrap.cpp diff --git a/corona/windowinfowrap.cpp b/app/windowinfowrap.cpp similarity index 100% rename from corona/windowinfowrap.cpp rename to app/windowinfowrap.cpp diff --git a/corona/windowinfowrap.h b/app/windowinfowrap.h similarity index 100% rename from corona/windowinfowrap.h rename to app/windowinfowrap.h From 9debe8dbb3a2067e7e7ca83e426bfba97159316a Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Thu, 29 Dec 2016 00:37:53 -0500 Subject: [PATCH 24/46] added methods to reserve screen space --- app/abstractwindowinterface.h | 6 +++++ app/xwindowinterface.cpp | 50 +++++++++++++++++++++++++++++++++++ app/xwindowinterface.h | 10 ++++--- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/app/abstractwindowinterface.h b/app/abstractwindowinterface.h index 76f65b61e..2877de4b7 100644 --- a/app/abstractwindowinterface.h +++ b/app/abstractwindowinterface.h @@ -9,8 +9,11 @@ #include #include +#include #include +#include + namespace Latte { class AbstractWindowInterface : public QObject { @@ -27,6 +30,9 @@ public: virtual WindowInfoWrap requestInfoActive() = 0; virtual const std::list &windows() = 0; + virtual void setDockStruts(const QRect &dockRect, Plasma::Types::Location location) = 0; + virtual void removeDockStruts() = 0; + signals: void activeWindowChanged(WId wid); void windowChanged(const WindowInfoWrap &winfo); diff --git a/app/xwindowinterface.cpp b/app/xwindowinterface.cpp index 37d712e9c..411c567b4 100644 --- a/app/xwindowinterface.cpp +++ b/app/xwindowinterface.cpp @@ -1,5 +1,7 @@ #include "xwindowinterface.h" +#include "../liblattedock/extras.h" +#include #include #include @@ -64,6 +66,54 @@ const std::list &XWindowInterface::windows() return m_windows; } +void XWindowInterface::setDockStruts(const QRect &dockRect, Plasma::Types::Location location) +{ + NETExtendedStrut strut; + + switch (location) { + case Plasma::Types::TopEdge: + strut.top_width = dockRect.height(); + strut.top_start = dockRect.x(); + strut.top_end = dockRect.x() + dockRect.width() - 1; + break; + + case Plasma::Types::BottomEdge: + strut.bottom_width = dockRect.height(); + strut.bottom_start = dockRect.x(); + strut.bottom_end = dockRect.x() + dockRect.width() - 1; + break; + + case Plasma::Types::LeftEdge: + strut.left_width = dockRect.width(); + strut.left_start = dockRect.y(); + strut.left_end = dockRect.y() + dockRect.height() - 1; + break; + + case Plasma::Types::RightEdge: + strut.right_width = dockRect.width(); + strut.right_start = dockRect.y(); + strut.right_end = dockRect.y() + dockRect.height() - 1; + break; + + default: + qWarning() << "wrong location:" << qEnumToStr(location); + return; + } + + + KWindowSystem::setExtendedStrut(m_view->winId(), + strut.left_width, strut.left_start, strut.left_end, + strut.right_width, strut.right_start, strut.right_end, + strut.top_width, strut.top_start, strut.top_end, + strut.bottom_width, strut.bottom_start, strut.bottom_end + ); +} + +void XWindowInterface::removeDockStruts() +{ + KWindowSystem::setStrut(m_view->winId(), 0, 0, 0, 0); +} + WindowInfoWrap XWindowInterface::requestInfoActive() { return requestInfo(KWindowSystem::activeWindow()); diff --git a/app/xwindowinterface.h b/app/xwindowinterface.h index 4fd3f51d9..b73f741b3 100644 --- a/app/xwindowinterface.h +++ b/app/xwindowinterface.h @@ -1,11 +1,12 @@ #ifndef XWINDOWINTERFACE_H #define XWINDOWINTERFACE_H +#include "abstractwindowinterface.h" + #include #include - -#include "abstractwindowinterface.h" +#include namespace Latte { @@ -14,7 +15,7 @@ class XWindowInterface : public AbstractWindowInterface { public: XWindowInterface(QQuickWindow *const view, QObject *parent); - virtual ~XWindowInterface(); + ~XWindowInterface() override; void setDockDefaultFlags() override; @@ -23,6 +24,9 @@ public: WindowInfoWrap requestInfoActive() override; const std::list &windows() override; + void setDockStruts(const QRect &dockRect, Plasma::Types::Location location) override; + void removeDockStruts() override; + private: bool isValidWindow(const KWindowInfo &winfo); void windowChangedProxy(WId wid, NET::Properties prop1, NET::Properties2 prop2); From b5a5d9759f319e58dc76ba2fc7ffc3b187837273 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Thu, 29 Dec 2016 00:40:35 -0500 Subject: [PATCH 25/46] added class visibilitymanagerprivate to implement visibility --- app/visibilitymanager.cpp | 462 ++++++++------------------------------ app/visibilitymanager_p.h | 64 ++++++ 2 files changed, 163 insertions(+), 363 deletions(-) create mode 100644 app/visibilitymanager_p.h diff --git a/app/visibilitymanager.cpp b/app/visibilitymanager.cpp index 584640430..537e18211 100644 --- a/app/visibilitymanager.cpp +++ b/app/visibilitymanager.cpp @@ -1,450 +1,186 @@ #include "visibilitymanager.h" +#include "visibilitymanager_p.h" -#include "abstractinterface.h" -#include "xwindowinterface.h" -#include "plasmaquick/containmentview.h" - -#include "../liblattedock/dock.h" +namespace Latte { -#include +//! BEGIN: VisiblityManagerPrivate implementation +VisibilityManagerPrivate::VisibilityManagerPrivate(PlasmaQuick::ContainmentView *view, VisibilityManager *q) + : QObject(view), q(q) +{ -#include +} -VisibilityManager::VisibilityManager(PlasmaQuick::ContainmentView *view) : - QObject(view), - m_disableHiding(false), - m_isAutoHidden(false), - m_isDockWindowType(true), - m_isHovered(false), - m_secondInitPass(false), - m_windowIsInAttention(false), - m_childrenLength(-1), - m_view(view) +VisibilityManagerPrivate::~VisibilityManagerPrivate() { - // m_windowSystem = new WindowSystem(this); - // connect(m_windowSystem, SIGNAL(compositingChanged()), this, SLOT(compositingChanged())); - - m_interface = new NowDock::XWindowInterface(m_view); - connect(m_interface, SIGNAL(windowInAttention(bool)), this, SLOT(setWindowInAttention(bool))); - connect(m_interface, SIGNAL(activeWindowChanged()), this, SLOT(activeWindowChanged())); - m_interface->setDockToAllDesktops(); - //fixes a bug in plasma-framework with wrong popups placement - m_interface->setDockNumber(2); - - // connect(this, SIGNAL(screenChanged(QScreen *)), this, SLOT(screenChanged(QScreen *))); - // setPanelScreen(screen()); - m_updateStateTimer.setSingleShot(true); - m_updateStateTimer.setInterval(900); - connect(&m_updateStateTimer, &QTimer::timeout, this, &VisibilityManager::updateState); - - m_initTimer.setSingleShot(true); - m_initTimer.setInterval(400); - connect(&m_initTimer, &QTimer::timeout, this, &VisibilityManager::initWindow); - - connect(this, SIGNAL(panelVisibilityChanged()), this, SLOT(updateVisibilityFlags())); - setPanelVisibility(Latte::Dock::DodgeActive); - // updateVisibilityFlags(); - - // connect(this, SIGNAL(locationChanged()), this, SLOT(updateWindowPosition())); - connect(this, SIGNAL(windowInAttentionChanged()), this, SLOT(updateState())); - - initialize(); } -VisibilityManager::~VisibilityManager() +void VisibilityManagerPrivate::setMode(Dock::Visibility mode) { + } -void VisibilityManager::setContainment(Plasma::Containment *containment) +void VisibilityManagerPrivate::setIsHidden(bool isHidden) { - if (containment == m_containment) { - return; - } - - m_containment = containment; - // setVisibility(mode); -} +} -Latte::Dock::Visibility VisibilityManager::panelVisibility() const +void VisibilityManagerPrivate::setTimerShow(int msec) { - return m_panelVisibility; + } -void VisibilityManager::setPanelVisibility(Latte::Dock::Visibility state) +void VisibilityManagerPrivate::setTimerHide(int msec) { - if (m_panelVisibility == state) { - return; - } - - m_panelVisibility = state; - emit panelVisibilityChanged(); + } -bool VisibilityManager::isAutoHidden() const +void VisibilityManagerPrivate::raiseDock(bool raise) { - return m_isAutoHidden; + if (raise) { + timerHide.stop(); + + if (!timerShow.isActive()) + timerShow.start(); + } else { + timerShow.stop(); + + if (!timerHide.isActive()) + timerHide.start(); + } } -void VisibilityManager::setIsAutoHidden(bool state) +void VisibilityManagerPrivate::setDockRect(const QRect &rect) { - if (m_isAutoHidden == state) { - return; - } - - m_isAutoHidden = state; - emit isAutoHiddenChanged(); + } -bool VisibilityManager::windowInAttention() const +void VisibilityManagerPrivate::windowAdded(WId id) { - return m_windowIsInAttention; + } -void VisibilityManager::setWindowInAttention(bool state) +void VisibilityManagerPrivate::dodgeActive(WId id) { - if (m_windowIsInAttention == state) { - return; - } - - m_windowIsInAttention = state; - emit windowInAttentionChanged(); + } -bool VisibilityManager::disableHiding() const +void VisibilityManagerPrivate::dodgeWindows(WId id) { - return m_disableHiding; + } -void VisibilityManager::setDisableHiding(bool value) +void VisibilityManagerPrivate::checkAllWindows() { - if (m_disableHiding == value) { - return; - } - - m_disableHiding = value; - - emit disableHidingChanged(); - - if (!m_disableHiding) { - m_updateStateTimer.start(); - } + } -bool VisibilityManager::isDockWindowType() const +bool VisibilityManagerPrivate::intersects(const WindowInfoWrap &info) { - return m_isDockWindowType; + } -void VisibilityManager::setIsDockWindowType(bool state) +void VisibilityManagerPrivate::saveConfig() { - if (m_isDockWindowType == state) { - return; - } - - m_isDockWindowType = state; - - updateVisibilityFlags(); - - emit isDockWindowTypeChanged(); - - m_updateStateTimer.start(); + } -bool VisibilityManager::isHovered() const +void VisibilityManagerPrivate::restoreConfig() { - return m_isHovered; + } -void VisibilityManager::setIsHovered(bool state) +bool VisibilityManagerPrivate::event(QEvent *ev) { - if (m_isHovered == state) { - return; + if (ev->type() == QEvent::Enter && !containsMouse) { + containsMouse = true; + emit q->containsMouseChanged(); + + if (mode == Dock::AutoHide) + raiseDock(true); + + } else if (ev->type() == QEvent::Leave && containsMouse) { + containsMouse = false; + emit q->containsMouseChanged(); + + if (mode == Dock::AutoHide) + raiseDock(false); } - m_isHovered = state; - emit isHoveredChanged(); + return QObject::event(ev); } -void VisibilityManager::setMaskArea(QRect area) +//! END: VisibilityManager implementation + +//! BEGIN: VisiblityManager implementation +VisibilityManager::VisibilityManager(PlasmaQuick::ContainmentView *view) + : d(new VisibilityManagerPrivate(view, this)) { - m_interface->setMaskArea(area); + d->restoreConfig(); } -/*******************************/ - -void VisibilityManager::initialize() +VisibilityManager::~VisibilityManager() { - m_secondInitPass = true; - m_initTimer.start(); + } -void VisibilityManager::initWindow() +Dock::Visibility VisibilityManager::mode() const { - updateVisibilityFlags(); - - // updateWindowPosition(); - - // The initialization phase makes two passes because - // changing the window style and type wants a small delay - // and afterwards the second pass positions them correctly - if (m_secondInitPass) { - m_initTimer.start(); - m_secondInitPass = false; - } + return d->mode; } - -/*void VisibilityManager::updateWindowPosition() +void VisibilityManager::setMode(Dock::Visibility mode) { - //setPanelScreen(screen()); - // qDebug() << "updateWindowPosition: start..."; - if (!transientParent() || !transientParent()->screen()) { - // qDebug() << "updateWindowPosition: break transient..."; - return; - } - - // qDebug() << "updateWindowPosition: transientParent setting screen position..."; - setPanelScreen(transientParent()->screen()); - - if (!m_screen || m_screenGeometry.isNull()) { - // qDebug() << "updateWindowPosition: break m_screen..."; - return; - } - // qDebug() << "updateWindowPosition: check passed..."; - // qDebug() << m_screen->geometry().x() << " - " << m_screen->geometry().y() << " - " << m_screen->geometry().width() << " - " << m_screen->geometry().height(); - - if (m_location == Plasma::Types::BottomEdge) { - setX(m_screenGeometry.x()); - setY(m_screenGeometry.y()+m_screenGeometry.height() - height()); - } else if (m_location == Plasma::Types::TopEdge) { - setX(m_screenGeometry.x()); - setY(m_screenGeometry.y()); - } else if (m_location == Plasma::Types::LeftEdge) { - setX(m_screenGeometry.x()); - setY(m_screenGeometry.y()); - } else if (m_location == Plasma::Types::RightEdge) { - setX(m_screenGeometry.x()+m_screenGeometry.width() - width()); - setY(m_screenGeometry.y()); - } - - ///FIXME: in come cases the below can not catch up and this may be the reason - //that on start up in some cases dock's contents are not shown, - //needs a timer maybe? - /*if (m_screen != screen()) { - setScreen(m_screen); - }*/ -//} + d->setMode(mode); +} -void VisibilityManager::updateVisibilityFlags() +bool VisibilityManager::isHidden() const { - m_interface->setDockToAllDesktops(); - - /* if ((m_panelVisibility == AutoHide)||(m_isDockWindowType)) { - m_updateStateTimer.setInterval(2500); - } else { - m_updateStateTimer.setInterval(1500); - }*/ - - m_interface->setDockDefaultFlags(m_isDockWindowType); - - // updateWindowPosition(); - if (!m_isDockWindowType) { - showOnTop(); - } - - m_updateStateTimer.start(); + return d->isHidden; } -/* - * It is used from the m_updateStateTimer in order to check the dock's - * visibility and trigger events and actions which are needed to - * respond accordingly - */ -void VisibilityManager::updateState() +void VisibilityManager::setHidden(bool isHidden) { - // qDebug() << "in update state disableHiding:" <desktopIsActive() && m_interface->dockIntersectsActiveWindow()) { - if (m_interface->dockIsOnTop() || (m_isDockWindowType && !m_isAutoHidden)) { - // qDebug() << m_isHovered << " - " << m_windowIsInAttention << " - "<< m_disableHiding; - if (!m_isHovered && !m_windowIsInAttention && !m_disableHiding) { - // qDebug() << "must be lowered...."; - emit mustBeLowered(); //showNormal(); - } - } else { - if (m_windowIsInAttention) { - if (!m_isDockWindowType || (m_isDockWindowType && m_isAutoHidden)) { - emit mustBeRaised(); //showOnTop(); - } - } - } - } else { - if (!m_interface->activeIsDialog()) { - if ((!m_interface->desktopIsActive() && m_interface->dockIsCovered()) - || (m_isDockWindowType && m_isAutoHidden)) { - // qDebug() << "must be raised...."; - emit mustBeRaised(); - } else { - showOnTop(); - } - } - } - - break; - - case Latte::Dock::DodgeMaximized: - if (!m_interface->desktopIsActive() && m_interface->activeIsMaximized() && m_interface->dockIntersectsActiveWindow()) { - if (m_interface->dockIsOnTop() || (m_isDockWindowType && !m_isAutoHidden)) { - if (!m_isHovered && !m_windowIsInAttention && !m_disableHiding) { - emit mustBeLowered(); //showNormal(); - } - } else { - if (m_windowIsInAttention) { - if (!m_isDockWindowType || (m_isDockWindowType && m_isAutoHidden)) { - emit mustBeRaised(); //showOnTop(); - } - } - } - } else { - if ((!m_interface->desktopIsActive() && m_interface->dockIsCovered()) - || (m_isDockWindowType && m_isAutoHidden)) { - emit mustBeRaised(); - } else { - showOnTop(); - } - } - - break; - - /* case Latte::Dock::LetWindowsCover: - - //this is not supported in clean Dock Window Types such as in wayland case - if (m_isDockWindowType) { - return; - } - - if (!m_isHovered && m_interface->dockIsOnTop()) { - if (m_interface->dockIsCovering()) { - if (!m_disableHiding) { - emit mustBeLowered(); - } - } else { - showOnBottom(); - } - } else if (m_windowIsInAttention) { - if (!m_interface->dockIsOnTop()) { - if (m_interface->dockIsCovered()) { - emit mustBeRaised(); - } else { - showOnTop(); - } - } - } - - break; - - case LatteDock::Types::WindowsGoBelow: - //Do nothing, the dock is OnTop state in every case - break;*/ - - case Latte::Dock::AutoHide: - if (m_windowIsInAttention && m_isAutoHidden) { - emit mustBeRaised(); - } else if (!m_isHovered && !m_disableHiding) { - emit mustBeLowered(); - } - - break; - - case Latte::Dock::AlwaysVisible: - //Do nothing, the dock in OnTop state in every case - break; - } - + d->setIsHidden(isHidden); } -void VisibilityManager::showOnTop() +bool VisibilityManager::containsMouse() const { - // qDebug() << "reached make top..."; - m_interface->showDockOnTop(); + return d->containsMouse; } -void VisibilityManager::showNormal() +int VisibilityManager::timerShow() const { - // qDebug() << "reached make normal..."; - m_interface->showDockAsNormal(); + return d->timerShow.interval(); } -void VisibilityManager::showOnBottom() +void VisibilityManager::setTimerShow(int msec) { - // qDebug() << "reached make bottom..."; - m_interface->showDockOnBottom(); + d->setTimerShow(msec); } -/***************/ -void VisibilityManager::activeWindowChanged() +int VisibilityManager::timerHide() const { - // if ((m_panelVisibility == LatteDock::Types::WindowsGoBelow) - if ((m_panelVisibility == Latte::Dock::AlwaysVisible) - || (m_panelVisibility == Latte::Dock::AutoHide)) { - return; - } - - //this check is important because otherwise the signals are so often - //that the timer is never triggered - if (!m_updateStateTimer.isActive()) { - m_updateStateTimer.start(); - } + return d->timerHide.interval(); } - -//It is used in order to trigger a beautiful slide in effect when -//the dock is totally hidden underneath -void VisibilityManager::showOnTopCheck() +void VisibilityManager::setTimerHide(int msec) { - if ((m_panelVisibility == Latte::Dock::DodgeActive) || (m_panelVisibility == Latte::Dock::DodgeMaximized)) { - //|| (m_panelVisibility == Latte::Dock::LetWindowsCover)) { - if (m_interface->dockIsCovered(true)) { - m_updateStateTimer.stop(); - setIsHovered(true); - - emit mustBeRaisedImmediately(); - } else { - showOnTop(); - } - } + d->setTimerHide(msec); } -bool VisibilityManager::event(QEvent *event) +void VisibilityManager::updateDockGeometry(const QRect &geometry) { - if (!event) { - return false; - } - - if ((event->type() == QEvent::Enter) && !m_isHovered) { - m_updateStateTimer.stop(); - setIsHovered(true); - - if ((m_panelVisibility == Latte::Dock::AutoHide) || (m_isDockWindowType)) { - if (m_isAutoHidden) { - emit mustBeRaised(); - } - } else { - showOnTop(); - } - } else if (event->type() == QEvent::Leave) { - setIsHovered(false); - - // if ((m_panelVisibility != LatteDock::Types::WindowsGoBelow) && - if (m_panelVisibility != Latte::Dock::AlwaysVisible) { - m_updateStateTimer.start(); - } - } - - return true; + d->setDockRect(geometry); +} + +//! END: VisibilityManager implementation } + +#include "abstractwindowinterface.h" +#include "xwindowinterface.h" +#include "plasmaquick/containmentview.h" + + + + diff --git a/app/visibilitymanager_p.h b/app/visibilitymanager_p.h new file mode 100644 index 000000000..4f330791c --- /dev/null +++ b/app/visibilitymanager_p.h @@ -0,0 +1,64 @@ +#ifndef VISIBILITYMANAGERPRIVATE_H +#define VISIBILITYMANAGERPRIVATE_H + +#include "../liblattedock/dock.h" +#include "windowinfowrap.h" + +#include +#include + +#include +#include +#include + +#include + +namespace Latte { + +class VisibilityManager; + +/*! + * \brief The Latte::VisibilityManagerPrivate is a class d-pointer + */ +class VisibilityManagerPrivate : public QObject { + Q_GADGET + +public: + VisibilityManagerPrivate(PlasmaQuick::ContainmentView *view, VisibilityManager *q); + ~VisibilityManagerPrivate(); + + void setMode(Dock::Visibility mode); + void setTimerShow(int msec); + void setTimerHide(int msec); + + void raiseDock(bool raise); + + void setDockRect(const QRect &rect); + + void windowAdded(WId id); + void dodgeActive(WId id); + void dodgeWindows(WId id); + void checkAllWindows(); + + bool intersects(const WindowInfoWrap &info); + + void saveConfig(); + void restoreConfig(); + + bool event(QEvent *ev) override; + + VisibilityManager *q; + Dock::Visibility mode{Dock::DodgeActive}; + std::array connections; + std::unordered_map> windows; + QTimer timerShow; + QTimer timerHide; + QTimer timerCheckWindows; + QRect dockRect; + bool isHidden{false}; + bool containsMouse{false}; +}; + +} + +#endif // VISIBILITYMANAGERPRIVATE_H From 206f115e01f877c69725f8a1274e68ac6c79f388 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Thu, 29 Dec 2016 00:42:55 -0500 Subject: [PATCH 26/46] const correctness and namespace --- app/visibilitymanager.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/visibilitymanager.h b/app/visibilitymanager.h index 7a7308bbd..a563a7e8d 100644 --- a/app/visibilitymanager.h +++ b/app/visibilitymanager.h @@ -9,6 +9,10 @@ #include +namespace Latte { + +class VisibilityManagerPrivate; + class VisibilityManager : public QObject { Q_OBJECT @@ -39,7 +43,7 @@ public: /** * @brief updateDockGeometry, the window geometry in absolute coordinates. */ - void updateDockGeometry(QRect &geometry); + void updateDockGeometry(const QRect &geometry); signals: void mustBeShown(); @@ -54,4 +58,6 @@ signals: private: VisibilityManagerPrivate *const d; }; + +} #endif // VISIBILITYMANAGER_H From b65a97d92af698ccefda3610aa941a521a5105e1 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Thu, 29 Dec 2016 00:43:26 -0500 Subject: [PATCH 27/46] formatted --- app/main.cpp | 2 +- app/nowdockconfigview.cpp | 22 +++++++++++----------- app/nowdockconfigview.h | 2 +- app/nowdockcorona.cpp | 22 +++++++++++----------- app/nowdockview.cpp | 8 ++++---- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/app/main.cpp b/app/main.cpp index 0f503c9cf..477ca7309 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -54,7 +54,7 @@ int main(int argc, char **argv) QApplication app(argc, argv); app.setApplicationVersion(version); - + app.setOrganizationDomain(QStringLiteral("latte-dock")); KLocalizedString::setApplicationDomain("latte-dock"); app.setApplicationName(QStringLiteral("Latte Dock")); diff --git a/app/nowdockconfigview.cpp b/app/nowdockconfigview.cpp index 06f0486bb..f87ba0eb1 100644 --- a/app/nowdockconfigview.cpp +++ b/app/nowdockconfigview.cpp @@ -91,7 +91,7 @@ void NowDockConfigView::syncGeometry() { if (!m_containment || !rootObject()) return; - + const auto location = m_containment->location(); const auto sGeometry = screen()->geometry(); @@ -101,7 +101,7 @@ void NowDockConfigView::syncGeometry() setMaximumSize(size); setMinimumSize(size); resize(size); - + if (location == Plasma::Types::TopEdge) { setPosition(sGeometry.center().x() - size.width() / 2 , m_dockView->currentThickness()); @@ -117,7 +117,7 @@ void NowDockConfigView::syncGeometry() setMaximumSize(size); setMinimumSize(size); resize(size); - + if (location == Plasma::Types::LeftEdge) { setPosition(m_dockView->currentThickness() , sGeometry.center().y() - size.height() / 2); @@ -139,26 +139,26 @@ void NowDockConfigView::syncSlideEffect() { if (!m_containment) return; - + KWindowEffects::SlideFromLocation slideLocation{KWindowEffects::NoEdge}; switch (m_containment->location()) { case Plasma::Types::TopEdge: slideLocation = KWindowEffects::TopEdge; break; - + case Plasma::Types::RightEdge: slideLocation = KWindowEffects::RightEdge; break; - + case Plasma::Types::BottomEdge: slideLocation = KWindowEffects::BottomEdge; break; - + case Plasma::Types::LeftEdge: slideLocation = KWindowEffects::LeftEdge; break; - + default: qDebug() << staticMetaObject.className() << "wrong location";// << qEnumToStr(m_containment->location()); break; @@ -180,7 +180,7 @@ void NowDockConfigView::showEvent(QShowEvent *ev) if (m_containment) m_containment->setUserConfiguring(true); - + // m_dockView->visibility()->forceShow(true); // m_dockView->visibility()->showImmediately(); m_screenSyncTimer.start(); @@ -219,8 +219,8 @@ void NowDockConfigView::focusOutEvent(QFocusEvent *ev) if (focusWindow && focusWindow->flags().testFlag(Qt::Popup)) return; - - + + // hide(); } diff --git a/app/nowdockconfigview.h b/app/nowdockconfigview.h index 168fce542..50933e166 100644 --- a/app/nowdockconfigview.h +++ b/app/nowdockconfigview.h @@ -53,7 +53,7 @@ protected: void syncGeometry(); void syncSlideEffect(); - + private Q_SLOTS: void immutabilityChanged(Plasma::Types::ImmutabilityType type); void configurationShown(PlasmaQuick::ConfigView *configView); diff --git a/app/nowdockcorona.cpp b/app/nowdockcorona.cpp index 49b54383b..600d0c124 100644 --- a/app/nowdockcorona.cpp +++ b/app/nowdockcorona.cpp @@ -54,11 +54,11 @@ NowDockCorona::NowDockCorona(QObject *parent) setKPackage(package); qmlRegisterTypes(); - + connect(this, &Corona::containmentAdded, this, &NowDockCorona::addDock); - + loadLayout(); - + /*QAction *addDock = actions()->add(QStringLiteral("add dock")); connect(addDock, &QAction::triggered, this, &NowDockCorona::loadDefaultLayout); addDock->setText(i18n("Add New Dock")); @@ -66,7 +66,7 @@ NowDockCorona::NowDockCorona(QObject *parent) addDock->setStatusTip(tr("Adds a new dock in the environment")); addDock->setVisible(true); addDock->setEnabled(true); - + addDock->setIcon(QIcon::fromTheme(QStringLiteral("object-locked"))); addDock->setData(Plasma::Types::ControlAction); addDock->setShortcut(QKeySequence(QStringLiteral("alt+d, l"))); @@ -150,21 +150,21 @@ void NowDockCorona::addDock(Plasma::Containment *containment) qWarning() << "the requested containment plugin can not be located or loaded"; return; } - + // the system tray is a containment that behaves as an applet // so a dockview shouldnt be created for it KPluginMetaData metadata = containment->kPackage().metadata(); - + if (metadata.pluginId() == "org.kde.plasma.systemtray") { return; } - + foreach (NowDockView *dock, m_containments) { if (dock->containment() == containment) { return; } } - + qWarning() << "Adding dock for container..."; auto dockView = new NowDockView(this); @@ -185,7 +185,7 @@ void NowDockCorona::loadDefaultLayout() QVariantList args; auto defaultContainment = createContainmentDelayed("org.kde.latte.containment", args); - + defaultContainment->setContainmentType(Plasma::Types::PanelContainment); defaultContainment->init(); @@ -193,7 +193,7 @@ void NowDockCorona::loadDefaultLayout() qWarning() << "the requested containment plugin can not be located or loaded"; return; } - + auto config = defaultContainment->config(); defaultContainment->restore(config); @@ -211,7 +211,7 @@ void NowDockCorona::loadDefaultLayout() defaultContainment->flushPendingConstraintsEvents(); emit containmentAdded(defaultContainment); emit containmentCreated(defaultContainment); - + addDock(defaultContainment); defaultContainment->createApplet(QStringLiteral("org.kde.latte.plasmoid")); diff --git a/app/nowdockview.cpp b/app/nowdockview.cpp index ddb756aef..c91ddb57a 100644 --- a/app/nowdockview.cpp +++ b/app/nowdockview.cpp @@ -119,7 +119,7 @@ void NowDockView::init() rootContext()->setContextProperty(QStringLiteral("dock"), this); engine()->rootContext()->setContextObject(new KLocalizedContext(this)); - + // engine()->rootContext()->setContextProperty(QStringLiteral("dock"), this); setSource(corona()->kPackage().filePath("nowdockui")); @@ -189,7 +189,7 @@ void NowDockView::adaptToScreen(QScreen *screen) void NowDockView::addNewDock() { NowDockCorona *corona = dynamic_cast(m_corona); - + if (corona) { corona->loadDefaultLayout(); } @@ -198,10 +198,10 @@ void NowDockView::addNewDock() void NowDockView::removeDock() { NowDockCorona *corona = dynamic_cast(m_corona); - + if (corona->containments().count() > 1) { QAction *removeAct = containment()->actions()->action(QStringLiteral("remove")); - + if (removeAct) { removeAct->trigger(); } From 10816064458331e34b766d04a7fc6f1d796d9b06 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Fri, 30 Dec 2016 02:09:21 -0500 Subject: [PATCH 28/46] Added X11Extras dependence --- CMakeLists.txt | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c7c79935..916a28d57 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,10 @@ project(lattedock) cmake_minimum_required(VERSION 3.0 FATAL_ERROR) -set (CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD 11) set(VERSION 0.5.89) -set(AUTHOR "Michail Vourlakos") -set(EMAIL "mvourlakos@gmail.com") +set(AUTHOR "Michail Vourlakos, Smith Ar") +set(EMAIL "mvourlakos@gmail.com, audoban@openmailbox.org") set(WEBSITE "https://github.com/psifidotos/Latte-Dock") set(QT_MIN_VERSION "5.6.0") @@ -15,13 +15,12 @@ find_package(ECM 1.8.0 REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS - Quick QuickWidgets) + Quick QuickWidgets X11Extras) find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS Plasma PlasmaQuick WindowSystem Declarative I18n CoreAddons XmlGui DBusAddons Notifications) -include(FakeTarget.cmake) FIND_PROGRAM(GETTEXT_MSGFMT_EXECUTABLE msgfmt) @@ -122,6 +121,8 @@ ELSE(NOT GETTEXT_MSGFMT_EXECUTABLE) ENDIF(NOT GETTEXT_MSGFMT_EXECUTABLE) +add_subdirectory(app) + add_subdirectory(liblattedock) add_subdirectory(containment) plasma_install_package(build/containment/release org.kde.latte.containment) @@ -131,7 +132,5 @@ plasma_install_package(build/plasmoid/release org.kde.latte.plasmoid) add_subdirectory(shell) plasma_install_package(build/shell/release org.kde.latte.shell shells shell) -add_subdirectory(app) - add_subdirectory(icons) From c2e7e3db9b52324b11820d78280d0b71c59127fe Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Fri, 30 Dec 2016 02:10:12 -0500 Subject: [PATCH 29/46] FakeTarget moved to app/ --- app/CMakeLists.txt | 4 ++++ FakeTarget.cmake => app/FakeTarget.cmake | 12 ++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) rename FakeTarget.cmake => app/FakeTarget.cmake (74%) diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 4f74aa69f..e12d770d7 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -30,11 +30,14 @@ set(lattedock-app_SRCS add_executable(latte-dock ${lattedock-app_SRCS}) +include(FakeTarget.cmake) + target_link_libraries( latte-dock Qt5::Widgets Qt5::Quick Qt5::Qml + Qt5::X11Extras KF5::I18n KF5::CoreAddons KF5::XmlGui @@ -43,6 +46,7 @@ target_link_libraries( KF5::QuickAddons KF5::DBusAddons KF5::Notifications + KF5::WindowSystem ) install(TARGETS latte-dock ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) diff --git a/FakeTarget.cmake b/app/FakeTarget.cmake similarity index 74% rename from FakeTarget.cmake rename to app/FakeTarget.cmake index a42dac188..e2127ae35 100644 --- a/FakeTarget.cmake +++ b/app/FakeTarget.cmake @@ -1,13 +1,13 @@ -execute_process(COMMAND find shell containment plasmoid -name "*.qml" -o -name "*.js" - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} +execute_process(COMMAND find ../shell ../containment ../plasmoid -name "*.qml" -o -name "*.js" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE QML_SRCS_STRING) string(REPLACE "\n" ";" QML_SRCS ${QML_SRCS_STRING}) # fake target for QtCreator project add_custom_target(fake-target - SOURCES ${QML_SRCS} - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + SOURCES ${QML_SRCS}) # qmllint: qml static syntax checker if(${CMAKE_BUILD_TYPE} MATCHES "Debug") @@ -15,9 +15,9 @@ if(${CMAKE_BUILD_TYPE} MATCHES "Debug") if(EXISTS "${QMLLINT}") message("-- Found qmllint: ${QMLLINT}") - add_custom_command(TARGET candil PRE_BUILD + add_custom_command(TARGET latte-dock PRE_BUILD COMMAND ${QMLLINT} ${QML_SRCS} - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Running qmllint") else() message("-- qmllint: QML Syntax verifier not found") From 45347200cde3df1cfa1a6c123591ac1de649b8dc Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Fri, 30 Dec 2016 02:11:42 -0500 Subject: [PATCH 30/46] update signatures on abstractwindowinterface.h --- app/abstractwindowinterface.h | 6 +++++- app/xwindowinterface.cpp | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/abstractwindowinterface.h b/app/abstractwindowinterface.h index 2877de4b7..247b0171e 100644 --- a/app/abstractwindowinterface.h +++ b/app/abstractwindowinterface.h @@ -16,6 +16,8 @@ namespace Latte { +class XWindowInterface; + class AbstractWindowInterface : public QObject { Q_OBJECT @@ -33,9 +35,11 @@ public: virtual void setDockStruts(const QRect &dockRect, Plasma::Types::Location location) = 0; virtual void removeDockStruts() = 0; + static AbstractWindowInterface *getInstance(QQuickWindow *const view, QObject *parent = nullptr); + signals: void activeWindowChanged(WId wid); - void windowChanged(const WindowInfoWrap &winfo); + void windowChanged(WId winfo); void windowAdded(WId wid); void windowRemoved(WId wid); void currentDesktopChanged(int desktop); diff --git a/app/xwindowinterface.cpp b/app/xwindowinterface.cpp index 411c567b4..3ad11b39c 100644 --- a/app/xwindowinterface.cpp +++ b/app/xwindowinterface.cpp @@ -5,6 +5,7 @@ #include #include +#include #include namespace Latte { @@ -167,7 +168,7 @@ void XWindowInterface::windowChangedProxy(WId wid, NET::Properties prop1, NET::P if (prop1 && !(prop1 & NET::WMState || prop1 & NET::WMGeometry || prop1 & NET::ActiveWindow)) return; - emit windowChanged(requestInfo(wid)); + emit windowChanged(wid); } } From 1d5dcbf014f7941c957f739869cdbcf80456cbcf Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Fri, 30 Dec 2016 02:13:33 -0500 Subject: [PATCH 31/46] static method for get a instance of abstractwindowinterface NOTE: WaylandWindowInterface has not been implemented --- app/abstractwindowinterface.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/app/abstractwindowinterface.cpp b/app/abstractwindowinterface.cpp index edf970246..84948f899 100644 --- a/app/abstractwindowinterface.cpp +++ b/app/abstractwindowinterface.cpp @@ -1,8 +1,11 @@ #include "abstractwindowinterface.h" +#include "xwindowinterface.h" #include #include +#include + namespace Latte { AbstractWindowInterface::AbstractWindowInterface(QQuickWindow *const view, QObject *parent) @@ -13,9 +16,18 @@ AbstractWindowInterface::AbstractWindowInterface(QQuickWindow *const view, QObje AbstractWindowInterface::~AbstractWindowInterface() { - + } - +AbstractWindowInterface *AbstractWindowInterface::getInstance(QQuickWindow * const view, QObject *parent) +{ + if (KWindowSystem::isPlatformWayland()) { + //! TODO: WaylandWindowInterface + return nullptr; + } + + /* if(KWindowSystem::isPlatformX11) */ + return new XWindowInterface(view, parent); +} } From aa10cda7f7e3e9ca018657bd41a17def0646e0a8 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Fri, 30 Dec 2016 02:13:57 -0500 Subject: [PATCH 32/46] include guard --- app/windowinfowrap.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/windowinfowrap.h b/app/windowinfowrap.h index ca193e752..e3a817b5b 100644 --- a/app/windowinfowrap.h +++ b/app/windowinfowrap.h @@ -1,5 +1,5 @@ -#ifndef WINDOWINFO_H -#define WINDOWINFO_H +#ifndef WINDOWINFOWRAP_H +#define WINDOWINFOWRAP_H #include #include @@ -56,4 +56,4 @@ private: } -#endif // WINDOWINFO_H +#endif // WINDOWINFOWRAP_H From 9ad00b2354b041f5d8e037134d9a31b99df6e37d Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Fri, 30 Dec 2016 02:16:27 -0500 Subject: [PATCH 33/46] the inline function cause build errors, removed for now --- app/windowinfowrap.cpp | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/app/windowinfowrap.cpp b/app/windowinfowrap.cpp index aa772bcce..8c3a1acf8 100644 --- a/app/windowinfowrap.cpp +++ b/app/windowinfowrap.cpp @@ -1,6 +1,6 @@ #include "windowinfowrap.h" -using namespace Latte; +namespace Latte { WindowInfoWrap::WindowInfoWrap() : m_isValid(false) @@ -33,98 +33,99 @@ WindowInfoWrap &WindowInfoWrap::operator=(const WindowInfoWrap &rhs) return *this; } -inline bool WindowInfoWrap::operator==(const WindowInfoWrap &rhs) const + bool WindowInfoWrap::operator==(const WindowInfoWrap &rhs) const { return m_wid == rhs.m_wid; } -inline bool WindowInfoWrap::operator<(const WindowInfoWrap &rhs) const + bool WindowInfoWrap::operator<(const WindowInfoWrap &rhs) const { return m_wid < rhs.m_wid; } -inline bool WindowInfoWrap::operator>(const WindowInfoWrap &rhs) const + bool WindowInfoWrap::operator>(const WindowInfoWrap &rhs) const { return m_wid > rhs.m_wid; } -inline bool WindowInfoWrap::isValid() const + bool WindowInfoWrap::isValid() const { return m_isValid; } -inline void WindowInfoWrap::setIsValid(bool isValid) + void WindowInfoWrap::setIsValid(bool isValid) { m_isValid = isValid; } -inline bool WindowInfoWrap::isActive() const + bool WindowInfoWrap::isActive() const { return m_isActive; } -inline void WindowInfoWrap::setIsActive(bool isActive) + void WindowInfoWrap::setIsActive(bool isActive) { m_isActive = isActive; } -inline bool WindowInfoWrap::isMinimized() const + bool WindowInfoWrap::isMinimized() const { return m_isMinimized; } -inline void WindowInfoWrap::setIsMinimized(bool isMinimized) + void WindowInfoWrap::setIsMinimized(bool isMinimized) { m_isMinimized = isMinimized; } -inline bool WindowInfoWrap::isMaximized() const + bool WindowInfoWrap::isMaximized() const { return m_isMaximized; } -inline void WindowInfoWrap::setIsMaximized(bool isMaximized) + void WindowInfoWrap::setIsMaximized(bool isMaximized) { m_isMaximized = isMaximized; } -inline bool WindowInfoWrap::isFullscreen() const + bool WindowInfoWrap::isFullscreen() const { return m_isFullscreen; } -inline void WindowInfoWrap::setIsFullscreen(bool isFullscreen) + void WindowInfoWrap::setIsFullscreen(bool isFullscreen) { m_isFullscreen = isFullscreen; } -inline bool WindowInfoWrap::isOnCurrentDesktop() const + bool WindowInfoWrap::isOnCurrentDesktop() const { return m_isOnCurrentDesktop; } -inline void WindowInfoWrap::setIsOnCurrentDesktop(bool isOnCurrentDesktop) + void WindowInfoWrap::setIsOnCurrentDesktop(bool isOnCurrentDesktop) { m_isOnCurrentDesktop = isOnCurrentDesktop; } -inline QRect WindowInfoWrap::geometry() const + QRect WindowInfoWrap::geometry() const { return m_geometry; } -inline void WindowInfoWrap::setGeometry(const QRect &geometry) + void WindowInfoWrap::setGeometry(const QRect &geometry) { m_geometry = geometry; } -inline WId WindowInfoWrap::wid() const + WId WindowInfoWrap::wid() const { return m_wid; } -inline void WindowInfoWrap::setWid(WId wid) + void WindowInfoWrap::setWid(WId wid) { m_wid = wid; } +} From 948b03a357d4e7e4750577d04baf49de6b38e3d6 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Fri, 30 Dec 2016 02:17:38 -0500 Subject: [PATCH 34/46] Visibility manager has been implemented, but need integration on qml --- app/visibilitymanager.cpp | 221 +++++++++++++++++++++++++++++++++----- app/visibilitymanager_p.h | 11 +- 2 files changed, 201 insertions(+), 31 deletions(-) diff --git a/app/visibilitymanager.cpp b/app/visibilitymanager.cpp index 537e18211..27639879c 100644 --- a/app/visibilitymanager.cpp +++ b/app/visibilitymanager.cpp @@ -1,42 +1,135 @@ #include "visibilitymanager.h" #include "visibilitymanager_p.h" +#include "windowinfowrap.h" + +#include "../liblattedock/extras.h" namespace Latte { //! BEGIN: VisiblityManagerPrivate implementation VisibilityManagerPrivate::VisibilityManagerPrivate(PlasmaQuick::ContainmentView *view, VisibilityManager *q) - : QObject(view), q(q) + : QObject(view), q(q), view(view), wm(AbstractWindowInterface::getInstance(view, nullptr)) { - + timerCheckWindows.setInterval(350); + timerCheckWindows.setSingleShot(true); + + timerShow.setSingleShot(true); + timerHide.setSingleShot(true); + + restoreConfig(); + + connect(&timerCheckWindows, &QTimer::timeout, this, &VisibilityManagerPrivate::checkAllWindows); + connect(&timerShow, &QTimer::timeout, q, &VisibilityManager::mustBeShown); + connect(&timerHide, &QTimer::timeout, q, &VisibilityManager::mustBeHide); } VisibilityManagerPrivate::~VisibilityManagerPrivate() { - + wm->removeDockStruts(); } -void VisibilityManagerPrivate::setMode(Dock::Visibility mode) +inline void VisibilityManagerPrivate::setMode(Dock::Visibility mode) { - + if (this->mode == mode) + return; + + // clear mode + if (this->mode == Dock::AlwaysVisible) + wm->removeDockStruts(); + + for (auto &c : connections) { + disconnect(c); + } + + timerShow.stop(); + timerHide.stop(); + timerCheckWindows.stop(); + + this->mode = mode; + + switch (this->mode) { + case Dock::AlwaysVisible: + { + wm->setDockStruts(dockRect, view->location()); + raiseDock(true); + } + break; + case Dock::AutoHide: + { + raiseDock(true); + } + break; + case Dock::DodgeActive: + { + connections[0] = connect(wm.get(), &AbstractWindowInterface::activeWindowChanged + , this, &VisibilityManagerPrivate::dodgeActive); + connections[1] = connect(wm.get(), &AbstractWindowInterface::windowChanged + , this, &VisibilityManagerPrivate::dodgeActive); + + dodgeActive(wm->activeWindow()); + } + break; + case Dock::DodgeMaximized: + { + connections[0] = connect(wm.get(), &AbstractWindowInterface::windowChanged + , this, &VisibilityManagerPrivate::dodgeMaximized); + } + break; + case Dock::DodgeAllWindows: + { + for(const auto & wid : wm->windows()) { + windows.insert({wid, wm->requestInfo(wid)}); + } + + connections[0] = connect(wm.get(), &AbstractWindowInterface::windowChanged + , this, &VisibilityManagerPrivate::dodgeWindows); + + connections[1] = connect(wm.get(), &AbstractWindowInterface::windowRemoved + , this, [&](WId wid) { + windows.erase(wid); + timerCheckWindows.start(); + }); + connections[2] = connect(wm.get(), &AbstractWindowInterface::windowAdded + , this, [&](WId wid) { + windows.insert({wid, wm->requestInfo(wid)}); + timerCheckWindows.start(); + }); + } + } + + saveConfig(); } -void VisibilityManagerPrivate::setIsHidden(bool isHidden) +inline void VisibilityManagerPrivate::setIsHidden(bool isHidden) { - + if (this->isHidden == isHidden) + return; + + this->isHidden = isHidden; + emit q->isHiddenChanged(); } -void VisibilityManagerPrivate::setTimerShow(int msec) +inline void VisibilityManagerPrivate::setTimerShow(int msec) { - + timerShow.setInterval(msec); + saveConfig(); + emit q->timerShowChanged(); } -void VisibilityManagerPrivate::setTimerHide(int msec) +inline void VisibilityManagerPrivate::setTimerHide(int msec) { - + timerHide.setInterval(msec); + saveConfig(); + emit q->timerHideChanged(); } -void VisibilityManagerPrivate::raiseDock(bool raise) +inline void VisibilityManagerPrivate::raiseDock(bool raise) { + // possible optimization + /* if (!isHidden == raise) { + return; + } */ + if (raise) { timerHide.stop(); @@ -50,44 +143,116 @@ void VisibilityManagerPrivate::raiseDock(bool raise) } } -void VisibilityManagerPrivate::setDockRect(const QRect &rect) +inline void VisibilityManagerPrivate::setDockRect(const QRect &dockRect) { - + if (!view->containment() || this->dockRect == dockRect) + return; + + this->dockRect = dockRect; + + if (mode == Dock::AlwaysVisible) { + wm->setDockStruts(this->dockRect, view->containment()->location()); + } } -void VisibilityManagerPrivate::windowAdded(WId id) +void VisibilityManagerPrivate::dodgeActive(WId wid) { - + if (wid != wm->activeWindow()) + return; + + auto winfo = wm->requestInfo(wid); + + if (!winfo.isValid() || !winfo.isOnCurrentDesktop() || winfo.isMinimized()) + return; + + raiseDock(intersects(winfo)); } -void VisibilityManagerPrivate::dodgeActive(WId id) +void VisibilityManagerPrivate::dodgeMaximized(WId wid) { - + auto winfo = wm->requestInfo(wid); + + if (!winfo.isValid() || !winfo.isOnCurrentDesktop() || winfo.isMinimized()) + return; + + if (winfo.isMaximized()) + raiseDock(false); + else + timerCheckWindows.start(); } -void VisibilityManagerPrivate::dodgeWindows(WId id) +void VisibilityManagerPrivate::dodgeWindows(WId wid) { - + auto winfo = wm->requestInfo(wid); + + if (!winfo.isValid() || !winfo.isOnCurrentDesktop() || winfo.isMinimized()) + return; + + if (intersects(winfo)) + raiseDock(false); + else + timerCheckWindows.start(); } void VisibilityManagerPrivate::checkAllWindows() { - + bool raise{true}; + + for (const auto &winfo : windows) { + //! std::pair + if (!std::get<1>(winfo).isValid() || !std::get<1>(winfo).isOnCurrentDesktop()) + continue; + + if (std::get<1>(winfo).isFullscreen()) { + raise = false; + break; + + } else if (std::get<1>(winfo).isMinimized()) { + continue; + + } else if (mode == Dock::DodgeMaximized) { + if (std::get<1>(winfo).isMaximized()) + raise = false; + + continue; + } else if (intersects(std::get<1>(winfo))) { + raise = false; + break; + } + } + + raiseDock(raise); } -bool VisibilityManagerPrivate::intersects(const WindowInfoWrap &info) +inline bool VisibilityManagerPrivate::intersects(const WindowInfoWrap &winfo) { - + return winfo.geometry().intersects(dockRect); } -void VisibilityManagerPrivate::saveConfig() +inline void VisibilityManagerPrivate::saveConfig() { - + if (!view->containment()) + return; + + auto config = view->containment()->config(); + + config.writeEntry("visibility", static_cast(mode)); + config.writeEntry("timerShow", timerShow.interval()); + config.writeEntry("timerHide", timerHide.interval()); + + view->containment()->configNeedsSaving(); } -void VisibilityManagerPrivate::restoreConfig() +inline void VisibilityManagerPrivate::restoreConfig() { - + if (!view->containment()) + return; + + auto config = view->containment()->config(); + + mode = static_cast(config.readEntry("visibility", static_cast(Dock::DodgeActive))); + timerShow.setInterval(config.readEntry("timerShow", 0)); + timerHide.setInterval(config.readEntry("timerHide", 0)); } bool VisibilityManagerPrivate::event(QEvent *ev) @@ -139,7 +304,7 @@ bool VisibilityManager::isHidden() const return d->isHidden; } -void VisibilityManager::setHidden(bool isHidden) +void VisibilityManager::setIsHidden(bool isHidden) { d->setIsHidden(isHidden); } diff --git a/app/visibilitymanager_p.h b/app/visibilitymanager_p.h index 4f330791c..c42d8e11b 100644 --- a/app/visibilitymanager_p.h +++ b/app/visibilitymanager_p.h @@ -3,9 +3,10 @@ #include "../liblattedock/dock.h" #include "windowinfowrap.h" +#include "abstractwindowinterface.h" -#include #include +#include #include #include @@ -28,6 +29,7 @@ public: ~VisibilityManagerPrivate(); void setMode(Dock::Visibility mode); + void setIsHidden(bool isHidden); void setTimerShow(int msec); void setTimerHide(int msec); @@ -37,10 +39,11 @@ public: void windowAdded(WId id); void dodgeActive(WId id); + void dodgeMaximized(WId id); void dodgeWindows(WId id); void checkAllWindows(); - bool intersects(const WindowInfoWrap &info); + bool intersects(const WindowInfoWrap &winfo); void saveConfig(); void restoreConfig(); @@ -48,9 +51,11 @@ public: bool event(QEvent *ev) override; VisibilityManager *q; + PlasmaQuick::ContainmentView *view; + std::unique_ptr wm; Dock::Visibility mode{Dock::DodgeActive}; std::array connections; - std::unordered_map> windows; + std::unordered_map windows; QTimer timerShow; QTimer timerHide; QTimer timerCheckWindows; From 35aafde5b0babc8ca582a065edefce19f7883946 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Fri, 30 Dec 2016 02:18:08 -0500 Subject: [PATCH 35/46] fixed signatures --- app/visibilitymanager.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/visibilitymanager.h b/app/visibilitymanager.h index a563a7e8d..1dc9f8357 100644 --- a/app/visibilitymanager.h +++ b/app/visibilitymanager.h @@ -17,7 +17,7 @@ class VisibilityManager : public QObject { Q_OBJECT Q_PROPERTY(Latte::Dock::Visibility mode READ mode WRITE setMode NOTIFY modeChanged) - Q_PROPERTY(bool isHidden READ isHidden WRITE isHidden NOTIFY isHiddenChanged) + Q_PROPERTY(bool isHidden READ isHidden WRITE setIsHidden NOTIFY isHiddenChanged) Q_PROPERTY(bool containsMouse READ containsMouse NOTIFY containsMouseChanged) Q_PROPERTY(int timerShow READ timerShow WRITE setTimerShow NOTIFY timerShowChanged) Q_PROPERTY(int timerHide READ timerHide WRITE setTimerHide NOTIFY timerHideChanged) @@ -30,7 +30,7 @@ public: void setMode(Latte::Dock::Visibility mode); bool isHidden() const; - void setHidden(bool isHidden); + void setIsHidden(bool isHidden); bool containsMouse() const; From 335e473a64abb8bfe98435b91300813b4e790524 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Fri, 30 Dec 2016 02:20:06 -0500 Subject: [PATCH 36/46] class inserts into namespace Latte --- app/main.cpp | 2 +- app/nowdockconfigview.cpp | 3 +++ app/nowdockconfigview.h | 4 ++++ app/nowdockcorona.cpp | 4 ++++ app/nowdockcorona.h | 3 +++ app/nowdockview.cpp | 5 +++-- app/nowdockview.h | 8 ++++---- 7 files changed, 22 insertions(+), 7 deletions(-) diff --git a/app/main.cpp b/app/main.cpp index 477ca7309..3c8dcb02e 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -72,7 +72,7 @@ int main(int argc, char **argv) "%{if-critical}\n%{backtrace depth=" DEPTH " separator=\"\n\"}%{endif}" CNORMAL)); // qputenv("QT_QUICK_CONTROLS_1_STYLE", "Desktop"); - NowDockCorona corona; + Latte::NowDockCorona corona; return app.exec(); } diff --git a/app/nowdockconfigview.cpp b/app/nowdockconfigview.cpp index f87ba0eb1..a65b6f7ba 100644 --- a/app/nowdockconfigview.cpp +++ b/app/nowdockconfigview.cpp @@ -32,6 +32,8 @@ #include +namespace Latte { + NowDockConfigView::NowDockConfigView(Plasma::Containment *containment, NowDockView *dockView, QWindow *parent) : PlasmaQuick::ConfigView(containment, parent), m_containment(containment), m_dockView(dockView) { @@ -238,4 +240,5 @@ void NowDockConfigView::immutabilityChanged(Plasma::Types::ImmutabilityType type } } +} // kate: indent-mode cstyle; indent-width 4; replace-tabs on; diff --git a/app/nowdockconfigview.h b/app/nowdockconfigview.h index 50933e166..0076ffb98 100644 --- a/app/nowdockconfigview.h +++ b/app/nowdockconfigview.h @@ -34,6 +34,8 @@ class Containment; class Types; } +namespace Latte { + class NowDockView; class NowDockConfigView : public PlasmaQuick::ConfigView { @@ -65,5 +67,7 @@ private: QTimer m_screenSyncTimer; }; + +} #endif //DOCKCONFIGVIEW_H // kate: indent-mode cstyle; indent-width 4; replace-tabs on; diff --git a/app/nowdockcorona.cpp b/app/nowdockcorona.cpp index 600d0c124..4326a871d 100644 --- a/app/nowdockcorona.cpp +++ b/app/nowdockcorona.cpp @@ -38,6 +38,8 @@ #include #include +namespace Latte { + NowDockCorona::NowDockCorona(QObject *parent) : Plasma::Corona(parent) { @@ -229,3 +231,5 @@ inline void NowDockCorona::qmlRegisterTypes() const // qmlRegisterUncreatableType(uri, vMajor, vMinor, "DockView", "class DockView uncreatable"); qmlRegisterType(); } + +} diff --git a/app/nowdockcorona.h b/app/nowdockcorona.h index c3ff452b6..2888f8b59 100644 --- a/app/nowdockcorona.h +++ b/app/nowdockcorona.h @@ -33,6 +33,8 @@ class Containment; class Types; } +namespace Latte { + class NowDockCorona : public Plasma::Corona { Q_OBJECT @@ -63,5 +65,6 @@ private: std::vector m_containments; }; +} #endif diff --git a/app/nowdockview.cpp b/app/nowdockview.cpp index c91ddb57a..363766079 100644 --- a/app/nowdockview.cpp +++ b/app/nowdockview.cpp @@ -39,6 +39,7 @@ #include "nowdockcorona.h" +namespace Latte { NowDockView::NowDockView(Plasma::Corona *corona, QScreen *targetScreen) : PlasmaQuick::ContainmentView(corona), @@ -81,7 +82,6 @@ NowDockView::NowDockView(Plasma::Corona *corona, QScreen *targetScreen) m_visibility = new VisibilityManager(this); } - m_visibility->setContainment(containment()); }, Qt::DirectConnection); } @@ -417,7 +417,6 @@ void NowDockView::setMaskArea(QRect area) } m_maskArea = area; - m_visibility->setMaskArea(area); setMask(m_maskArea); @@ -577,6 +576,8 @@ void NowDockView::restoreConfig() // setAlignment(static_cast(readEntry("alignment", Dock::Center).toInt())); } +} + //!END SLOTS diff --git a/app/nowdockview.h b/app/nowdockview.h index f58f6af77..77cde3296 100644 --- a/app/nowdockview.h +++ b/app/nowdockview.h @@ -47,12 +47,12 @@ class DockConfigView; class VisibilityManager; }*/ +namespace Latte { + class NowDockView : public PlasmaQuick::ContainmentView { Q_OBJECT - Q_PROPERTY(bool compositing READ compositing NOTIFY compositingChanged) - Q_PROPERTY(int height READ height NOTIFY heightChanged) Q_PROPERTY(int length READ length WRITE setLength NOTIFY lengthChanged) Q_PROPERTY(int maxLength READ maxLength WRITE setMaxLength NOTIFY maxLengthChanged) @@ -61,9 +61,7 @@ class NowDockView : public PlasmaQuick::ContainmentView { Q_PROPERTY(int width READ width NOTIFY widthChanged) Q_PROPERTY(QRect maskArea READ maskArea WRITE setMaskArea NOTIFY maskAreaChanged) - Q_PROPERTY(VisibilityManager *visibility READ visibility NOTIFY visibilityChanged) - Q_PROPERTY(QQmlListProperty screens READ screens) public: @@ -165,4 +163,6 @@ private: void initWindow(); }; +} + #endif From 402583865b842be7adcf230148ff7b0f0348d273 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Fri, 30 Dec 2016 02:23:07 -0500 Subject: [PATCH 37/46] script for clean the directories --- clean.sh | 4 ++++ 1 file changed, 4 insertions(+) create mode 100755 clean.sh diff --git a/clean.sh b/clean.sh new file mode 100755 index 000000000..1348427ce --- /dev/null +++ b/clean.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +rm -v `find . -name '*.orig' -o -name '.directory' -o -name '*~' -o -name '*.user' -o -name '*.autosave'` +rm -rf ./build From 530c489ef90362d53db6e0ae0b86628d0e79c1d0 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Fri, 30 Dec 2016 02:24:04 -0500 Subject: [PATCH 38/46] code formatted --- app/abstractwindowinterface.cpp | 4 +- app/visibilitymanager.cpp | 107 ++++++++++++++++---------------- app/windowinfowrap.cpp | 40 ++++++------ 3 files changed, 75 insertions(+), 76 deletions(-) diff --git a/app/abstractwindowinterface.cpp b/app/abstractwindowinterface.cpp index 84948f899..90cce8c41 100644 --- a/app/abstractwindowinterface.cpp +++ b/app/abstractwindowinterface.cpp @@ -16,10 +16,10 @@ AbstractWindowInterface::AbstractWindowInterface(QQuickWindow *const view, QObje AbstractWindowInterface::~AbstractWindowInterface() { - + } -AbstractWindowInterface *AbstractWindowInterface::getInstance(QQuickWindow * const view, QObject *parent) +AbstractWindowInterface *AbstractWindowInterface::getInstance(QQuickWindow *const view, QObject *parent) { if (KWindowSystem::isPlatformWayland()) { //! TODO: WaylandWindowInterface diff --git a/app/visibilitymanager.cpp b/app/visibilitymanager.cpp index 27639879c..fb530e3f8 100644 --- a/app/visibilitymanager.cpp +++ b/app/visibilitymanager.cpp @@ -32,7 +32,7 @@ inline void VisibilityManagerPrivate::setMode(Dock::Visibility mode) { if (this->mode == mode) return; - + // clear mode if (this->mode == Dock::AlwaysVisible) wm->removeDockStruts(); @@ -48,53 +48,52 @@ inline void VisibilityManagerPrivate::setMode(Dock::Visibility mode) this->mode = mode; switch (this->mode) { - case Dock::AlwaysVisible: - { - wm->setDockStruts(dockRect, view->location()); - raiseDock(true); - } - break; - case Dock::AutoHide: - { - raiseDock(true); - } + case Dock::AlwaysVisible: { + wm->setDockStruts(dockRect, view->location()); + raiseDock(true); + } break; - case Dock::DodgeActive: - { - connections[0] = connect(wm.get(), &AbstractWindowInterface::activeWindowChanged - , this, &VisibilityManagerPrivate::dodgeActive); - connections[1] = connect(wm.get(), &AbstractWindowInterface::windowChanged - , this, &VisibilityManagerPrivate::dodgeActive); - dodgeActive(wm->activeWindow()); - } - break; - case Dock::DodgeMaximized: - { - connections[0] = connect(wm.get(), &AbstractWindowInterface::windowChanged - , this, &VisibilityManagerPrivate::dodgeMaximized); - } + case Dock::AutoHide: { + raiseDock(true); + } break; - case Dock::DodgeAllWindows: - { - for(const auto & wid : wm->windows()) { - windows.insert({wid, wm->requestInfo(wid)}); + + case Dock::DodgeActive: { + connections[0] = connect(wm.get(), &AbstractWindowInterface::activeWindowChanged + , this, &VisibilityManagerPrivate::dodgeActive); + connections[1] = connect(wm.get(), &AbstractWindowInterface::windowChanged + , this, &VisibilityManagerPrivate::dodgeActive); + + dodgeActive(wm->activeWindow()); } + break; - connections[0] = connect(wm.get(), &AbstractWindowInterface::windowChanged - , this, &VisibilityManagerPrivate::dodgeWindows); + case Dock::DodgeMaximized: { + connections[0] = connect(wm.get(), &AbstractWindowInterface::windowChanged + , this, &VisibilityManagerPrivate::dodgeMaximized); + } + break; - connections[1] = connect(wm.get(), &AbstractWindowInterface::windowRemoved - , this, [&](WId wid) { + case Dock::DodgeAllWindows: { + for (const auto &wid : wm->windows()) { + windows.insert({wid, wm->requestInfo(wid)}); + } + + connections[0] = connect(wm.get(), &AbstractWindowInterface::windowChanged + , this, &VisibilityManagerPrivate::dodgeWindows); + + connections[1] = connect(wm.get(), &AbstractWindowInterface::windowRemoved + , this, [&](WId wid) { windows.erase(wid); timerCheckWindows.start(); - }); - connections[2] = connect(wm.get(), &AbstractWindowInterface::windowAdded - , this, [&](WId wid) { + }); + connections[2] = connect(wm.get(), &AbstractWindowInterface::windowAdded + , this, [&](WId wid) { windows.insert({wid, wm->requestInfo(wid)}); timerCheckWindows.start(); - }); - } + }); + } } saveConfig(); @@ -104,7 +103,7 @@ inline void VisibilityManagerPrivate::setIsHidden(bool isHidden) { if (this->isHidden == isHidden) return; - + this->isHidden = isHidden; emit q->isHiddenChanged(); } @@ -145,7 +144,7 @@ inline void VisibilityManagerPrivate::raiseDock(bool raise) inline void VisibilityManagerPrivate::setDockRect(const QRect &dockRect) { - if (!view->containment() || this->dockRect == dockRect) + if (!view->containment() || this->dockRect == dockRect) return; this->dockRect = dockRect; @@ -159,12 +158,12 @@ void VisibilityManagerPrivate::dodgeActive(WId wid) { if (wid != wm->activeWindow()) return; - + auto winfo = wm->requestInfo(wid); if (!winfo.isValid() || !winfo.isOnCurrentDesktop() || winfo.isMinimized()) return; - + raiseDock(intersects(winfo)); } @@ -174,7 +173,7 @@ void VisibilityManagerPrivate::dodgeMaximized(WId wid) if (!winfo.isValid() || !winfo.isOnCurrentDesktop() || winfo.isMinimized()) return; - + if (winfo.isMaximized()) raiseDock(false); else @@ -187,7 +186,7 @@ void VisibilityManagerPrivate::dodgeWindows(WId wid) if (!winfo.isValid() || !winfo.isOnCurrentDesktop() || winfo.isMinimized()) return; - + if (intersects(winfo)) raiseDock(false); else @@ -209,11 +208,11 @@ void VisibilityManagerPrivate::checkAllWindows() } else if (std::get<1>(winfo).isMinimized()) { continue; - + } else if (mode == Dock::DodgeMaximized) { if (std::get<1>(winfo).isMaximized()) - raise = false; - + raise = false; + continue; } else if (intersects(std::get<1>(winfo))) { raise = false; @@ -246,13 +245,13 @@ inline void VisibilityManagerPrivate::saveConfig() inline void VisibilityManagerPrivate::restoreConfig() { if (!view->containment()) - return; - - auto config = view->containment()->config(); - - mode = static_cast(config.readEntry("visibility", static_cast(Dock::DodgeActive))); - timerShow.setInterval(config.readEntry("timerShow", 0)); - timerHide.setInterval(config.readEntry("timerHide", 0)); + return; + + auto config = view->containment()->config(); + + mode = static_cast(config.readEntry("visibility", static_cast(Dock::DodgeActive))); + timerShow.setInterval(config.readEntry("timerShow", 0)); + timerHide.setInterval(config.readEntry("timerHide", 0)); } bool VisibilityManagerPrivate::event(QEvent *ev) diff --git a/app/windowinfowrap.cpp b/app/windowinfowrap.cpp index 8c3a1acf8..d7fa43b88 100644 --- a/app/windowinfowrap.cpp +++ b/app/windowinfowrap.cpp @@ -1,6 +1,6 @@ #include "windowinfowrap.h" -namespace Latte { +namespace Latte { WindowInfoWrap::WindowInfoWrap() : m_isValid(false) @@ -33,97 +33,97 @@ WindowInfoWrap &WindowInfoWrap::operator=(const WindowInfoWrap &rhs) return *this; } - bool WindowInfoWrap::operator==(const WindowInfoWrap &rhs) const +bool WindowInfoWrap::operator==(const WindowInfoWrap &rhs) const { return m_wid == rhs.m_wid; } - bool WindowInfoWrap::operator<(const WindowInfoWrap &rhs) const +bool WindowInfoWrap::operator<(const WindowInfoWrap &rhs) const { return m_wid < rhs.m_wid; } - bool WindowInfoWrap::operator>(const WindowInfoWrap &rhs) const +bool WindowInfoWrap::operator>(const WindowInfoWrap &rhs) const { return m_wid > rhs.m_wid; } - bool WindowInfoWrap::isValid() const +bool WindowInfoWrap::isValid() const { return m_isValid; } - void WindowInfoWrap::setIsValid(bool isValid) +void WindowInfoWrap::setIsValid(bool isValid) { m_isValid = isValid; } - bool WindowInfoWrap::isActive() const +bool WindowInfoWrap::isActive() const { return m_isActive; } - void WindowInfoWrap::setIsActive(bool isActive) +void WindowInfoWrap::setIsActive(bool isActive) { m_isActive = isActive; } - bool WindowInfoWrap::isMinimized() const +bool WindowInfoWrap::isMinimized() const { return m_isMinimized; } - void WindowInfoWrap::setIsMinimized(bool isMinimized) +void WindowInfoWrap::setIsMinimized(bool isMinimized) { m_isMinimized = isMinimized; } - bool WindowInfoWrap::isMaximized() const +bool WindowInfoWrap::isMaximized() const { return m_isMaximized; } - void WindowInfoWrap::setIsMaximized(bool isMaximized) +void WindowInfoWrap::setIsMaximized(bool isMaximized) { m_isMaximized = isMaximized; } - bool WindowInfoWrap::isFullscreen() const +bool WindowInfoWrap::isFullscreen() const { return m_isFullscreen; } - void WindowInfoWrap::setIsFullscreen(bool isFullscreen) +void WindowInfoWrap::setIsFullscreen(bool isFullscreen) { m_isFullscreen = isFullscreen; } - bool WindowInfoWrap::isOnCurrentDesktop() const +bool WindowInfoWrap::isOnCurrentDesktop() const { return m_isOnCurrentDesktop; } - void WindowInfoWrap::setIsOnCurrentDesktop(bool isOnCurrentDesktop) +void WindowInfoWrap::setIsOnCurrentDesktop(bool isOnCurrentDesktop) { m_isOnCurrentDesktop = isOnCurrentDesktop; } - QRect WindowInfoWrap::geometry() const +QRect WindowInfoWrap::geometry() const { return m_geometry; } - void WindowInfoWrap::setGeometry(const QRect &geometry) +void WindowInfoWrap::setGeometry(const QRect &geometry) { m_geometry = geometry; } - WId WindowInfoWrap::wid() const +WId WindowInfoWrap::wid() const { return m_wid; } - void WindowInfoWrap::setWid(WId wid) +void WindowInfoWrap::setWid(WId wid) { m_wid = wid; } From 4c10939484d61b34649465c0a15c4ac172ede9b5 Mon Sep 17 00:00:00 2001 From: Johan Smith Agudelo Rodriguez Date: Fri, 30 Dec 2016 02:45:38 -0500 Subject: [PATCH 39/46] if mode is DodgeMaximized, only dodge active window --- app/visibilitymanager.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/visibilitymanager.cpp b/app/visibilitymanager.cpp index fb530e3f8..d106b9416 100644 --- a/app/visibilitymanager.cpp +++ b/app/visibilitymanager.cpp @@ -21,6 +21,8 @@ VisibilityManagerPrivate::VisibilityManagerPrivate(PlasmaQuick::ContainmentView connect(&timerCheckWindows, &QTimer::timeout, this, &VisibilityManagerPrivate::checkAllWindows); connect(&timerShow, &QTimer::timeout, q, &VisibilityManager::mustBeShown); connect(&timerHide, &QTimer::timeout, q, &VisibilityManager::mustBeHide); + + wm->setDockDefaultFlags(); } VisibilityManagerPrivate::~VisibilityManagerPrivate() @@ -169,15 +171,15 @@ void VisibilityManagerPrivate::dodgeActive(WId wid) void VisibilityManagerPrivate::dodgeMaximized(WId wid) { + if (wid != wm->activeWindow()) + return; + auto winfo = wm->requestInfo(wid); if (!winfo.isValid() || !winfo.isOnCurrentDesktop() || winfo.isMinimized()) return; - if (winfo.isMaximized()) - raiseDock(false); - else - timerCheckWindows.start(); + raiseDock(winfo.isMaximized()); } void VisibilityManagerPrivate::dodgeWindows(WId wid) @@ -209,11 +211,6 @@ void VisibilityManagerPrivate::checkAllWindows() } else if (std::get<1>(winfo).isMinimized()) { continue; - } else if (mode == Dock::DodgeMaximized) { - if (std::get<1>(winfo).isMaximized()) - raise = false; - - continue; } else if (intersects(std::get<1>(winfo))) { raise = false; break; @@ -269,6 +266,9 @@ bool VisibilityManagerPrivate::event(QEvent *ev) if (mode == Dock::AutoHide) raiseDock(false); + + } else if (ev->type() == QEvent::Show) { + wm->setDockDefaultFlags(); } return QObject::event(ev); From df08a92d0e095d3e3a59548d9fb7d889d5e11bd6 Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Fri, 30 Dec 2016 13:46:56 +0200 Subject: [PATCH 40/46] support new visibilitymanager in ui -- small fixes in visibilitymanager and removed some whitespaces also --- app/nowdockview.cpp | 14 +--- app/nowdockview.h | 1 + app/visibilitymanager.cpp | 67 +++++++++++-------- app/visibilitymanager.h | 5 +- containment/contents/ui/VisibilityManager.qml | 65 +++++++----------- containment/contents/ui/main.qml | 43 ++++++------ .../LatteDockConfiguration.qml.cmake | 6 ++ 7 files changed, 100 insertions(+), 101 deletions(-) diff --git a/app/nowdockview.cpp b/app/nowdockview.cpp index 363766079..026ece423 100644 --- a/app/nowdockview.cpp +++ b/app/nowdockview.cpp @@ -475,19 +475,7 @@ VisibilityManager *NowDockView::visibility() bool NowDockView::event(QEvent *e) { - - /* if (ev->type() == QEvent::Enter) { - m_visibility->show(); - emit entered(); - } else if (ev->type() == QEvent::Leave) { - m_visibility->restore(); - emit exited(); - } */ - - //return QQuickWindow::event(e); - if (m_visibility) { - m_visibility->event(e); - } + emit eventTriggered(e); return ContainmentView::event(e); } diff --git a/app/nowdockview.h b/app/nowdockview.h index 77cde3296..7e54c84cb 100644 --- a/app/nowdockview.h +++ b/app/nowdockview.h @@ -124,6 +124,7 @@ protected: signals: // void visibilityChanged(); void addInternalViewSplitter(); + void eventTriggered(QEvent *ev); void alignmentChanged(); void compositingChanged(); void heightChanged(); diff --git a/app/visibilitymanager.cpp b/app/visibilitymanager.cpp index d106b9416..d91df9082 100644 --- a/app/visibilitymanager.cpp +++ b/app/visibilitymanager.cpp @@ -4,12 +4,20 @@ #include "../liblattedock/extras.h" +#include "nowdockview.h" + namespace Latte { //! BEGIN: VisiblityManagerPrivate implementation VisibilityManagerPrivate::VisibilityManagerPrivate(PlasmaQuick::ContainmentView *view, VisibilityManager *q) : QObject(view), q(q), view(view), wm(AbstractWindowInterface::getInstance(view, nullptr)) { + NowDockView *dockView = dynamic_cast(view); + + if (dockView) { + connect(dockView, &NowDockView::eventTriggered, q, &VisibilityManager::eventReceived); + } + timerCheckWindows.setInterval(350); timerCheckWindows.setSingleShot(true); @@ -34,11 +42,11 @@ inline void VisibilityManagerPrivate::setMode(Dock::Visibility mode) { if (this->mode == mode) return; - + // clear mode if (this->mode == Dock::AlwaysVisible) wm->removeDockStruts(); - + for (auto &c : connections) { disconnect(c); } @@ -60,31 +68,31 @@ inline void VisibilityManagerPrivate::setMode(Dock::Visibility mode) raiseDock(true); } break; - + case Dock::DodgeActive: { connections[0] = connect(wm.get(), &AbstractWindowInterface::activeWindowChanged , this, &VisibilityManagerPrivate::dodgeActive); connections[1] = connect(wm.get(), &AbstractWindowInterface::windowChanged , this, &VisibilityManagerPrivate::dodgeActive); - + dodgeActive(wm->activeWindow()); } break; - + case Dock::DodgeMaximized: { connections[0] = connect(wm.get(), &AbstractWindowInterface::windowChanged , this, &VisibilityManagerPrivate::dodgeMaximized); } break; - + case Dock::DodgeAllWindows: { for (const auto &wid : wm->windows()) { windows.insert({wid, wm->requestInfo(wid)}); } - + connections[0] = connect(wm.get(), &AbstractWindowInterface::windowChanged , this, &VisibilityManagerPrivate::dodgeWindows); - + connections[1] = connect(wm.get(), &AbstractWindowInterface::windowRemoved , this, [&](WId wid) { windows.erase(wid); @@ -99,13 +107,15 @@ inline void VisibilityManagerPrivate::setMode(Dock::Visibility mode) } saveConfig(); + + emit q->modeChanged(); } inline void VisibilityManagerPrivate::setIsHidden(bool isHidden) { if (this->isHidden == isHidden) return; - + this->isHidden = isHidden; emit q->isHiddenChanged(); } @@ -130,15 +140,18 @@ inline void VisibilityManagerPrivate::raiseDock(bool raise) /* if (!isHidden == raise) { return; } */ - + if (raise) { timerHide.stop(); - if (!timerShow.isActive()) + if (!timerShow.isActive() && mode != Dock::AutoHide) { timerShow.start(); + } else { + emit q->mustBeShown(); + } } else { timerShow.stop(); - + if (!timerHide.isActive()) timerHide.start(); } @@ -148,7 +161,7 @@ inline void VisibilityManagerPrivate::setDockRect(const QRect &dockRect) { if (!view->containment() || this->dockRect == dockRect) return; - + this->dockRect = dockRect; if (mode == Dock::AlwaysVisible) { @@ -160,12 +173,12 @@ void VisibilityManagerPrivate::dodgeActive(WId wid) { if (wid != wm->activeWindow()) return; - + auto winfo = wm->requestInfo(wid); if (!winfo.isValid() || !winfo.isOnCurrentDesktop() || winfo.isMinimized()) return; - + raiseDock(intersects(winfo)); } @@ -173,12 +186,12 @@ void VisibilityManagerPrivate::dodgeMaximized(WId wid) { if (wid != wm->activeWindow()) return; - + auto winfo = wm->requestInfo(wid); if (!winfo.isValid() || !winfo.isOnCurrentDesktop() || winfo.isMinimized()) return; - + raiseDock(winfo.isMaximized()); } @@ -188,7 +201,7 @@ void VisibilityManagerPrivate::dodgeWindows(WId wid) if (!winfo.isValid() || !winfo.isOnCurrentDesktop() || winfo.isMinimized()) return; - + if (intersects(winfo)) raiseDock(false); else @@ -203,7 +216,7 @@ void VisibilityManagerPrivate::checkAllWindows() //! std::pair if (!std::get<1>(winfo).isValid() || !std::get<1>(winfo).isOnCurrentDesktop()) continue; - + if (std::get<1>(winfo).isFullscreen()) { raise = false; break; @@ -229,7 +242,7 @@ inline void VisibilityManagerPrivate::saveConfig() { if (!view->containment()) return; - + auto config = view->containment()->config(); config.writeEntry("visibility", static_cast(mode)); @@ -243,7 +256,7 @@ inline void VisibilityManagerPrivate::restoreConfig() { if (!view->containment()) return; - + auto config = view->containment()->config(); mode = static_cast(config.readEntry("visibility", static_cast(Dock::DodgeActive))); @@ -259,14 +272,14 @@ bool VisibilityManagerPrivate::event(QEvent *ev) if (mode == Dock::AutoHide) raiseDock(true); - + } else if (ev->type() == QEvent::Leave && containsMouse) { containsMouse = false; emit q->containsMouseChanged(); if (mode == Dock::AutoHide) raiseDock(false); - + } else if (ev->type() == QEvent::Show) { wm->setDockDefaultFlags(); } @@ -338,13 +351,13 @@ void VisibilityManager::updateDockGeometry(const QRect &geometry) d->setDockRect(geometry); } +void VisibilityManager::eventReceived(QEvent *ev) +{ + d->event(ev); +} //! END: VisibilityManager implementation } #include "abstractwindowinterface.h" #include "xwindowinterface.h" #include "plasmaquick/containmentview.h" - - - - diff --git a/app/visibilitymanager.h b/app/visibilitymanager.h index 1dc9f8357..97cd64046 100644 --- a/app/visibilitymanager.h +++ b/app/visibilitymanager.h @@ -44,7 +44,10 @@ public: * @brief updateDockGeometry, the window geometry in absolute coordinates. */ void updateDockGeometry(const QRect &geometry); - + +public Q_SLOTS: + void eventReceived(QEvent *); + signals: void mustBeShown(); void mustBeHide(); diff --git a/containment/contents/ui/VisibilityManager.qml b/containment/contents/ui/VisibilityManager.qml index d98680d9c..5625812ed 100644 --- a/containment/contents/ui/VisibilityManager.qml +++ b/containment/contents/ui/VisibilityManager.qml @@ -36,15 +36,6 @@ Item{ property int thicknessNormalOriginalValue: statesLineSizeOriginal + plasmoid.configuration.iconSize + iconMarginOriginal + 1 property int thicknessZoomOriginal: statesLineSizeOriginal + ((plasmoid.configuration.iconSize+iconMarginOriginal) * root.zoomFactor) + 2 - - Binding{ - //this is way to avoid warnings for null during initialization phase - target: dock ? dock.visibility : manager - property:"panelVisibility" - when: dock && dock.visibility - value: plasmoid.configuration.panelVisibility - } - Binding{ target: dock ? dock : manager property:"maxThickness" @@ -71,22 +62,22 @@ Item{ onThicknessZoomOriginalChanged: updateMaskArea(); function slotDisableHidingChanged() { - if (!dock.visibility.disableHiding) { + /*if (!dock.visibility.disableHiding) { checkListHovered.restart(); - } + }*/ } - function slotIsHoveredChanged() { - if(dock.visibility.isHovered) { + function slotContainsMouseChanged() { + if(dock.visibility.containsMouse) { //stop parent window timer for auto hiding - if ((dock.visibility.panelVisibility === Latte.Dock.AutoHide)|| dock.visibility.isDockWindowType) { + /* if (dock.visibility.mode === Latte.Dock.AutoHide) { if(hideMagicWindowInAutoHide.forcedDisableHiding) { hideMagicWindowInAutoHide.forcedDisableHiding = false; dock.visibility.disableHiding = false; } hideMagicWindowInAutoHide.stop(); - } + }*/ if (delayerTimer.running) { delayerTimer.stop(); @@ -99,29 +90,23 @@ Item{ } } - function slotMustBeRaised() { - if ((dock.visibility.panelVisibility === Latte.Dock.AutoHide) || dock.visibility.isDockWindowType) { - slidingAnimationAutoHiddenIn.init(); - } else { - slidingAnimation.init(true,false); - } + function slotMustBeShown() { + console.log("show..."); + slidingAnimationAutoHiddenIn.init(); } function slotMustBeRaisedImmediately() { slidingAnimation.init(true,true); } - function slotMustBeLowered() { - if ((dock.visibility.panelVisibility === Latte.Dock.AutoHide) || dock.visibility.isDockWindowType ) { - slidingAnimationAutoHiddenOut.init(); - } else { - slidingAnimation.init(false,false); - } + function slotMustBeHide() { + console.log("hide...."); + slidingAnimationAutoHiddenOut.init(); } - function slotPanelVisibilityChanged() { - if (dock.visibility.panelVisibility !== Latte.Dock.AutoHide) { - dock.visibility.isAutoHidden = false; + function slotModeChanged() { + if (dock.visibility.mode !== Latte.Dock.AutoHide) { + dock.visibility.isHidden = false; } } @@ -164,7 +149,7 @@ Item{ tempThickness = thicknessMidOriginal; } - if (dock.visibility.isAutoHidden && ((dock.visibility.panelVisibility === Latte.Dock.AutoHide) || dock.visibility.isDockWindowType)) { + if (dock.visibility.isHidden && (dock.visibility.mode === Latte.Dock.AutoHide)) { tempThickness = thicknessAutoHidden; } @@ -358,7 +343,7 @@ Item{ } onStopped: { - dock.visibility.isAutoHidden = true; + dock.visibility.isHidden = true; updateMaskArea(); } @@ -385,7 +370,7 @@ Item{ } function init() { - dock.visibility.isAutoHidden = false; + dock.visibility.isHidden = false; updateMaskArea(); start(); } @@ -396,12 +381,12 @@ Item{ onCurrentActivityChanged: { dock.visibility.disableHiding = true; - if (dock.visibility.isAutoHidden) { - dock.visibility.mustBeRaised(); + if (dock.visibility.isHidden) { + dock.visibility.mustBeShown(); } - hideMagicWindowInAutoHide.forcedDisableHiding = true; - hideMagicWindowInAutoHide.start(); + // hideMagicWindowInAutoHide.forcedDisableHiding = true; + // hideMagicWindowInAutoHide.start(); } } @@ -424,9 +409,9 @@ Item{ interval: manager.inStartup ? 1000 : 500 onTriggered: { layoutsContainer.opacity = 1; - if ((dock.visibility.panelVisibility !== Latte.Dock.AutoHide) && !dock.visibility.isDockWindowType) { - slidingAnimation.init(true,false); - } else { + if (dock.visibility.mode !== Latte.Dock.AutoHide) { + /*slidingAnimation.init(true,false); + } else {*/ slidingAnimationAutoHiddenIn.init(); } } diff --git a/containment/contents/ui/main.qml b/containment/contents/ui/main.qml index b914d2cfc..635b80e9a 100644 --- a/containment/contents/ui/main.qml +++ b/containment/contents/ui/main.qml @@ -398,12 +398,15 @@ DragDrop.DropArea { dock.onWidthChanged.connect(visibilityManager.updateMaskArea); dock.onHeightChanged.connect(visibilityManager.updateMaskArea); - dock.visibility.onDisableHidingChanged.connect(visibilityManager.slotDisableHidingChanged); - dock.visibility.onIsHoveredChanged.connect(visibilityManager.slotIsHoveredChanged); - dock.visibility.onMustBeLowered.connect(visibilityManager.slotMustBeLowered); - dock.visibility.onMustBeRaised.connect(visibilityManager.slotMustBeRaised); - dock.visibility.onMustBeRaisedImmediately.connect(visibilityManager.slotMustBeRaisedImmediately); - dock.visibility.onPanelVisibilityChanged.connect(visibilityManager.slotPanelVisibilityChanged); + dock.visibility.timerShow = 1000; + dock.visibility.timerHide = 1000; + + //dock.visibility.onDisableHidingChanged.connect(visibilityManager.slotDisableHidingChanged); + dock.visibility.onContainsMouseChanged.connect(visibilityManager.slotContainsMouseChanged); + dock.visibility.onMustBeHide.connect(visibilityManager.slotMustBeHide); + dock.visibility.onMustBeShown.connect(visibilityManager.slotMustBeShown); + //dock.visibility.onMustBeRaisedImmediately.connect(visibilityManager.slotMustBeRaisedImmediately); + dock.visibility.onModeChanged.connect(visibilityManager.slotModeChanged); } } @@ -439,9 +442,9 @@ DragDrop.DropArea { } onIsHoveredChanged: { - if (isHovered){ + /*if (isHovered){ dock.visibility.showOnTopCheck(); - } + }*/ } onHeightChanged: { @@ -584,16 +587,16 @@ DragDrop.DropArea { } } - if (plasmoid.immutable) { + /* if (plasmoid.immutable) { if (windowSystem.compositingActive) { - // magicWin.initialize(); + magicWin.initialize(); } dock.visibility.disableHiding = false; } else { dock.visibility.disableHiding = true; dock.visibility.mustBeRaised(); - } + }*/ visibilityManager.updateMaskArea(); @@ -749,7 +752,7 @@ DragDrop.DropArea { animatedLengthTimer.start(); } - if (!dock.visibility.isHovered && (root.animationsNeedBothAxis === 0) + if (!dock.visibility.containsMouse && (root.animationsNeedBothAxis === 0) && (root.animationsNeedLength===0) && (root.appletsAnimations === 0)) { mainLayout.animatedLength = true; } else { @@ -761,9 +764,9 @@ DragDrop.DropArea { function clearZoom(){ //console.log("Panel clear...."); - if (dock.visibility.disableHiding) { + /* if (dock.visibility.disableHiding) { return; - } + } */ layoutsContainer.currentSpot = -1000; layoutsContainer.hoveredIndex = -1; @@ -871,7 +874,7 @@ DragDrop.DropArea { } function slotDisableHiding(value) { - dock.visibility.disableHiding = value; + // dock.visibility.disableHiding = value; } function updateAutomaticIconSize() { @@ -1251,17 +1254,17 @@ DragDrop.DropArea { property bool forcedDisableHiding: false onTriggered: { - if (forcedDisableHiding) { + /* if (forcedDisableHiding) { forcedDisableHiding = false; dock.visibility.disableHiding = false; } var visibility = dock.visibility; - if (plasmoid.immutable && !visibility.isHovered //&& !wholeArea.containsMouse - && ((visibility.panelVisibility === Latte.Dock.AutoHide) || visibility.isDockWindowType) ) { - visibility.mustBeLowered(); - } + if (plasmoid.immutable && !visibility.containsMouse //&& !wholeArea.containsMouse + && (visibility.movde === Latte.Dock.AutoHide) ) { + visibility.mustBeHide(); + }*/ } } diff --git a/shell/contents/configuration/LatteDockConfiguration.qml.cmake b/shell/contents/configuration/LatteDockConfiguration.qml.cmake index b85e9dcd8..f18adb01b 100644 --- a/shell/contents/configuration/LatteDockConfiguration.qml.cmake +++ b/shell/contents/configuration/LatteDockConfiguration.qml.cmake @@ -375,6 +375,7 @@ PlasmaCore.FrameSvgItem { onCheckedChanged: { if(checked && !parent.inStartup){ + dock.visibility.mode = Latte.Dock.AlwaysVisible plasmoid.configuration.panelVisibility = 0 } } @@ -388,6 +389,7 @@ PlasmaCore.FrameSvgItem { onCheckedChanged: { if(checked && !parent.inStartup){ + dock.visibility.mode = Latte.Dock.AutoHide plasmoid.configuration.panelVisibility = 1 } } @@ -401,6 +403,7 @@ PlasmaCore.FrameSvgItem { onCheckedChanged: { if(checked && !parent.inStartup){ + dock.visibility.mode = Latte.Dock.DodgeActive plasmoid.configuration.panelVisibility = 2 } } @@ -415,6 +418,7 @@ PlasmaCore.FrameSvgItem { onCheckedChanged: { if(checked && !parent.inStartup){ + dock.visibility.mode = Latte.Dock.DodgeMaximized plasmoid.configuration.panelVisibility = 3 } } @@ -429,6 +433,7 @@ PlasmaCore.FrameSvgItem { onCheckedChanged: { if(checked && !parent.inStartup){ + dock.visibility.mode = Latte.Dock.DodgeWindows plasmoid.configuration.panelVisibility = 4 } } @@ -442,6 +447,7 @@ PlasmaCore.FrameSvgItem { onCheckedChanged: { if(checked && !parent.inStartup){ + dock.visibility.mode = Latte.Dock.AlwaysVisible plasmoid.configuration.panelVisibility = 5 } } From 02a0aa8de4db55520656eaaa34cac5893a002779 Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Fri, 30 Dec 2016 13:58:31 +0200 Subject: [PATCH 41/46] disable hiding on !immutable --- app/visibilitymanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/visibilitymanager.cpp b/app/visibilitymanager.cpp index d91df9082..4a0f9b992 100644 --- a/app/visibilitymanager.cpp +++ b/app/visibilitymanager.cpp @@ -152,7 +152,7 @@ inline void VisibilityManagerPrivate::raiseDock(bool raise) } else { timerShow.stop(); - if (!timerHide.isActive()) + if (!timerHide.isActive() && view->containment()->immutability() != Plasma::Types::Mutable) timerHide.start(); } } From 9cd16c5cda30a00fc7f7ff1b56a77d64951ae2a0 Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Fri, 30 Dec 2016 16:51:44 +0200 Subject: [PATCH 42/46] fix #16, systemtray working ok --calculate freeedges even when screen=-1 is passed, such a case is on the creation of a containment --- app/nowdockcorona.cpp | 29 +++++++++++++++++++++++++---- app/nowdockcorona.h | 1 + 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/app/nowdockcorona.cpp b/app/nowdockcorona.cpp index 4326a871d..89a88c7ac 100644 --- a/app/nowdockcorona.cpp +++ b/app/nowdockcorona.cpp @@ -121,14 +121,35 @@ QRect NowDockCorona::availableScreenRect(int id) const return qGuiApp->primaryScreen()->availableGeometry(); } +int NowDockCorona::primaryScreenId() const +{ + const auto screens = qGuiApp->screens(); + + int id = -1; + + for (int i = 0; i < screens.size(); ++i) { + auto *scr = screens.at(i); + + if (scr == qGuiApp->primaryScreen()) { + id = i; + break; + } + } + + return id; +} + QList NowDockCorona::freeEdges(int screen) const { using Plasma::Types; QList edges{Types::BottomEdge, Types::LeftEdge, Types::TopEdge, Types::RightEdge}; - + + //when screen=-1 is passed then the primaryScreenid is used + int fixedScreen = (screen == -1) ? primaryScreenId() : screen; + for (const NowDockView *cont : m_containments) { - if (cont && cont->containment()->screen() == screen) + if (cont && cont->containment()->screen() == fixedScreen) edges.removeOne(cont->location()); } @@ -156,8 +177,8 @@ void NowDockCorona::addDock(Plasma::Containment *containment) // the system tray is a containment that behaves as an applet // so a dockview shouldnt be created for it KPluginMetaData metadata = containment->kPackage().metadata(); - - if (metadata.pluginId() == "org.kde.plasma.systemtray") { + + if (metadata.pluginId() == "org.kde.plasma.private.systemtray") { return; } diff --git a/app/nowdockcorona.h b/app/nowdockcorona.h index 2888f8b59..f9ad89c2c 100644 --- a/app/nowdockcorona.h +++ b/app/nowdockcorona.h @@ -61,6 +61,7 @@ signals: private: void qmlRegisterTypes() const; + int primaryScreenId() const; std::vector m_containments; }; From f204cb3666d7a089a01d3a71840bc799403aab0e Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Fri, 30 Dec 2016 19:25:52 +0200 Subject: [PATCH 43/46] fix some blocking animation behavior from applets --- containment/contents/ui/AppletItem.qml | 33 +++++++++++++------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/containment/contents/ui/AppletItem.qml b/containment/contents/ui/AppletItem.qml index fab53d195..49c3439ae 100644 --- a/containment/contents/ui/AppletItem.qml +++ b/containment/contents/ui/AppletItem.qml @@ -758,30 +758,31 @@ Item { } onPositionChanged: { - if(!pressed){ - if (root.isHorizontal){ - var step = Math.abs(layoutsContainer.currentSpot-mouse.x); - if (step >= container.animationStep){ - layoutsContainer.hoveredIndex = index; - layoutsContainer.currentSpot = mouse.x; - - wrapper.calculateScales(mouse.x); - } + // if(!pressed){ + if (root.isHorizontal){ + var step = Math.abs(layoutsContainer.currentSpot-mouse.x); + if (step >= container.animationStep){ + layoutsContainer.hoveredIndex = index; + layoutsContainer.currentSpot = mouse.x; + + wrapper.calculateScales(mouse.x); } - else{ - var step = Math.abs(layoutsContainer.currentSpot-mouse.y); - if (step >= container.animationStep){ - layoutsContainer.hoveredIndex = index; - layoutsContainer.currentSpot = mouse.y; + } + else{ + var step = Math.abs(layoutsContainer.currentSpot-mouse.y); + if (step >= container.animationStep){ + layoutsContainer.hoveredIndex = index; + layoutsContainer.currentSpot = mouse.y; - wrapper.calculateScales(mouse.y); - } + wrapper.calculateScales(mouse.y); } } + // } mouse.accepted = false; } onPressed: pressed = true; + onReleased: pressed = false; } //BEGIN states From dfbfbd13c99270d29bff9f04ef1a3232760b4cee Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Fri, 30 Dec 2016 19:48:42 +0200 Subject: [PATCH 44/46] fix, some tasks didnt return to scale:1 after zoom --- containment/contents/ui/AppletItem.qml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/containment/contents/ui/AppletItem.qml b/containment/contents/ui/AppletItem.qml index 49c3439ae..55fa6219e 100644 --- a/containment/contents/ui/AppletItem.qml +++ b/containment/contents/ui/AppletItem.qml @@ -665,10 +665,13 @@ Item { zoomScale = zoomScale + step; } else{ - if(layoutsContainer.hoveredIndex=container.index) + nowDock.updateScale(1, 1, 0); + } else if(layoutsContainer.hoveredIndex>=container.index) { nowDock.updateScale(root.tasksCount-1, nScale, step); + nowDock.updateScale(root.tasksCount-2, 1, 0); + } } } ///if the applet is hidden must forward its scale events to its neighbours else if ((applet && (applet.status === PlasmaCore.Types.HiddenStatus)) From 7af3b6e62060ad7f6daf7b1997556f2775b374b7 Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Fri, 30 Dec 2016 20:24:21 +0200 Subject: [PATCH 45/46] support DodgeActive --add localDockGeometry to be used for the intersect situation --- app/nowdockview.cpp | 21 +++++++++++++++++++ app/nowdockview.h | 5 ++++- app/visibilitymanager.cpp | 10 +++------ app/xwindowinterface.cpp | 3 +-- containment/contents/ui/VisibilityManager.qml | 4 ++++ 5 files changed, 33 insertions(+), 10 deletions(-) diff --git a/app/nowdockview.cpp b/app/nowdockview.cpp index 026ece423..5eb12e9cc 100644 --- a/app/nowdockview.cpp +++ b/app/nowdockview.cpp @@ -72,6 +72,10 @@ NowDockView::NowDockView(Plasma::Corona *corona, QScreen *targetScreen) m_lockGeometry.setSingleShot(true); m_lockGeometry.setInterval(700); + + connect(this, SIGNAL(localDockGeometryChanged()), this, SLOT(updateAbsDockGeometry())); + connect(this, SIGNAL(xChanged(int)), this, SLOT(updateAbsDockGeometry())); + connect(this, SIGNAL(yChanged(int)), this, SLOT(updateAbsDockGeometry())); connect(this, &NowDockView::containmentChanged , this, [&]() { @@ -286,6 +290,23 @@ void NowDockView::resizeWindow() } } +void NowDockView::setLocalDockGeometry(QRect geometry) +{ + if (geometry == m_localDockGeometry) { + return; + } + + m_localDockGeometry = geometry; + + emit localDockGeometryChanged(); +} + +void NowDockView::updateAbsDockGeometry() +{ + QRect absoluteGeometry = {x() + m_localDockGeometry.x(), y() + m_localDockGeometry.y(), m_localDockGeometry.width(), m_localDockGeometry.height()}; + m_visibility->updateDockGeometry(absoluteGeometry); +} + inline void NowDockView::updateDockPosition() { if (!containment()) diff --git a/app/nowdockview.h b/app/nowdockview.h index 7e54c84cb..a5c6010b2 100644 --- a/app/nowdockview.h +++ b/app/nowdockview.h @@ -109,6 +109,7 @@ public slots: Q_INVOKABLE QList freeEdges() const; Q_INVOKABLE void initialize(); Q_INVOKABLE void removeDock(); + Q_INVOKABLE void setLocalDockGeometry(QRect geometry); void resizeWindow(); void restoreConfig(); void saveConfig(); @@ -129,6 +130,7 @@ signals: void compositingChanged(); void heightChanged(); void lengthChanged(); + void localDockGeometryChanged(); void maskAreaChanged(); void maxLengthChanged(); void maxThicknessChanged(); @@ -139,6 +141,7 @@ signals: public Q_SLOTS: void updateDockPositionSlot(); + void updateAbsDockGeometry(); private: bool m_secondInitPass; @@ -148,7 +151,7 @@ private: int m_length{0}; int m_maxLength{INT_MAX}; - QRect m_dockGeometry; + QRect m_localDockGeometry; QRect m_maskArea; QPointer m_configView; diff --git a/app/visibilitymanager.cpp b/app/visibilitymanager.cpp index 4a0f9b992..9a7065037 100644 --- a/app/visibilitymanager.cpp +++ b/app/visibilitymanager.cpp @@ -144,10 +144,8 @@ inline void VisibilityManagerPrivate::raiseDock(bool raise) if (raise) { timerHide.stop(); - if (!timerShow.isActive() && mode != Dock::AutoHide) { + if (!timerShow.isActive()) { timerShow.start(); - } else { - emit q->mustBeShown(); } } else { timerShow.stop(); @@ -179,7 +177,7 @@ void VisibilityManagerPrivate::dodgeActive(WId wid) if (!winfo.isValid() || !winfo.isOnCurrentDesktop() || winfo.isMinimized()) return; - raiseDock(intersects(winfo)); + raiseDock(!intersects(winfo)); } void VisibilityManagerPrivate::dodgeMaximized(WId wid) @@ -270,9 +268,7 @@ bool VisibilityManagerPrivate::event(QEvent *ev) containsMouse = true; emit q->containsMouseChanged(); - if (mode == Dock::AutoHide) - raiseDock(true); - + emit q->mustBeShown(); } else if (ev->type() == QEvent::Leave && containsMouse) { containsMouse = false; emit q->containsMouseChanged(); diff --git a/app/xwindowinterface.cpp b/app/xwindowinterface.cpp index 3ad11b39c..b25b7c7d4 100644 --- a/app/xwindowinterface.cpp +++ b/app/xwindowinterface.cpp @@ -122,7 +122,7 @@ WindowInfoWrap XWindowInterface::requestInfoActive() WindowInfoWrap XWindowInterface::requestInfo(WId wid) { - const KWindowInfo winfo{wid, NET::WMDesktop | NET::WMFrameExtents | NET::WMWindowType | NET::WMState}; + const KWindowInfo winfo{wid, NET::WMDesktop | NET::WMFrameExtents | NET::WMWindowType | NET::WMGeometry | NET::WMState}; WindowInfoWrap winfoWrap; @@ -172,4 +172,3 @@ void XWindowInterface::windowChangedProxy(WId wid, NET::Properties prop1, NET::P } } - diff --git a/containment/contents/ui/VisibilityManager.qml b/containment/contents/ui/VisibilityManager.qml index 5625812ed..7ccb99a67 100644 --- a/containment/contents/ui/VisibilityManager.qml +++ b/containment/contents/ui/VisibilityManager.qml @@ -241,6 +241,10 @@ Item{ } dock.maskArea = newMaskArea; + + if(normalState && !dock.visibility.isHidden){ + dock.setLocalDockGeometry(newMaskArea); + } } } From 4bc7a45474c446ed2a5f0ea58de3b50b1308cf1e Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Fri, 30 Dec 2016 20:49:48 +0200 Subject: [PATCH 46/46] restore previous functionality for QEvent:Leave --- app/visibilitymanager.cpp | 7 +++---- containment/contents/ui/main.qml | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/visibilitymanager.cpp b/app/visibilitymanager.cpp index 9a7065037..ab3726655 100644 --- a/app/visibilitymanager.cpp +++ b/app/visibilitymanager.cpp @@ -63,7 +63,7 @@ inline void VisibilityManagerPrivate::setMode(Dock::Visibility mode) raiseDock(true); } break; - + case Dock::AutoHide: { raiseDock(true); } @@ -268,14 +268,13 @@ bool VisibilityManagerPrivate::event(QEvent *ev) containsMouse = true; emit q->containsMouseChanged(); - emit q->mustBeShown(); + raiseDock(true); } else if (ev->type() == QEvent::Leave && containsMouse) { containsMouse = false; emit q->containsMouseChanged(); - + if (mode == Dock::AutoHide) raiseDock(false); - } else if (ev->type() == QEvent::Show) { wm->setDockDefaultFlags(); } diff --git a/containment/contents/ui/main.qml b/containment/contents/ui/main.qml index 635b80e9a..443e179ab 100644 --- a/containment/contents/ui/main.qml +++ b/containment/contents/ui/main.qml @@ -398,7 +398,7 @@ DragDrop.DropArea { dock.onWidthChanged.connect(visibilityManager.updateMaskArea); dock.onHeightChanged.connect(visibilityManager.updateMaskArea); - dock.visibility.timerShow = 1000; + dock.visibility.timerShow = 300; dock.visibility.timerHide = 1000; //dock.visibility.onDisableHidingChanged.connect(visibilityManager.slotDisableHidingChanged);