diff --git a/Documentation/Software/KWin/Reflection.md b/Documentation/Software/KWin/Reflection.md index 180966a..7834cc1 100755 --- a/Documentation/Software/KWin/Reflection.md +++ b/Documentation/Software/KWin/Reflection.md @@ -86,7 +86,7 @@ This only applies to regular windows (most windows with server-side decorations) ## Configuration menu -The accent color can be edited in real time through the configuration menu. Internally, the color is stored in the RGB color model as that's what OpenGL expects during rendering. The color mixer window is designed to look and function like Windows 7's Personalization menu, and includes the accent colors found on Windows 7, which were directly pulled from the following registry key: +The accent color can be edited in real time through the configuration menu. Real time editing was made possible through the use of [QSharedMemory](https://doc.qt.io/qt-6/qsharedmemory.html) and calling the ```reconfigure()``` method through qdbus whenever a change occurs. Internally, the color is stored in the RGB color model as that's what OpenGL expects during rendering. The color mixer window is designed to look and function like Windows 7's Personalization menu, and includes the accent colors found on Windows 7, which were directly pulled from the following registry key: ```[ HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM\ColorizationColor ]``` @@ -152,4 +152,4 @@ Windows 8.1 features a slightly more pastel variety of colors compared to Window |     |#c4ffffff|

-While not very conclusive, [here](https://stackoverflow.com/questions/3560890/vista-7-how-to-get-glass-color) is a useful thread for more information on how accent colors work in Aero, focusing mainly on Windows 7. \ No newline at end of file +While not very conclusive, [here](https://stackoverflow.com/questions/3560890/vista-7-how-to-get-glass-color) is a useful thread for more information on how accent colors work in Aero, focusing mainly on Windows 7. diff --git a/Documentation/Software/Plasmoids/SevenStart.md b/Documentation/Software/Plasmoids/SevenStart.md index 720ae03..10850d4 100755 --- a/Documentation/Software/Plasmoids/SevenStart.md +++ b/Documentation/Software/Plasmoids/SevenStart.md @@ -26,6 +26,21 @@ The first notable thing about SevenStart is the use of animated icons or "orbs" In earlier versions of SevenStart, only two images were used, but now three images are used due to upstream updates causing subtle timing issues that would cause undesirable visual effects. Using three images did end up allowing SevenStart to replicate the effects of Vista and 7's Start menu more accurately. By default, SevenStart uses internal icons if no external icons are provided in the configuration window. +Users can also force the orb to have a constant size, which allows the orb to stick out of the panel if the panel's height is lower than the orb's height. This allows the user to have a small panel with the orb protruding out of the panel, much like Windows 7 and Vista. The implementation is very similar to the user icon sticking out of the menu, which is described in more detail below. This implementation introduces a couple of problems: + +1. Right clicking on this dialog window won't open the standard context menu as expected, as it actually isn't part of the compact or full representation. +2. When compositing is disabled, even with the NoBackground hint, this dialog window will simply be drawn with an opaque, black background. + +The first problem is solved by implementing a separate context menu that pulls the appropriate actions from [ContainmentInterface](https://api.kde.org/frameworks/plasma-framework/html/classContainmentInterface.html) and [AppletInterface](https://api.kde.org/frameworks/plasma-framework/html/classAppletInterface.html), which is actually the ```plasmoid``` object. + +Potential solutions to the second problem are far less trivial, as all of them require some sort of compromise. The potential solutions are: + +1. Reverting to the regular orb while compositing is disabled, which is embedded within the panel, and/or resizing the orb back to its unaltered scale. This solution is aesthetically not pleasing at all, and it pretty much defeats the purpose of even enabling this feature to begin with. +2. Adding a compiled component to this plasmoid, which would expose more Qt and KDE API methods that can define an opacity mask around the orb. The downside to this solution is that a compiled component reduces portability and makes the installation process slightly more complicated. To see how such an implementation would work however, see this [link](https://github.com/ryanmcalister/donutwindow). +3. Applying an opacity mask through an already existing SVG file which can be applied to the dialog window. The downside to this solution is that it feels pretty much like a hack/workaround, and because it uses the provided frameworks in an unintended way. + +This implementation goes for the third solution, which takes advantage of the solid appearance variant found in Plasma themes. The dialog window loads in a completely transparent tooltip SVG that has a customized opacity mask that is created based on the orb texture. This does mean that if the user wants to have a different kind of orb texture that's not spherical in shape, they would also need to provide a correct SVG that represents the opacity mask of the orb. See the source code for more implementation details. + Another notable thing about the compact representation is that it is used in an unusual way compared to how plasmoids are generally designed to behave. Plasmoids have two representations: 1. Compact representation, which is used when the plasmoid is in a panel. @@ -88,3 +103,6 @@ Files: |OftenUsedView.qml|Used to display recently opened programs.| |SidePanelItemDelegate.qml|Displays and holds information about the sidebar menu entries.| |ApplicationsView.qml|Used to display all applications installed on the system.| +|StartOrb.qml|Dialog window representing the orb that is used for the small taskbar layout.| +|FloatingOrb.qml|The actual orb button that handles the visual animations and functionality.| +|ContextMenu.qml|Reimplemented context menu for StartOrb to bypass Dialog limitations.| diff --git a/Documentation/Themes/Seven-Black.md b/Documentation/Themes/Seven-Black.md index 8652738..ae4b6bf 100755 --- a/Documentation/Themes/Seven-Black.md +++ b/Documentation/Themes/Seven-Black.md @@ -34,6 +34,8 @@ Regular textures are used for all other windows (plasmoids, OSD popups, task swi The opaque appearance state aims to be a recreation of Aero Basic (WIP). Currently, only plasmoids using solid textures and the window manager don't comply with the aesthetic, but everything else does. A potential solution is to detect a change in compositing in plasmoids that use solid textures, change the dialog type to ```NoBackground``` and display a custom texture as the background while compositing is disabled. A similar solution can also be applied to the window manager. +Another important note is that the tooltip SVG used in the solid appearance is now used as a workaround to allow orb transparency in SevenStart. For more information, go to [SevenStart](../Software/Plasmoids/SevenStart.md)'s documentation. + ### Icons This theme also features a small set of icons used mainly by plasmoids like the system tray. Most of these icons are simply just scaled down variants of icons taken from Breeze, while other icons are taken directly from the main icon theme of this project. @@ -54,7 +56,7 @@ The "Unique" column describes if the file itself is exclusive to Seven-Black. |panel-background.svg |widgets/ |Default taskbar texture. |Y |Y |N | |tooltip.svg |widgets/ |Default tooltip texture. |Y |Y |N | |button-close.svg |widgets/ |Close button icon used in SevenTasks. |N |N |Y | -|menuitem.svg |widgets/ |Texture used for menu items in SevenStart and SevenTasks|N |N |Y | +|menuitem.svg |widgets/ |Texture used for menu items in SevenStart and SevenTasks.|N |N |Y | |showdesktop.svg |widgets/ |Texture used for the Show desktop plasmoid. |N |N |Y | |sidebaritem.svg |widgets/ |Texture used for sidebar entries in SevenStart. |N |N |Y | |startmenu-buttons.svg |widgets/ |Texture used for the shut down button in SevenStart.|N |N |Y | @@ -70,6 +72,7 @@ The "Unique" column describes if the file itself is exclusive to Seven-Black. |panel-background.svg |opaque/widgets/|Used when compositing is disabled. |N |Y |N | |tooltip.svg |opaque/widgets/|Used when compositing is disabled. |N |Y |N | |background.svg |solid/dialogs/ |Used by the system tray and date and time plasmoid. |Y |Y |N | +|tooltip.svg |solid/widgets/ |Used to provide an opacity mask to SevenStart's orb. |Y |Y |N | ## Nonstandard SVGs diff --git a/INSTALL.md b/INSTALL.md index 056847b..93fd65a 100755 --- a/INSTALL.md +++ b/INSTALL.md @@ -72,7 +72,7 @@ Starting off with the simplest modifications, this is a list of recommended sett - Under KWin Scripts: - Enable 'MinimizeAll' -When editing Plasma's bottom panel, make sure its width is set to 40 pixels. +When editing Plasma's bottom panel, make sure its width is set to 40 pixels (30 if using a small panel). ### KDE Plasma Theme diff --git a/Plasma/KDE_Plasma_Theme/Seven-Black/solid/widgets/tooltip.svg b/Plasma/KDE_Plasma_Theme/Seven-Black/solid/widgets/tooltip.svg new file mode 100755 index 0000000..5b581af --- /dev/null +++ b/Plasma/KDE_Plasma_Theme/Seven-Black/solid/widgets/tooltip.svg @@ -0,0 +1,3693 @@ + +image/svg+xmlimage/svg+xml diff --git a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/config/main.xml b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/config/main.xml index 5e421f2..36334cb 100755 --- a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/config/main.xml +++ b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/config/main.xml @@ -12,6 +12,9 @@ true + + false + diff --git a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/CompactRepresentation.qml b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/CompactRepresentation.qml index c0cf0f2..2107ba3 100755 --- a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/CompactRepresentation.qml +++ b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/CompactRepresentation.qml @@ -22,10 +22,10 @@ import QtQuick.Layouts 1.1 import org.kde.plasma.plasmoid 2.0 import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.kwindowsystem 1.0 Item { id: root - readonly property var screenGeometry: plasmoid.screenGeometry readonly property bool inPanel: (plasmoid.location == PlasmaCore.Types.TopEdge || plasmoid.location == PlasmaCore.Types.RightEdge @@ -33,23 +33,28 @@ Item { || plasmoid.location == PlasmaCore.Types.LeftEdge) readonly property bool vertical: (plasmoid.formFactor == PlasmaCore.Types.Vertical) readonly property bool useCustomButtonImage: (plasmoid.configuration.useCustomButtonImage) + + // Should the orb be rendered in its own dialog window so that it can stick out of the panel? + readonly property bool stickOutOrb: plasmoid.configuration.stickOutOrb && inPanel && !editMode property QtObject dashWindow: null + property QtObject orb: null + property QtObject contextMenu: null Plasmoid.status: dashWindow && dashWindow.visible ? PlasmaCore.Types.RequiresAttentionStatus : PlasmaCore.Types.PassiveStatus onWidthChanged: updateSizeHints() onHeightChanged: updateSizeHints() - + clip: true function updateSizeHints() { if (useCustomButtonImage) { if (vertical) { - var scaledHeight = Math.floor(parent.width * (buttonIcon.implicitHeight / buttonIcon.implicitWidth)); + var scaledHeight = Math.floor(parent.width * (floatingOrbPanel.buttonIcon.implicitHeight / floatingOrbPanel.buttonIcon.implicitWidth)); root.Layout.minimumHeight = scaledHeight; root.Layout.maximumHeight = scaledHeight; root.Layout.minimumWidth = units.iconSizes.small; root.Layout.maximumWidth = inPanel ? units.iconSizeHints.panel : -1; } else { - var scaledWidth = Math.floor(parent.height * (buttonIcon.implicitWidth / buttonIcon.implicitHeight)); + var scaledWidth = Math.floor(parent.height * (floatingOrbPanel.buttonIcon.implicitWidth / floatingOrbPanel.buttonIcon.implicitHeight)); root.Layout.minimumWidth = scaledWidth; root.Layout.maximumWidth = scaledWidth; root.Layout.minimumHeight = units.iconSizes.small; @@ -61,15 +66,89 @@ Item { root.Layout.minimumHeight = units.iconSizes.small root.Layout.maximumHeight = inPanel ? units.iconSizeHints.panel : -1; } + if(stickOutOrb && orb) { + root.Layout.minimumWidth = orb.width + panelSvg.margins.right*(compositing ? 0 : 1); + root.Layout.maximumWidth = orb.width + panelSvg.margins.right*(compositing ? 0 : 1); + root.Layout.minimumHeight = orb.height; + root.Layout.maximumHeight = orb.height; + } } + onStickOutOrbChanged: { + updateSizeHints(); + positionOrb(); + } + + + /* The following code gets the ContainmentInterface instance which is used for two things: + * 1. Getting context menu actions for entering edit mode and adding plasmoids + * 2. Keeping track on when edit mode is enabled. This allows us to hide the StartOrb + * object so the user can actually highlight and select this plasmoid during edit mode. + */ + property var containmentInterface: null + readonly property bool editMode: containmentInterface ? containmentInterface.editMode : false + onParentChanged: { + if (parent) { + for (var obj = root, depth = 0; !!obj; obj = obj.parent, depth++) { + if (obj.toString().startsWith('ContainmentInterface')) { + // desktop containment / plasmoidviewer + // Note: This doesn't always work. FolderViewDropArea may not yet have + // ContainmentInterface as a parent when this loop runs. + if (typeof obj['editMode'] === 'boolean') { + root.containmentInterface = obj + break + } + } else if (obj.toString().startsWith('DeclarativeDropArea')) { + // panel containment + if (typeof obj['Plasmoid'] !== 'undefined' && obj['Plasmoid'].toString().startsWith('ContainmentInterface')) { + if (typeof obj['Plasmoid']['editMode'] === 'boolean') { + root.containmentInterface = obj.Plasmoid + break + } + } + } + } + } + } Connections { target: units.iconSizeHints function onPanelChanged() { updateSizeHints(); } } + property bool compositing: kwindowsystem.compositingActive - // If the url is empty (default value), then use the fallback url. + /* We want to change the background hint for the orb dialog window depending + * on the compositing state. In this case, 0 refers to NoBackground, while + * 2 refers to SolidBackground. + */ + onCompositingChanged: { + if(compositing) { + orb.backgroundHints = 0; + } else { + orb.backgroundHints = 2; + } + updateSizeHints(); + positionOrb(); + + // Add a little padding to the orb. + if(compositing) + orb.x += panelSvg.margins.left; + } + + function positionOrb() { + var pos = plasmoid.mapToGlobal(kicker.x, kicker.y); // Gets the global position of this plasmoid, in screen coordinates. + orb.width = floatingOrbPanel.buttonIcon.implicitWidth + panelSvg.margins.left; + orb.height = floatingOrbPanel.buttonIcon.implicitHeight; + orb.x = pos.x; + orb.y = pos.y + panelSvg.margins.bottom; + + // Keep the orb positioned exactly on the bottom if it is rendered out of bounds (beyond the screen geometry) + if(orb.y + orb.height > plasmoid.screenGeometry.height) { + orb.y -= orb.y + orb.height - plasmoid.screenGeometry.height; + } + } + // If the url is empty (default value), then use the fallback url. Otherwise, return the url path relative to + // the location of the source code. function getResolvedUrl(url, fallback) { if(url.toString() === "") { return Qt.resolvedUrl(fallback); @@ -78,6 +157,12 @@ Item { } property int opacityDuration: 250 + function createContextMenu(pos) { + contextMenu = Qt.createQmlObject("ContextMenu {}", root); + contextMenu.fillActions(); + contextMenu.show(); + } + /* * Three IconItems are used in order to achieve the same look and feel as Windows 7's * orbs. When the menu is closed, hovering over the orb results in the hovered icon @@ -85,73 +170,48 @@ Item { * visibility, where the normal and hovered icons are invisible, and the pressed icon * is visible. * - * These icons will by default try to fill up as much space as they can in the compact - * representation. + * When they're bounded by the panel, these icons will by default try to fill up as + * much space as they can in the compact representation while preserving their aspect + * ratio. */ - PlasmaCore.IconItem { - id: buttonIcon - anchors.fill: parent - opacity: 1 - readonly property double aspectRatio: (vertical ? implicitHeight / implicitWidth - : implicitWidth / implicitHeight) - - source: getResolvedUrl(plasmoid.configuration.customButtonImage, "orbs/normal.png") - - smooth: true - roundToIconSize: !useCustomButtonImage || aspectRatio === 1 - onSourceChanged: updateSizeHints() - } - PlasmaCore.IconItem { - id: buttonIconPressed - anchors.fill: parent - opacity: 1 - visible: dashWindow.visible - readonly property double aspectRatio: (vertical ? implicitHeight / implicitWidth - : implicitWidth / implicitHeight) - source: getResolvedUrl(plasmoid.configuration.customButtonImageActive, "orbs/selected.png") // - - smooth: true - roundToIconSize: !useCustomButtonImage || aspectRatio === 1 - onSourceChanged: updateSizeHints() - } - PlasmaCore.IconItem { - id: buttonIconHovered - z: 1 - source: getResolvedUrl(plasmoid.configuration.customButtonImageHover, "orbs/hovered.png"); - opacity: mouseArea.containsMouse - visible: !dashWindow.visible + FloatingOrb { + id: floatingOrbPanel + visible: (!stickOutOrb) anchors.fill: parent - readonly property double aspectRatio: (vertical ? implicitHeight / implicitWidth - : implicitWidth / implicitHeight) - smooth: true - Behavior on opacity { - NumberAnimation { properties: "opacity"; easing.type: Easing.InOutQuad; duration: opacityDuration } - } - // A custom icon could also be rectangular. However, if a square, custom, icon is given, assume it - // to be an icon and round it to the nearest icon size again to avoid scaling artifacts. - roundToIconSize: !useCustomButtonImage || aspectRatio === 1 - - onSourceChanged: updateSizeHints() + objectName: "innerorb" } - // Clicking on the plasmoid or activating it in any way causes the Full representation - // to show/hide. + // Covers the entire compact representation just in case the orb dialog doesn't cover + // the entire area by itself. MouseArea { - id: mouseArea + id: mouseAreaCompositingOff anchors.fill: parent hoverEnabled: true + visible: stickOutOrb + acceptedButtons: Qt.LeftButton | Qt.RightButton onClicked: { - dashWindow.visible = !dashWindow.visible; - dashWindow.showingAllPrograms = false; + if(mouse.button == Qt.RightButton) { + var pos = plasmoid.mapToGlobal(mouse.x, mouse.y); + createContextMenu(pos); + + + } else { + dashWindow.visible = !dashWindow.visible; + dashWindow.showingAllPrograms = false; + } } } + Component.onCompleted: { dashWindow = Qt.createQmlObject("MenuRepresentation {}", root); + orb = Qt.createQmlObject("StartOrb {}", root); plasmoid.activated.connect(function() { dashWindow.visible = !dashWindow.visible; + dashWindow.showingAllPrograms = false; }); + positionOrb(); } } diff --git a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/ConfigGeneral.qml b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/ConfigGeneral.qml index aec5bde..c348454 100755 --- a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/ConfigGeneral.qml +++ b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/ConfigGeneral.qml @@ -48,6 +48,7 @@ Item { property alias cfg_appNameFormat: appNameFormat.currentIndex property alias cfg_switchCategoriesOnHover: switchCategoriesOnHover.checked + property alias cfg_stickOutOrb: stickOutOrb.checked property alias cfg_useExtraRunners: useExtraRunners.checked @@ -61,7 +62,7 @@ Item { spacing: units.smallSpacing Label { - text: i18n("Icon:") + text: i18n("Orb:") } IconPicker { @@ -73,7 +74,7 @@ Item { } Label { - text: i18n("Hover Icon:") + text: i18n("Hover Orb:") } IconPicker { id: iconPickerHover @@ -84,7 +85,7 @@ Item { } Label { - text: i18n("Active Icon:") + text: i18n("Clicked Orb:") } IconPicker { id: iconPickerActive @@ -123,6 +124,11 @@ Item { text: i18n("Switch categories on hover") } + CheckBox { + id: stickOutOrb + + text: i18n("Force constant orb size") + } } } diff --git a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/ContextMenu.qml b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/ContextMenu.qml new file mode 100644 index 0000000..584cc60 --- /dev/null +++ b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/ContextMenu.qml @@ -0,0 +1,93 @@ + +import QtQuick 2.15 +import QtQuick.Layouts 1.1 +import org.kde.plasma.plasmoid 2.0 + +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.components 2.0 as PlasmaComponents + + +PlasmaComponents.ContextMenu { + id: menu + + placement: { + if (plasmoid.location === PlasmaCore.Types.LeftEdge) { + return PlasmaCore.Types.RightPosedTopAlignedPopup; + } else if (plasmoid.location === PlasmaCore.Types.TopEdge) { + return PlasmaCore.Types.BottomPosedLeftAlignedPopup; + } else if (plasmoid.location === PlasmaCore.Types.RightEdge) { + return PlasmaCore.Types.LeftPosedTopAlignedPopup; + } else { + return PlasmaCore.Types.TopPosedLeftAlignedPopup; + } + } + + minimumWidth: root.width + function show() { + openRelative(); + } + + function newMenuItem(parent) { + return Qt.createQmlObject(` + import org.kde.plasma.components 2.0 as PlasmaComponents + + PlasmaComponents.MenuItem { } + `, parent); + } + + function newSeparator(parent) { + return Qt.createQmlObject(` + import org.kde.plasma.components 2.0 as PlasmaComponents + + PlasmaComponents.MenuItem { separator: true } + `, parent); + } + function fillItem(item, action) { + item.text = action.text; + item.icon = action.icon; + item.visible = action.visible; + item.objectName = action.objectName; + item.clicked.connect(function() { + action.trigger(); + }); + addMenuItem(item); + } + function fillActions() { + plasmoid.prepareContextualActions(); + for(var index = 0; index < plasmoid.contextualActions.length; index++) { + var action = plasmoid.contextualActions[index]; + var item = newMenuItem(menu); + fillItem(item, action); + } + var action = plasmoid.action("alternatives"); + if(action && action.enabled) { + var item = newMenuItem(menu); + fillItem(item, action); + } + + item = newMenuItem(menu); + action = plasmoid.action("configure"); + fillItem(item, action); + + item = newSeparator(menu); + addMenuItem(item); + + action = containmentInterface.action("add widgets"); + if(action) { + item = newMenuItem(menu); + fillItem(item, action); + }; + + action = containmentInterface.action("configure"); + if(action) { + item = newMenuItem(menu); + fillItem(item, action); + }; + + } + onStatusChanged: { + if (status == PlasmaComponents.DialogStatus.Closed) { + menu.destroy(); + } + } +} diff --git a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/FloatingOrb.qml b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/FloatingOrb.qml new file mode 100644 index 0000000..59261ce --- /dev/null +++ b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/FloatingOrb.qml @@ -0,0 +1,103 @@ + +import QtQuick 2.4 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 +import QtQuick.Layouts 1.1 +import QtQuick.Dialogs 1.2 +import QtQuick.Window 2.1 +import QtGraphicalEffects 1.0 + +import org.kde.plasma.plasmoid 2.0 +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.components 2.0 as PlasmaComponents +import org.kde.plasma.extras 2.0 as PlasmaExtras + +import org.kde.plasma.private.kicker 0.1 as Kicker +import org.kde.kcoreaddons 1.0 as KCoreAddons // kuser +import org.kde.plasma.private.shell 2.0 + +import org.kde.kwindowsystem 1.0 +import org.kde.kquickcontrolsaddons 2.0 +import org.kde.plasma.private.quicklaunch 1.0 + +import org.kde.kirigami 2.13 as Kirigami +import org.kde.kquickcontrolsaddons 2.0 as KQuickAddons + +import org.kde.kwindowsystem 1.0 +import org.kde.kquickcontrolsaddons 2.0 as KQuickControlsAddons + + +Item { + id: floatingOrb + width: buttonIcon.implicitWidth + height: buttonIcon.implicitHeight + property alias buttonIcon: buttonIcon + property alias buttonIconPressed: buttonIconPressed + property alias buttonIconHovered: buttonIconHovered + property alias mouseArea: mouseArea + + PlasmaCore.IconItem { + id: buttonIcon + anchors.fill: parent + opacity: 1 + readonly property double aspectRatio: (vertical ? implicitHeight / implicitWidth + : implicitWidth / implicitHeight) + + source: getResolvedUrl(plasmoid.configuration.customButtonImage, "orbs/normal.png") + smooth: true + roundToIconSize: !useCustomButtonImage || aspectRatio === 1 + onSourceChanged: updateSizeHints() + } + PlasmaCore.IconItem { + id: buttonIconPressed + anchors.fill: parent + opacity: 1 + visible: dashWindow.visible + readonly property double aspectRatio: (vertical ? implicitHeight / implicitWidth + : implicitWidth / implicitHeight) + + source: getResolvedUrl(plasmoid.configuration.customButtonImageActive, "orbs/selected.png") // + + smooth: true + roundToIconSize: !useCustomButtonImage || aspectRatio === 1 + onSourceChanged: updateSizeHints() + } + PlasmaCore.IconItem { + id: buttonIconHovered + z: 1 + source: getResolvedUrl(plasmoid.configuration.customButtonImageHover, "orbs/hovered.png"); + opacity: mouseArea.containsMouse || mouseAreaCompositingOff.containsMouse + visible: !dashWindow.visible + anchors.fill: parent + readonly property double aspectRatio: (vertical ? implicitHeight / implicitWidth + : implicitWidth / implicitHeight) + smooth: true + Behavior on opacity { + NumberAnimation { properties: "opacity"; easing.type: Easing.InOutQuad; duration: opacityDuration } + } + // A custom icon could also be rectangular. However, if a square, custom, icon is given, assume it + // to be an icon and round it to the nearest icon size again to avoid scaling artifacts. + roundToIconSize: !useCustomButtonImage || aspectRatio === 1 + + onSourceChanged: updateSizeHints() + } + + MouseArea + { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + acceptedButtons: Qt.LeftButton | Qt.RightButton + onClicked: { + if(mouse.button == Qt.RightButton) { + var pos = plasmoid.mapToGlobal(mouse.x, mouse.y); + createContextMenu(pos); + + + } else { + dashWindow.visible = !dashWindow.visible; + dashWindow.showingAllPrograms = false; + } + } + } +} diff --git a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/ItemMultiGridView.qml b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/ItemMultiGridView.qml index adaac4e..298a12a 100755 --- a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/ItemMultiGridView.qml +++ b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/ItemMultiGridView.qml @@ -126,7 +126,10 @@ PlasmaExtras.ScrollArea { delegate: Item { width: itemColumn.width height: gridViewLabel.height + gridView.height + (index == repeater.count - 1 ? 0 : units.smallSpacing) - visible: repeater.model.modelForRow(index).count > 0 + visible: { + if(!repeater.model.modelForRow(index)) return false; + return repeater.model.modelForRow(index).count > 0 + } property alias currentIndex: gridView.currentIndex property alias count: gridView.count @@ -143,7 +146,10 @@ PlasmaExtras.ScrollArea { color: "#1d3287"; level: 4 verticalAlignment: Qt.AlignVCenter - text: repeater.model.modelForRow(index).description + " (" + repeater.model.modelForRow(index).count +")" + text: { + if(!repeater.model.modelForRow(index)) return ""; + return repeater.model.modelForRow(index).description + " (" + repeater.model.modelForRow(index).count +")"; + } } //Line that extends from the header to the right of the search view. diff --git a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/KickerListModel.qml b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/KickerListModel.qml index 49c664a..2825836 100755 --- a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/KickerListModel.qml +++ b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/KickerListModel.qml @@ -65,6 +65,7 @@ ListModel { } function parseModel(appList, model, path) { + // console.log(path, model, model.description, model.count); for (var i = 0; i < model.count; i++) { var item = model.modelForRow(i); if (!item) { @@ -72,8 +73,10 @@ ListModel { } var itemPath = (path || []).concat(i); if (item && item.hasChildren) { + // console.log(item) parseModel(appList, item, itemPath); } else { + // console.log(itemPath, item, item.description); appList.push(item); } } diff --git a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/MenuRepresentation.qml b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/MenuRepresentation.qml index f7de27f..0cc2ecd 100755 --- a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/MenuRepresentation.qml +++ b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/MenuRepresentation.qml @@ -42,7 +42,7 @@ import org.kde.plasma.private.quicklaunch 1.0 import org.kde.kirigami 2.13 as Kirigami import org.kde.kquickcontrolsaddons 2.0 as KQuickAddons -import org.kde.kwindowsystem 1.0 + PlasmaCore.Dialog { @@ -61,7 +61,7 @@ PlasmaCore.Dialog { property bool searching: (searchField.text != "") property bool showingAllPrograms: false property bool firstTimePopup: false // To make sure the user icon is displayed properly. - property bool compositingEnabled: kwindowsystem.compositingActive + property int slideAnimationDuration: 105 @@ -182,7 +182,7 @@ PlasmaCore.Dialog { focus: true clip: true - KWindowSystem { id: kwindowsystem } // Used for detecting compositing changes. + KCoreAddons.KUser { id: kuser } // Used for getting the username and icon. Logic { id: logic } // Probably useful. diff --git a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/SearchView.qml b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/SearchView.qml index d082b0f..23963da 100755 --- a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/SearchView.qml +++ b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/SearchView.qml @@ -57,7 +57,7 @@ Item { if (!searchField.text) { repeaterModelIndex = 0; runnerGrid.repeater.currentModelIndex = 0; - runnerModel.model = null; + if(runnerModel.model) runnerModel.model = null; } else { if(runnerGrid.count != 0) { runnerGrid.repeater.currentModelIndex = 0; @@ -72,6 +72,7 @@ Item { if(!focus) repeaterModelIndex = runnerGrid.repeater.currentModelIndex; else { runnerGrid.repeater.currentModelIndex = repeaterModelIndex; + console.log("home."); } } } diff --git a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/StartOrb.qml b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/StartOrb.qml new file mode 100644 index 0000000..11b4dc1 --- /dev/null +++ b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/StartOrb.qml @@ -0,0 +1,103 @@ + +import QtQuick 2.4 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 +import QtQuick.Layouts 1.1 +import QtQuick.Dialogs 1.2 +import QtQuick.Window 2.1 +import QtGraphicalEffects 1.0 + +import org.kde.plasma.plasmoid 2.0 +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.components 2.0 as PlasmaComponents +import org.kde.plasma.extras 2.0 as PlasmaExtras + +import org.kde.plasma.private.kicker 0.1 as Kicker +import org.kde.kcoreaddons 1.0 as KCoreAddons // kuser +import org.kde.plasma.private.shell 2.0 + +import org.kde.kwindowsystem 1.0 +import org.kde.kquickcontrolsaddons 2.0 +import org.kde.plasma.private.quicklaunch 1.0 + +import org.kde.kirigami 2.13 as Kirigami +import org.kde.kquickcontrolsaddons 2.0 as KQuickAddons + +import org.kde.kwindowsystem 1.0 +import org.kde.kquickcontrolsaddons 2.0 as KQuickControlsAddons + +/* + * This is the Dialog that displays the Start menu orb when it sticks out + * of the panel. In principle, it works in almost the same way as the + * Start menu user icon, in fact most of the code is directly copied from + * there. + * + * With this approach, two important problems come up: + * 1. Right clicking on this dialog window won't open the standard + * context menu as expected, as it actually isn't part of the + * compact or full representation. + * 2. When compositing is disabled, even with the NoBackground hint, this + * dialog window will simply be drawn with an opaque, black background. + * + * This source code tackles both problems in such a way to avoid having to + * introduce a compiled component of the plasmoid, which would greatly + * reduce its portability and ease of installation. The downside of this + * approach is that the solution to the second problem leaves us bound to + * the Seven-Black Plasma theme, as it uses the SVG file found in + * + * /solid/widgets/tooltip.svg + * + * However, this can be circumvented by copying this file over to any other + * theme, as this is probably the *least* used SVG texture in KDE, if not + * completely unused. This SVG file contains only the opacity and input + * mask of the dialog window, which gets applied when X11 compositing is + * disabled. Another slight limitation to this approach is that the + * possible choice of menu orbs is limited to perfect spheres in this + * particular configuration. This can be corrected if the opacity mask is + * changed in the SVG file, meaning that installing custom orbs might + * potentially be a two-step process now. + * + * Compared to the popup avatar, this dialog window should NOT have any + * visualParent set, as it causes inexplicable behavior where the orb + * moves away. I have no idea why it does that. + * + * This has been developed only for the bottom/south oriented panel, and + * other orientations should receive support when I begin giving pretty + * much *everything* else support for other orientations. + * + */ + + PlasmaCore.Dialog { + id: iconUser + flags: Qt.WindowStaysOnTopHint | Qt.Popup | Qt.X11BypassWindowManagerHint // To prevent the icon from animating its opacity when its visibility is changed + type: "Tooltip" // Crucial to making this work under no compositing. See above for details. + location: "Floating" + + // Positions are defined when the plasmoid has been fully loaded, to prevent undefined behavior. + x: 0 + y: 0 + onYChanged: { // Tries to circumvent possible inexplicable changes in position. Currently doesn't seem to run in practice anymore, as it has most likely been fixed by keeping the visualParent undefined. + var pos = plasmoid.mapToGlobal(kicker.x, kicker.y); + if(iconUser.y - pos.y < 0) { + iconUser.y -= iconUser.y - pos.y + panelSvg.margins.bottom*2 + panelSvg.margins.top*2; + } + } + backgroundHints: PlasmaCore.Types.SolidBackground + visible: root.visible && stickOutOrb + opacity: iconUser.visible // To prevent even more NP-hard unpredictable behavior + + // The actual orb button, this dialog window is just a container for it. + mainItem: FloatingOrb { + id: floatingOrbIcon + } + Component.onCompleted: { + /* + * When compositing is enabled, we want to simply use the NoBackground + * hint to render a fully transparent, blur-free window. If we used the + * same opacity mask for both cases, blur would be applied behind the + * orb, which would also by extension render reflections and colorize + * the entire area as well. + */ + iconUser.backgroundHints = compositing ? 0 : 2; + } +} diff --git a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/main.qml b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/main.qml index 2c00674..13cf635 100755 --- a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/main.qml +++ b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/main.qml @@ -24,6 +24,8 @@ import org.kde.plasma.plasmoid 2.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.plasma.private.kicker 0.1 as Kicker +import org.kde.kquickcontrolsaddons 2.0 as KQuickControlsAddons +import org.kde.kwindowsystem 1.0 Item { id: kicker @@ -33,6 +35,7 @@ Item { anchors.fill: parent property bool isDash: false property Item dragSource: null + clip: true // With this we can make the compact representation be any // item we want. @@ -42,6 +45,7 @@ Item { property QtObject globalFavorites: rootModel.favoritesModel property QtObject systemFavorites: rootModel.systemFavoritesModel + property bool compositingEnabled: kwindowsystem.compositingActive // Runs KMenuEdit. function action_menuedit() { @@ -82,7 +86,7 @@ Item { } signal exited(string cmd, int exitCode, int exitStatus, string stdout, string stderr) } - + KWindowSystem { id: kwindowsystem } // Used for detecting compositing changes. Kicker.RootModel { id: rootModel @@ -230,5 +234,6 @@ Item { rootModel.refreshed.connect(reset); dragHelper.dropped.connect(resetDragSource); + } } diff --git a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/orbs/hovered.png b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/orbs/hovered.png index 6a652f1..a01a6d1 100755 Binary files a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/orbs/hovered.png and b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/orbs/hovered.png differ diff --git a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/orbs/normal.png b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/orbs/normal.png index b522030..8c00905 100755 Binary files a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/orbs/normal.png and b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/orbs/normal.png differ diff --git a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/orbs/selected.png b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/orbs/selected.png index 4b8a1a2..9b5965f 100755 Binary files a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/orbs/selected.png and b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.SevenStart/contents/ui/orbs/selected.png differ diff --git a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.seventasks/contents/ui/Task.qml b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.seventasks/contents/ui/Task.qml index 6d08a16..7d91674 100755 --- a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.seventasks/contents/ui/Task.qml +++ b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.seventasks/contents/ui/Task.qml @@ -58,6 +58,7 @@ MouseArea { property real taskHeight: 0 property string previousState: "" property bool rightClickDragging: false + property bool toolTipOpen: false property Item audioStreamOverlay property var audioStreams: [] @@ -153,6 +154,7 @@ MouseArea { } hoverEnabled = true; taskList.updateHoverFunc(); + toolTipArea.tooltipClicked = true; } onContainsMouseChanged: { @@ -176,6 +178,7 @@ MouseArea { hoverEnabled = true; updateMousePosition(ma.mouseX); + toolTipArea.tooltipClicked = true; } @@ -226,8 +229,11 @@ MouseArea { if (plasmoid.configuration.showToolTips && toolTipArea.active) { hideToolTipTemporarily(); } + /*if(childCount >= 2 && plasmoid.configuration.showToolTips && toolTipArea.active) { + toolTipArea.tooltipClicked = !toolTipArea.tooltipClicked; + }*/ TaskTools.activateTask(modelIndex(), model, mouse.modifiers, task); - + } else if (mouse.button === Qt.BackButton || mouse.button === Qt.ForwardButton) { var sourceName = mpris2Source.sourceNameForLauncherUrl(model.LauncherUrlWithoutIcon, model.AppPid); if (sourceName) { @@ -452,7 +458,7 @@ MouseArea { opacity: 0.6 visible: childCount >= 3 ? true : false anchors.rightMargin: PlasmaCore.Units.smallSpacing - enabledBorders: Plasma.FrameSvg.EnabledBorders.RightBorder + enabledBorders: PlasmaCore.FrameSvg.RightBorder } @@ -711,8 +717,8 @@ MouseArea { PlasmaCore.ToolTipArea { id: toolTipArea z: -1 - //backgroundHints: "SolidBackground" - MouseArea { + + MouseArea { id: ma hoverEnabled: true propagateComposedEvents: true @@ -720,34 +726,32 @@ MouseArea { onPositionChanged: { task.updateMousePosition(ma.mouseX); task.positionChanged(mouse); - //var xtr = toolTipArea.backgroundHints(); - } onContainsMouseChanged: { - task.updateMousePosition(ma.mouseX); - //task.onContainsMouseChanged(); - //toolTipArea.onContainsMouseChanged(); - //mouse.accepted = false; } onPressed: mouse.accepted = false; onReleased: mouse.accepted = false; onWheel: wheel.accepted = false; - //onExited: { hoverGradient.horizontalOffset = 0; - //task.onExited(); - //} } anchors.fill: parent location: plasmoid.location - - active: !inPopup && !groupDialog.visible && plasmoid.configuration.showToolTips + property bool tooltipClicked: true + active: !inPopup && !groupDialog.visible && (plasmoid.configuration.showToolTips || tasks.toolTipOpenedByClick === toolTipArea) interactive: model.IsWindow === true mainItem: (model.IsWindow === true) ? openWindowToolTipDelegate : pinnedAppToolTipDelegate property alias mainToolTip: toolTipArea.mainItem + onToolTipVisibleChanged: { + task.toolTipOpen = toolTipVisible; + if(!toolTipVisible) { + tasks.toolTipOpenedByClick = null; + } else { + tasks.toolTipAreaItem = toolTipArea; + } + } onContainsMouseChanged: { - updateMousePosition(ma.mouseX); if (containsMouse) { mainItem.parentTask = task; @@ -802,6 +806,9 @@ MouseArea { mainItem.smartLauncherCount = Qt.binding(function() { return mainItem.smartLauncherCountVisible ? task.smartLauncherItem.count : 0; }); + tasks.toolTipAreaItem = toolTipArea; + } else { + tasks.toolTipOpenedByClick = null; } } } diff --git a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.seventasks/contents/ui/code/tools.js b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.seventasks/contents/ui/code/tools.js index e672436..5816e75 100755 --- a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.seventasks/contents/ui/code/tools.js +++ b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.seventasks/contents/ui/code/tools.js @@ -148,7 +148,11 @@ function activateTask(index, model, modifiers, task) { else if (plasmoid.configuration.showToolTips && plasmoid.configuration.groupedTaskVisualization === 1 ) { - task.showToolTip(); + if(tasks.toolTipOpenedByClick) tasks.toolTipOpenedByClick.hideImmediately(); + else { + tasks.toolTipOpenedByClick = task.toolTipAreaItem; + task.showToolTip(); + } } // Option 3: show Present Windows for all child tasks diff --git a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.seventasks/contents/ui/main.qml b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.seventasks/contents/ui/main.qml index 6ea6c6e..c8d3e4a 100755 --- a/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.seventasks/contents/ui/main.qml +++ b/Plasma/Plasma_Widgets/User/io.gitgud.wackyideas.seventasks/contents/ui/main.qml @@ -27,7 +27,8 @@ MouseArea { // This property tells the plasmoid to render labels next to task icons. // Previously, this property was determined by the value of (plasmoid.pluginName === "org.kde.plasma.icontasks") property bool iconsOnly: !plasmoid.configuration.labelVisible - + property var toolTipOpenedByClick: null + property var toolTipAreaItem: null //property QtObject contextMenuComponent: Qt.createComponent("ContextMenu.qml"); property QtObject tasksMenuComponent: Qt.createComponent("TasksMenu.qml"); property QtObject pulseAudioComponent: Qt.createComponent("PulseAudio.qml"); @@ -60,6 +61,7 @@ MouseArea { signal requestLayout signal windowsHovered(variant winIds, bool hovered) + signal activateWindowView(variant winIds) signal presentWindows(variant winIds) states: State { @@ -511,10 +513,12 @@ MouseArea { // With this, we can update each task icon pretty much globally. function updateHoverFunc() { for(var i = 0; i < taskRepeater.count; i++) { - taskRepeater.itemAt(i).updateHoverColor(); + if(taskRepeater.itemAt(i)) { + taskRepeater.itemAt(i).updateHoverColor(); + } } tasks.state = ""; - console.log("Updated hovers"); + //console.log("Updated hovers"); } Timer { @@ -604,7 +608,8 @@ MouseArea { tasks.requestLayout.connect(layoutTimer.restart); tasks.requestLayout.connect(iconGeometryTimer.restart); tasks.windowsHovered.connect(backend.windowsHovered); - tasks.presentWindows.connect(backend.presentWindows); + //tasks.presentWindows.connect(backend.presentWindows); + tasks.activateWindowView.connect(backend.activateWindowView); dragHelper.dropped.connect(resetDragSource); taskList.updateHoverFunc(); } diff --git a/Plasma/Plasma_Widgets/User/seventasks_src/src/package/contents/ui/ContextMenu.qml b/Plasma/Plasma_Widgets/User/seventasks_src/src/package/contents/ui/ContextMenu.qml deleted file mode 100755 index 09493d6..0000000 --- a/Plasma/Plasma_Widgets/User/seventasks_src/src/package/contents/ui/ContextMenu.qml +++ /dev/null @@ -1,774 +0,0 @@ -/* - SPDX-FileCopyrightText: 2012-2016 Eike Hein - SPDX-FileCopyrightText: 2016 Kai Uwe Broulik - - SPDX-License-Identifier: GPL-2.0-or-later -*/ - -import QtQuick 2.15 - -import org.kde.plasma.plasmoid 2.0 - -import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.plasma.components 2.0 as PlasmaComponents - -import org.kde.taskmanager 0.1 as TaskManager - -import "code/layout.js" as LayoutManager - -PlasmaComponents.ContextMenu { - id: menu - - property QtObject backend - property QtObject mpris2Source - property var modelIndex - readonly property var atm: TaskManager.AbstractTasksModel - - property bool showAllPlaces: false - - - placement: { - if (plasmoid.location === PlasmaCore.Types.LeftEdge) { - return PlasmaCore.Types.RightPosedTopAlignedPopup; - } else if (plasmoid.location === PlasmaCore.Types.TopEdge) { - return PlasmaCore.Types.BottomPosedLeftAlignedPopup; - } else if (plasmoid.location === PlasmaCore.Types.RightEdge) { - return PlasmaCore.Types.LeftPosedTopAlignedPopup; - } else { - return PlasmaCore.Types.TopPosedLeftAlignedPopup; - } - } - - minimumWidth: visualParent.width - //We have all of the above - - //Might be important, at least the opening part - onStatusChanged: { - if (visualParent && get(atm.LauncherUrlWithoutIcon) != "" && status == PlasmaComponents.DialogStatus.Open) { - activitiesDesktopsMenu.refresh(); - - } else if (status == PlasmaComponents.DialogStatus.Closed) { - menu.destroy(); - backend.ungrabMouse(visualParent); - } - } - - Component.onCompleted: { - // Cannot have "Connections" as child of PlasmaCoponents.ContextMenu. - backend.showAllPlaces.connect(showContextMenuWithAllPlaces); - } - - Component.onDestruction: { - backend.showAllPlaces.disconnect(showContextMenuWithAllPlaces); - } - - function showContextMenuWithAllPlaces() { - visualParent.showContextMenu({showAllPlaces: true}); - } - - function get(modelProp) { - return tasksModel.data(modelIndex, modelProp) - } - - function show() { - loadDynamicLaunchActions(get(atm.LauncherUrlWithoutIcon)); - openRelative(); - } - - function newMenuItem(parent) { - return Qt.createQmlObject(` - import org.kde.plasma.components 2.0 as PlasmaComponents - - PlasmaComponents.MenuItem {} - `, parent); - } - - function newSeparator(parent) { - return Qt.createQmlObject(` - import org.kde.plasma.components 2.0 as PlasmaComponents - - PlasmaComponents.MenuItem { separator: true } - `, parent); - } - - function loadDynamicLaunchActions(launcherUrl) { - var sections = [ - { - title: i18n("Places"), - group: "places", - actions: backend.placesActions(launcherUrl, showAllPlaces, menu) - }, - { - title: i18n("Recent Files"), - group: "recents", - actions: backend.recentDocumentActions(launcherUrl, menu) - }, - { - title: i18n("Actions"), - group: "actions", - actions: backend.jumpListActions(launcherUrl, menu) - } - ] - - // C++ can override section heading by returning a QString as first action - sections.forEach((section) => { - if (typeof section.actions[0] === "string") { - section.title = section.actions.shift(); // take first - } - }); - - // QMenu does not limit its width automatically. Even if we set a maximumWidth - // it would just cut off text rather than eliding. So we do this manually. - var textMetrics = Qt.createQmlObject("import QtQuick 2.4; TextMetrics {}", menu); - var maximumWidth = LayoutManager.maximumContextMenuTextWidth(); - - sections.forEach(function (section) { - if (section["actions"].length > 0 || section["group"] == "actions") { - // Don't add the "Actions" header if the menu has nothing but actions - // in it, because then it's redundant (all menus have actions) - if ( - (section["group"] != "actions") || - (section["group"] == "actions" && (sections[0]["actions"].length > 0 || sections[1]["actions"].length > 0)) - ) { - var sectionHeader = newMenuItem(menu); - sectionHeader.text = section["title"]; - sectionHeader.section = true; - menu.addMenuItem(sectionHeader, startNewInstanceItem); - } - } - - for (var i = 0; i < section["actions"].length; ++i) { - var item = newMenuItem(menu); - item.action = section["actions"][i]; - - // Crude way of manually eliding... - var elided = false; - textMetrics.text = Qt.binding(function() { - return item.action.text; - }); - - while (textMetrics.width > maximumWidth) { - item.action.text = item.action.text.slice(0, -1); - elided = true; - } - - if (elided) { - item.action.text += "…"; - } - - menu.addMenuItem(item, startNewInstanceItem); - } - }); - - // Add Media Player control actions - var sourceName = mpris2Source.sourceNameForLauncherUrl(launcherUrl, get(atm.AppPid)); - - if (sourceName && !(get(atm.WinIdList) !== undefined && get(atm.WinIdList).length > 1)) { - var playerData = mpris2Source.data[sourceName] - - if (playerData.CanControl) { - var playing = (playerData.PlaybackStatus === "Playing"); - var menuItem = menu.newMenuItem(menu); - menuItem.text = i18nc("Play previous track", "Previous Track"); - menuItem.icon = "media-skip-backward"; - menuItem.enabled = Qt.binding(function() { - return playerData.CanGoPrevious; - }); - menuItem.clicked.connect(function() { - mpris2Source.goPrevious(sourceName); - }); - menu.addMenuItem(menuItem, startNewInstanceItem); - - menuItem = menu.newMenuItem(menu); - // PlasmaCore Menu doesn't actually handle icons or labels changing at runtime... - menuItem.text = Qt.binding(function() { - // if CanPause, toggle the menu entry between Play & Pause, otherwise always use Play - return playing && playerData.CanPause ? i18nc("Pause playback", "Pause") : i18nc("Start playback", "Play"); - }); - menuItem.icon = Qt.binding(function() { - return playing && playerData.CanPause ? "media-playback-pause" : "media-playback-start"; - }); - menuItem.enabled = Qt.binding(function() { - return playing ? playerData.CanPause : playerData.CanPlay; - }); - menuItem.clicked.connect(function() { - if (playing) { - mpris2Source.pause(sourceName); - } else { - mpris2Source.play(sourceName); - } - }); - menu.addMenuItem(menuItem, startNewInstanceItem); - - menuItem = menu.newMenuItem(menu); - menuItem.text = i18nc("Play next track", "Next Track"); - menuItem.icon = "media-skip-forward"; - menuItem.enabled = Qt.binding(function() { - return playerData.CanGoNext; - }); - menuItem.clicked.connect(function() { - mpris2Source.goNext(sourceName); - }); - menu.addMenuItem(menuItem, startNewInstanceItem); - - menuItem = menu.newMenuItem(menu); - menuItem.text = i18nc("Stop playback", "Stop"); - menuItem.icon = "media-playback-stop"; - menuItem.enabled = Qt.binding(function() { - return playerData.PlaybackStatus !== "Stopped"; - }); - menuItem.clicked.connect(function() { - mpris2Source.stop(sourceName); - }); - menu.addMenuItem(menuItem, startNewInstanceItem); - - // Technically media controls and audio streams are separate but for the user they're - // semantically related, don't add a separator inbetween. - if (!menu.visualParent.hasAudioStream) { - menu.addMenuItem(newSeparator(menu), startNewInstanceItem); - } - - // If we don't have a window associated with the player but we can quit - // it through MPRIS we'll offer a "Quit" option instead of "Close" - if (!closeWindowItem.visible && playerData.CanQuit) { - menuItem = menu.newMenuItem(menu); - menuItem.text = i18nc("Quit media player app", "Quit"); - menuItem.icon = "application-exit"; - menuItem.visible = Qt.binding(function() { - return !closeWindowItem.visible; - }); - menuItem.clicked.connect(function() { - mpris2Source.quit(sourceName); - }); - menu.addMenuItem(menuItem); - } - - // If we don't have a window associated with the player but we can raise - // it through MPRIS we'll offer a "Restore" option - if (get(atm.IsLauncher) === true && !startNewInstanceItem.visible && playerData.CanRaise) { - menuItem = menu.newMenuItem(menu); - menuItem.text = i18nc("Open or bring to the front window of media player app", "Restore"); - menuItem.icon = playerData["Desktop Icon Name"]; - menuItem.visible = Qt.binding(function() { - return !startNewInstanceItem.visible; - }); - menuItem.clicked.connect(function() { - mpris2Source.raise(sourceName); - }); - menu.addMenuItem(menuItem, startNewInstanceItem); - } - } - } - - // We allow mute/unmute whenever an application has a stream, regardless of whether it - // is actually playing sound. - // This way you can unmute, e.g. a telephony app, even after the conversation has ended, - // so you still have it ringing later on. - if (menu.visualParent.hasAudioStream) { - var muteItem = menu.newMenuItem(menu); - muteItem.checkable = true; - muteItem.checked = Qt.binding(function() { - return menu.visualParent && menu.visualParent.muted; - }); - muteItem.clicked.connect(function() { - menu.visualParent.toggleMuted(); - }); - muteItem.text = i18n("Mute"); - muteItem.icon = "audio-volume-muted"; - menu.addMenuItem(muteItem, startNewInstanceItem); - - menu.addMenuItem(newSeparator(menu), startNewInstanceItem); - } - } - - PlasmaComponents.MenuItem { - id: startNewInstanceItem - visible: get(atm.CanLaunchNewInstance) - text: i18n("Open New Window") - icon: "window-new" - - onClicked: tasksModel.requestNewInstance(modelIndex) - } - - PlasmaComponents.MenuItem { - id: virtualDesktopsMenuItem - - visible: virtualDesktopInfo.numberOfDesktops > 1 - && (visualParent && get(atm.IsLauncher) !== true - && get(atm.IsStartup) !== true - && get(atm.IsVirtualDesktopsChangeable) === true) - - enabled: visible - - text: i18n("Move to &Desktop") - icon: "virtual-desktops" - - Connections { - target: virtualDesktopInfo - - function onNumberOfDesktopsChanged() {Qt.callLater(virtualDesktopsMenu.refresh)} - function onDesktopIdsChanged() {Qt.callLater(virtualDesktopsMenu.refresh)} - function onDesktopNamesChanged() {Qt.callLater(virtualDesktopsMenu.refresh)} - } - - PlasmaComponents.ContextMenu { - id: virtualDesktopsMenu - - visualParent: virtualDesktopsMenuItem.action - - function refresh() { - clearMenuItems(); - - if (virtualDesktopInfo.numberOfDesktops <= 1) { - return; - } - - var menuItem = menu.newMenuItem(virtualDesktopsMenu); - menuItem.text = i18n("Move &To Current Desktop"); - menuItem.enabled = Qt.binding(function() { - return menu.visualParent && menu.get(atm.VirtualDesktops).indexOf(virtualDesktopInfo.currentDesktop) === -1; - }); - menuItem.clicked.connect(function() { - tasksModel.requestVirtualDesktops(menu.modelIndex, [virtualDesktopInfo.currentDesktop]); - }); - - menuItem = menu.newMenuItem(virtualDesktopsMenu); - menuItem.text = i18n("&All Desktops"); - menuItem.checkable = true; - menuItem.checked = Qt.binding(function() { - return menu.visualParent && menu.get(atm.IsOnAllVirtualDesktops) === true; - }); - menuItem.clicked.connect(function() { - tasksModel.requestVirtualDesktops(menu.modelIndex, []); - }); - backend.setActionGroup(menuItem.action); - - menu.newSeparator(virtualDesktopsMenu); - - for (var i = 0; i < virtualDesktopInfo.desktopNames.length; ++i) { - menuItem = menu.newMenuItem(virtualDesktopsMenu); - menuItem.text = i18nc("1 = number of desktop, 2 = desktop name", "&%1 %2", i + 1, virtualDesktopInfo.desktopNames[i]); - menuItem.checkable = true; - menuItem.checked = Qt.binding((function(i) { - return function() { return menu.visualParent && menu.get(atm.VirtualDesktops).indexOf(virtualDesktopInfo.desktopIds[i]) > -1 }; - })(i)); - menuItem.clicked.connect((function(i) { - return function() { return tasksModel.requestVirtualDesktops(menu.modelIndex, [virtualDesktopInfo.desktopIds[i]]); }; - })(i)); - backend.setActionGroup(menuItem.action); - } - - menu.newSeparator(virtualDesktopsMenu); - - menuItem = menu.newMenuItem(virtualDesktopsMenu); - menuItem.text = i18n("&New Desktop"); - menuItem.clicked.connect(function() { - tasksModel.requestNewVirtualDesktop(menu.modelIndex); - }); - } - - Component.onCompleted: refresh() - } - } - - PlasmaComponents.MenuItem { - id: activitiesDesktopsMenuItem - - visible: activityInfo.numberOfRunningActivities > 1 - && (visualParent && !get(atm.IsLauncher) - && !get(atm.IsStartup)) - - enabled: visible - - text: i18n("Show in &Activities") - icon: "activities" - - Connections { - target: activityInfo - - function onNumberOfRunningActivitiesChanged() { - activitiesDesktopsMenu.refresh() - } - } - - PlasmaComponents.ContextMenu { - id: activitiesDesktopsMenu - - visualParent: activitiesDesktopsMenuItem.action - - function refresh() { - clearMenuItems(); - - if (activityInfo.numberOfRunningActivities <= 1) { - return; - } - - var menuItem = menu.newMenuItem(activitiesDesktopsMenu); - menuItem.text = i18n("Add To Current Activity"); - menuItem.enabled = Qt.binding(function() { - return menu.visualParent && menu.get(atm.Activities).length > 0 && - menu.get(atm.Activities).indexOf(activityInfo.currentActivity) < 0; - }); - menuItem.clicked.connect(function() { - tasksModel.requestActivities(menu.modelIndex, menu.get(atm.Activities).concat(activityInfo.currentActivity)); - }); - - menuItem = menu.newMenuItem(activitiesDesktopsMenu); - menuItem.text = i18n("All Activities"); - menuItem.checkable = true; - menuItem.checked = Qt.binding(function() { - return menu.visualParent && menu.get(atm.Activities).length === 0; - }); - menuItem.toggled.connect(function(checked) { - let newActivities = []; // will cast to an empty QStringList i.e all activities - if (!checked) { - newActivities = new Array(activityInfo.currentActivity); - } - tasksModel.requestActivities(menu.modelIndex, newActivities); - }); - - menu.newSeparator(activitiesDesktopsMenu); - - var runningActivities = activityInfo.runningActivities(); - for (var i = 0; i < runningActivities.length; ++i) { - var activityId = runningActivities[i]; - - menuItem = menu.newMenuItem(activitiesDesktopsMenu); - menuItem.text = activityInfo.activityName(runningActivities[i]); - menuItem.checkable = true; - menuItem.checked = Qt.binding( (function(activityId) { - return function() { - return menu.visualParent && menu.get(atm.Activities).indexOf(activityId) >= 0; - }; - })(activityId)); - menuItem.toggled.connect((function(activityId) { - return function (checked) { - var newActivities = menu.get(atm.Activities); - if (checked) { - newActivities = newActivities.concat(activityId); - } else { - var index = newActivities.indexOf(activityId) - if (index < 0) { - return; - } - - newActivities.splice(index, 1); - } - return tasksModel.requestActivities(menu.modelIndex, newActivities); - }; - })(activityId)); - } - - menu.newSeparator(activitiesDesktopsMenu); - - for (var i = 0; i < runningActivities.length; ++i) { - var activityId = runningActivities[i]; - var onActivities = menu.get(atm.Activities); - - // if the task is on a single activity, don't insert a "move to" item for that activity - if(onActivities.length == 1 && onActivities[0] == activityId) { - continue; - } - - menuItem = menu.newMenuItem(activitiesDesktopsMenu); - menuItem.text = i18n("Move to %1", activityInfo.activityName(activityId)) - menuItem.clicked.connect((function(activityId) { - return function () { - return tasksModel.requestActivities(menu.modelIndex, [activityId]); - }; - })(activityId)); - } - - menu.newSeparator(activitiesDesktopsMenu); - } - - Component.onCompleted: refresh() - } - } - - PlasmaComponents.MenuItem { - id: launcherToggleAction - - visible: visualParent - && get(atm.IsLauncher) !== true - && get(atm.IsStartup) !== true - && plasmoid.immutability !== PlasmaCore.Types.SystemImmutable - && (activityInfo.numberOfRunningActivities < 2) - && !doesBelongToCurrentActivity() - - enabled: visualParent && get(atm.LauncherUrlWithoutIcon) != "" - - text: i18n("&Pin to Task Manager") - icon: "window-pin" - - function doesBelongToCurrentActivity() { - return tasksModel.launcherActivities(get(atm.LauncherUrlWithoutIcon)).some(function(activity) { - return activity === activityInfo.currentActivity || activity === activityInfo.nullUuid; - }); - } - - onClicked: { - tasksModel.requestAddLauncher(get(atm.LauncherUrl)); - } - } - - PlasmaComponents.MenuItem { - id: showLauncherInActivitiesItem - - text: i18n("&Pin to Task Manager") - icon: "window-pin" - - visible: visualParent - && get(atm.IsStartup) !== true - && plasmoid.immutability !== PlasmaCore.Types.SystemImmutable - && (activityInfo.numberOfRunningActivities >= 2) - - Connections { - target: activityInfo - function onNumberOfRunningActivitiesChanged() { - activitiesDesktopsMenu.refresh() - } - } - - PlasmaComponents.ContextMenu { - id: activitiesLaunchersMenu - visualParent: showLauncherInActivitiesItem.action - - function refresh() { - clearMenuItems(); - - if (menu.visualParent === null) return; - - var createNewItem = function(id, title, url, activities) { - var result = menu.newMenuItem(activitiesLaunchersMenu); - result.text = title; - - result.visible = true; - result.checkable = true; - - result.checked = activities.some(function(activity) { return activity === id }); - - result.clicked.connect( - function() { - if (result.checked) { - tasksModel.requestAddLauncherToActivity(url, id); - } else { - tasksModel.requestRemoveLauncherFromActivity(url, id); - } - } - ); - - return result; - } - - if (menu.visualParent === null) return; - - var url = menu.get(atm.LauncherUrlWithoutIcon); - - var activities = tasksModel.launcherActivities(url); - - createNewItem(activityInfo.nullUuid, i18n("On All Activities"), url, activities); - - if (activityInfo.numberOfRunningActivities <= 1) { - return; - } - - createNewItem(activityInfo.currentActivity, i18n("On The Current Activity"), url, activities); - - menu.newSeparator(activitiesLaunchersMenu); - - var runningActivities = activityInfo.runningActivities(); - - runningActivities.forEach(function(id) { - createNewItem(id, activityInfo.activityName(id), url, activities); - }); - } - - Component.onCompleted: { - menu.onVisualParentChanged.connect(refresh); - refresh(); - } - } - } - - PlasmaComponents.MenuItem { - visible: (visualParent - && plasmoid.immutability !== PlasmaCore.Types.SystemImmutable - && !launcherToggleAction.visible - && activityInfo.numberOfRunningActivities < 2) - - text: i18n("Unpin from Task Manager") - icon: "window-unpin" - - onClicked: { - tasksModel.requestRemoveLauncher(get(atm.LauncherUrlWithoutIcon)); - } - } - - PlasmaComponents.MenuItem { - id: moreActionsMenuItem - - visible: (visualParent && get(atm.IsLauncher) !== true && get(atm.IsStartup) !== true) - - enabled: visible - - text: i18n("More") - icon: "view-more-symbolic" - - PlasmaComponents.ContextMenu { - visualParent: moreActionsMenuItem.action - - PlasmaComponents.MenuItem { - enabled: menu.visualParent && menu.get(atm.IsMovable) === true - - text: i18n("&Move") - icon: "transform-move" - - onClicked: tasksModel.requestMove(menu.modelIndex) - } - - PlasmaComponents.MenuItem { - enabled: menu.visualParent && menu.get(atm.IsResizable) === true - - text: i18n("Re&size") - icon: "transform-scale" - - onClicked: tasksModel.requestResize(menu.modelIndex) - } - - PlasmaComponents.MenuItem { - visible: (menu.visualParent && get(atm.IsLauncher) !== true && get(atm.IsStartup) !== true) - - enabled: menu.visualParent && get(atm.IsMaximizable) === true - - checkable: true - checked: menu.visualParent && get(atm.IsMaximized) === true - - text: i18n("Ma&ximize") - icon: "window-maximize" - - onClicked: tasksModel.requestToggleMaximized(modelIndex) - } - - PlasmaComponents.MenuItem { - visible: (menu.visualParent && get(atm.IsLauncher) !== true && get(atm.IsStartup) !== true) - - enabled: menu.visualParent && get(atm.IsMinimizable) === true - - checkable: true - checked: menu.visualParent && get(atm.IsMinimized) === true - - text: i18n("Mi&nimize") - icon: "window-minimize" - - onClicked: tasksModel.requestToggleMinimized(modelIndex) - } - - PlasmaComponents.MenuItem { - checkable: true - checked: menu.visualParent && menu.get(atm.IsKeepAbove) === true - - text: i18n("Keep &Above Others") - icon: "window-keep-above" - - onClicked: tasksModel.requestToggleKeepAbove(menu.modelIndex) - } - - PlasmaComponents.MenuItem { - checkable: true - checked: menu.visualParent && menu.get(atm.IsKeepBelow) === true - - text: i18n("Keep &Below Others") - icon: "window-keep-below" - - onClicked: tasksModel.requestToggleKeepBelow(menu.modelIndex) - } - - PlasmaComponents.MenuItem { - enabled: menu.visualParent && menu.get(atm.IsFullScreenable) === true - - checkable: true - checked: menu.visualParent && menu.get(atm.IsFullScreen) === true - - text: i18n("&Fullscreen") - icon: "view-fullscreen" - - onClicked: tasksModel.requestToggleFullScreen(menu.modelIndex) - } - - PlasmaComponents.MenuItem { - enabled: menu.visualParent && menu.get(atm.IsShadeable) === true - - checkable: true - checked: menu.visualParent && menu.get(atm.IsShaded) === true - - text: i18n("&Shade") - icon: "window-shade" - - onClicked: tasksModel.requestToggleShaded(menu.modelIndex) - } - - PlasmaComponents.MenuItem { - separator: true - } - - PlasmaComponents.MenuItem { - visible: (plasmoid.configuration.groupingStrategy !== 0) && menu.get(atm.IsWindow) === true - - checkable: true - checked: menu.visualParent && menu.get(atm.IsGroupable) === true - - text: i18n("Allow this program to be grouped") - icon: "view-group" - - onClicked: tasksModel.requestToggleGrouping(menu.modelIndex) - } - - PlasmaComponents.MenuItem { - separator: true - } - - PlasmaComponents.MenuItem { - property QtObject configureAction: null - - enabled: configureAction && configureAction.enabled - visible: configureAction && configureAction.visible - - text: configureAction ? configureAction.text : "" - icon: configureAction ? configureAction.icon : "" - - onClicked: configureAction.trigger() - - Component.onCompleted: configureAction = plasmoid.action("configure") - } - - PlasmaComponents.MenuItem { - property QtObject alternativesAction: null - - enabled: alternativesAction && alternativesAction.enabled - visible: alternativesAction && alternativesAction.visible - - text: alternativesAction ? alternativesAction.text : "" - icon: alternativesAction ? alternativesAction.icon : "" - - onClicked: alternativesAction.trigger() - - Component.onCompleted: alternativesAction = plasmoid.action("alternatives") - } - } - } - - PlasmaComponents.MenuItem { separator: true } - - PlasmaComponents.MenuItem { - id: closeWindowItem - visible: (visualParent && get(atm.IsLauncher) !== true && get(atm.IsStartup) !== true) - - enabled: visualParent && get(atm.IsClosable) === true - - text: i18n("&Close") - icon: "window-close" - - onClicked: tasksModel.requestClose(modelIndex) - } -} diff --git a/Plasma/Plasma_Widgets/User/seventasks_src/src/package/contents/ui/Task.qml b/Plasma/Plasma_Widgets/User/seventasks_src/src/package/contents/ui/Task.qml index 6d08a16..7d91674 100755 --- a/Plasma/Plasma_Widgets/User/seventasks_src/src/package/contents/ui/Task.qml +++ b/Plasma/Plasma_Widgets/User/seventasks_src/src/package/contents/ui/Task.qml @@ -58,6 +58,7 @@ MouseArea { property real taskHeight: 0 property string previousState: "" property bool rightClickDragging: false + property bool toolTipOpen: false property Item audioStreamOverlay property var audioStreams: [] @@ -153,6 +154,7 @@ MouseArea { } hoverEnabled = true; taskList.updateHoverFunc(); + toolTipArea.tooltipClicked = true; } onContainsMouseChanged: { @@ -176,6 +178,7 @@ MouseArea { hoverEnabled = true; updateMousePosition(ma.mouseX); + toolTipArea.tooltipClicked = true; } @@ -226,8 +229,11 @@ MouseArea { if (plasmoid.configuration.showToolTips && toolTipArea.active) { hideToolTipTemporarily(); } + /*if(childCount >= 2 && plasmoid.configuration.showToolTips && toolTipArea.active) { + toolTipArea.tooltipClicked = !toolTipArea.tooltipClicked; + }*/ TaskTools.activateTask(modelIndex(), model, mouse.modifiers, task); - + } else if (mouse.button === Qt.BackButton || mouse.button === Qt.ForwardButton) { var sourceName = mpris2Source.sourceNameForLauncherUrl(model.LauncherUrlWithoutIcon, model.AppPid); if (sourceName) { @@ -452,7 +458,7 @@ MouseArea { opacity: 0.6 visible: childCount >= 3 ? true : false anchors.rightMargin: PlasmaCore.Units.smallSpacing - enabledBorders: Plasma.FrameSvg.EnabledBorders.RightBorder + enabledBorders: PlasmaCore.FrameSvg.RightBorder } @@ -711,8 +717,8 @@ MouseArea { PlasmaCore.ToolTipArea { id: toolTipArea z: -1 - //backgroundHints: "SolidBackground" - MouseArea { + + MouseArea { id: ma hoverEnabled: true propagateComposedEvents: true @@ -720,34 +726,32 @@ MouseArea { onPositionChanged: { task.updateMousePosition(ma.mouseX); task.positionChanged(mouse); - //var xtr = toolTipArea.backgroundHints(); - } onContainsMouseChanged: { - task.updateMousePosition(ma.mouseX); - //task.onContainsMouseChanged(); - //toolTipArea.onContainsMouseChanged(); - //mouse.accepted = false; } onPressed: mouse.accepted = false; onReleased: mouse.accepted = false; onWheel: wheel.accepted = false; - //onExited: { hoverGradient.horizontalOffset = 0; - //task.onExited(); - //} } anchors.fill: parent location: plasmoid.location - - active: !inPopup && !groupDialog.visible && plasmoid.configuration.showToolTips + property bool tooltipClicked: true + active: !inPopup && !groupDialog.visible && (plasmoid.configuration.showToolTips || tasks.toolTipOpenedByClick === toolTipArea) interactive: model.IsWindow === true mainItem: (model.IsWindow === true) ? openWindowToolTipDelegate : pinnedAppToolTipDelegate property alias mainToolTip: toolTipArea.mainItem + onToolTipVisibleChanged: { + task.toolTipOpen = toolTipVisible; + if(!toolTipVisible) { + tasks.toolTipOpenedByClick = null; + } else { + tasks.toolTipAreaItem = toolTipArea; + } + } onContainsMouseChanged: { - updateMousePosition(ma.mouseX); if (containsMouse) { mainItem.parentTask = task; @@ -802,6 +806,9 @@ MouseArea { mainItem.smartLauncherCount = Qt.binding(function() { return mainItem.smartLauncherCountVisible ? task.smartLauncherItem.count : 0; }); + tasks.toolTipAreaItem = toolTipArea; + } else { + tasks.toolTipOpenedByClick = null; } } } diff --git a/Plasma/Plasma_Widgets/User/seventasks_src/src/package/contents/ui/code/tools.js b/Plasma/Plasma_Widgets/User/seventasks_src/src/package/contents/ui/code/tools.js index e672436..5816e75 100755 --- a/Plasma/Plasma_Widgets/User/seventasks_src/src/package/contents/ui/code/tools.js +++ b/Plasma/Plasma_Widgets/User/seventasks_src/src/package/contents/ui/code/tools.js @@ -148,7 +148,11 @@ function activateTask(index, model, modifiers, task) { else if (plasmoid.configuration.showToolTips && plasmoid.configuration.groupedTaskVisualization === 1 ) { - task.showToolTip(); + if(tasks.toolTipOpenedByClick) tasks.toolTipOpenedByClick.hideImmediately(); + else { + tasks.toolTipOpenedByClick = task.toolTipAreaItem; + task.showToolTip(); + } } // Option 3: show Present Windows for all child tasks diff --git a/Plasma/Plasma_Widgets/User/seventasks_src/src/package/contents/ui/main.qml b/Plasma/Plasma_Widgets/User/seventasks_src/src/package/contents/ui/main.qml index 6ea6c6e..c8d3e4a 100755 --- a/Plasma/Plasma_Widgets/User/seventasks_src/src/package/contents/ui/main.qml +++ b/Plasma/Plasma_Widgets/User/seventasks_src/src/package/contents/ui/main.qml @@ -27,7 +27,8 @@ MouseArea { // This property tells the plasmoid to render labels next to task icons. // Previously, this property was determined by the value of (plasmoid.pluginName === "org.kde.plasma.icontasks") property bool iconsOnly: !plasmoid.configuration.labelVisible - + property var toolTipOpenedByClick: null + property var toolTipAreaItem: null //property QtObject contextMenuComponent: Qt.createComponent("ContextMenu.qml"); property QtObject tasksMenuComponent: Qt.createComponent("TasksMenu.qml"); property QtObject pulseAudioComponent: Qt.createComponent("PulseAudio.qml"); @@ -60,6 +61,7 @@ MouseArea { signal requestLayout signal windowsHovered(variant winIds, bool hovered) + signal activateWindowView(variant winIds) signal presentWindows(variant winIds) states: State { @@ -511,10 +513,12 @@ MouseArea { // With this, we can update each task icon pretty much globally. function updateHoverFunc() { for(var i = 0; i < taskRepeater.count; i++) { - taskRepeater.itemAt(i).updateHoverColor(); + if(taskRepeater.itemAt(i)) { + taskRepeater.itemAt(i).updateHoverColor(); + } } tasks.state = ""; - console.log("Updated hovers"); + //console.log("Updated hovers"); } Timer { @@ -604,7 +608,8 @@ MouseArea { tasks.requestLayout.connect(layoutTimer.restart); tasks.requestLayout.connect(iconGeometryTimer.restart); tasks.windowsHovered.connect(backend.windowsHovered); - tasks.presentWindows.connect(backend.presentWindows); + //tasks.presentWindows.connect(backend.presentWindows); + tasks.activateWindowView.connect(backend.activateWindowView); dragHelper.dropped.connect(resetDragSource); taskList.updateHoverFunc(); } diff --git a/README.md b/README.md index 36b743e..3a62ebe 100755 --- a/README.md +++ b/README.md @@ -86,6 +86,7 @@ Lastly, feel free to fork this project and/or contribute to it in any way. Any a + ### Clock diff --git a/Screenshots/Taskbar_3.png b/Screenshots/Taskbar_3.png new file mode 100644 index 0000000..6d70b6a Binary files /dev/null and b/Screenshots/Taskbar_3.png differ