mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
Merge pull request #1991 from tmarti2/workspace-show-app-hover
Show workspace applications on hover
This commit is contained in:
@@ -69,6 +69,7 @@ Item {
|
||||
|
||||
// Grouped mode (show applications) settings
|
||||
readonly property bool showApplications: (widgetSettings.showApplications !== undefined) ? widgetSettings.showApplications : widgetMetadata.showApplications
|
||||
readonly property bool showApplicationsHover: (widgetSettings.showApplicationsHover !== undefined) ? widgetSettings.showApplicationsHover : widgetMetadata.showApplicationsHover
|
||||
readonly property bool showLabelsOnlyWhenOccupied: (widgetSettings.showLabelsOnlyWhenOccupied !== undefined) ? widgetSettings.showLabelsOnlyWhenOccupied : widgetMetadata.showLabelsOnlyWhenOccupied
|
||||
readonly property bool colorizeIcons: (widgetSettings.colorizeIcons !== undefined) ? widgetSettings.colorizeIcons : widgetMetadata.colorizeIcons
|
||||
readonly property real unfocusedIconsOpacity: (widgetSettings.unfocusedIconsOpacity !== undefined) ? widgetSettings.unfocusedIconsOpacity : widgetMetadata.unfocusedIconsOpacity
|
||||
@@ -106,7 +107,6 @@ Item {
|
||||
}
|
||||
|
||||
property bool isDestroying: false
|
||||
property bool hovered: false
|
||||
|
||||
// Revision counter to force icon re-evaluation
|
||||
property int iconRevision: 0
|
||||
@@ -128,8 +128,34 @@ Item {
|
||||
|
||||
signal workspaceChanged(int workspaceId, color accentColor)
|
||||
|
||||
implicitWidth: showApplications ? (isVertical ? groupedGrid.implicitWidth : Math.round(groupedGrid.implicitWidth + horizontalPadding * hasLabel)) : (isVertical ? barHeight : computeWidth())
|
||||
implicitHeight: showApplications ? (isVertical ? Math.round(groupedGrid.implicitHeight + horizontalPadding * 0.6 * hasLabel) : barHeight) : (isVertical ? computeHeight() : barHeight)
|
||||
property bool isHovered: false
|
||||
|
||||
HoverHandler {
|
||||
id: workspaceHoverHandler
|
||||
enabled: showApplications && showApplicationsHover
|
||||
onHoveredChanged: {
|
||||
if(hovered) {
|
||||
hoverEval.stop();
|
||||
isHovered = true;
|
||||
} else {
|
||||
hoverEval.restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: hoverEval
|
||||
interval: 150
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
isHovered = workspaceHoverHandler.hovered || contextMenu.visible;
|
||||
}
|
||||
}
|
||||
|
||||
readonly property bool appVisible: showApplications && (!showApplicationsHover || root.isHovered)
|
||||
|
||||
implicitWidth: appVisible ? (isVertical ? groupedGrid.implicitWidth : Math.round(groupedGrid.implicitWidth + horizontalPadding * hasLabel)) : (isVertical ? barHeight : computeWidth())
|
||||
implicitHeight: appVisible ? (isVertical ? Math.round(groupedGrid.implicitHeight + horizontalPadding * 0.6 * hasLabel) : barHeight) : (isVertical ? computeHeight() : barHeight)
|
||||
|
||||
function getWorkspaceWidth(ws, activeOverride) {
|
||||
const d = Math.round(capsuleHeight * root.baseDimensionRatio);
|
||||
@@ -258,7 +284,11 @@ Item {
|
||||
onScreenChanged: Qt.callLater(refreshWorkspaces)
|
||||
onScreenNameChanged: Qt.callLater(refreshWorkspaces)
|
||||
onHideUnoccupiedChanged: Qt.callLater(refreshWorkspaces)
|
||||
onShowApplicationsChanged: Qt.callLater(refreshWorkspaces)
|
||||
onAppVisibleChanged: {
|
||||
if (appVisible) {
|
||||
Qt.callLater(refreshWorkspaces)
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: CompositorService
|
||||
@@ -266,13 +296,13 @@ Item {
|
||||
refreshWorkspaces();
|
||||
}
|
||||
function onWindowListChanged() {
|
||||
if (showApplications || showLabelsOnlyWhenOccupied) {
|
||||
if (appVisible || showLabelsOnlyWhenOccupied) {
|
||||
root.windowRevision++;
|
||||
refreshWorkspaces();
|
||||
}
|
||||
}
|
||||
function onActiveWindowChanged() {
|
||||
if (showApplications) {
|
||||
if (appVisible) {
|
||||
root.windowRevision++;
|
||||
refreshWorkspaces();
|
||||
}
|
||||
@@ -410,6 +440,15 @@ Item {
|
||||
NPopupContextMenu {
|
||||
id: contextMenu
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
hoverEval.stop();
|
||||
root.isHovered = true;
|
||||
} else {
|
||||
hoverEval.restart();
|
||||
}
|
||||
}
|
||||
|
||||
model: {
|
||||
var items = [];
|
||||
if (root.selectedWindowId) {
|
||||
@@ -486,7 +525,7 @@ Item {
|
||||
|
||||
Rectangle {
|
||||
id: workspaceBackground
|
||||
visible: !showApplications
|
||||
visible: !appVisible
|
||||
width: isVertical ? capsuleHeight : parent.width
|
||||
height: isVertical ? parent.height : capsuleHeight
|
||||
radius: Style.radiusM
|
||||
@@ -557,7 +596,15 @@ Item {
|
||||
spacing: spacingBetweenPills
|
||||
x: horizontalPadding
|
||||
y: 0
|
||||
visible: !isVertical && !showApplications
|
||||
visible: !isVertical && !appVisible
|
||||
scale: visible ? 1.0 : 0.8
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
easing.type: Easing.OutBack
|
||||
easing.overshoot: 1.2
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: workspaceRepeaterHorizontal
|
||||
@@ -592,7 +639,15 @@ Item {
|
||||
spacing: spacingBetweenPills
|
||||
x: 0
|
||||
y: horizontalPadding
|
||||
visible: isVertical && !showApplications
|
||||
visible: isVertical && !appVisible
|
||||
scale : visible ? 1.0 : 0.8
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
easing.type: Easing.OutBack
|
||||
easing.overshoot: 1.2
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: workspaceRepeaterVertical
|
||||
@@ -622,7 +677,7 @@ Item {
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// Grouped mode (showApplications = true)
|
||||
// Grouped mode (appVisible = true)
|
||||
// ========================================
|
||||
Component {
|
||||
id: groupedWorkspaceDelegate
|
||||
@@ -655,11 +710,15 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: groupHoverHandler
|
||||
}
|
||||
|
||||
width: Style.toOdd((hasWindows ? groupedIconsFlow.implicitWidth : root.iconSize) + (root.isVertical ? (root.baseItemSize - root.iconSize + Style.marginXS) : Style.marginXL))
|
||||
height: Style.toOdd((hasWindows ? groupedIconsFlow.implicitHeight : root.iconSize) + (root.isVertical ? Style.marginL : (root.baseItemSize - root.iconSize + Style.marginXS)))
|
||||
color: Style.capsuleColor
|
||||
radius: Style.radiusS
|
||||
border.color: Settings.data.bar.showOutline ? Style.capsuleBorderColor : Qt.alpha((workspaceModel.isFocused ? Color.mPrimary : Color.mOutline), root.groupedBorderOpacity)
|
||||
border.color: Settings.data.bar.showOutline ? Style.capsuleBorderColor : Qt.alpha((workspaceModel.isFocused ? Color.mPrimary : (groupHoverHandler.hovered ? Color.mHover : Color.mOutline)), root.groupedBorderOpacity)
|
||||
border.width: Style.borderS
|
||||
|
||||
Behavior on width {
|
||||
@@ -712,16 +771,19 @@ Item {
|
||||
delegate: Item {
|
||||
id: groupedTaskbarItem
|
||||
|
||||
property bool itemHovered: false
|
||||
|
||||
width: root.iconSize
|
||||
height: root.iconSize
|
||||
|
||||
HoverHandler {
|
||||
id: windowHoverHandler
|
||||
}
|
||||
|
||||
IconImage {
|
||||
id: groupedAppIcon
|
||||
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
source: {
|
||||
root.iconRevision; // Force re-evaluation when revision changes
|
||||
return ThemeIcons.iconForAppId(modelData.appId?.toLowerCase());
|
||||
@@ -733,13 +795,13 @@ Item {
|
||||
|
||||
Rectangle {
|
||||
id: groupedFocusIndicator
|
||||
visible: modelData.isFocused
|
||||
visible: modelData.isFocused || windowHoverHandler.hovered
|
||||
anchors.bottomMargin: -2
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: Style.toOdd(root.iconSize * 0.25)
|
||||
height: 4
|
||||
color: Color.mPrimary
|
||||
color: modelData.isFocused ? Color.mPrimary : Color.mHover
|
||||
radius: Math.min(Style.radiusXXS, width / 2)
|
||||
}
|
||||
|
||||
@@ -773,11 +835,9 @@ Item {
|
||||
}
|
||||
}
|
||||
onEntered: {
|
||||
groupedTaskbarItem.itemHovered = true;
|
||||
TooltipService.show(groupedTaskbarItem, modelData.title || modelData.appId || "Unknown app.", BarService.getTooltipDirection(root.screenName));
|
||||
}
|
||||
onExited: {
|
||||
groupedTaskbarItem.itemHovered = false;
|
||||
TooltipService.hide();
|
||||
}
|
||||
}
|
||||
@@ -906,7 +966,15 @@ Item {
|
||||
|
||||
Flow {
|
||||
id: groupedGrid
|
||||
visible: showApplications
|
||||
visible: appVisible
|
||||
scale: visible ? 1.0 : 0.8
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
easing.type: Easing.OutBack
|
||||
easing.overshoot: 1.2
|
||||
}
|
||||
}
|
||||
|
||||
x: root.isVertical ? Style.pixelAlignCenter(parent.width, width) : Math.round(horizontalPadding * root.hasLabel)
|
||||
y: root.isVertical ? Math.round(horizontalPadding * 0.4 * root.hasLabel) : Style.pixelAlignCenter(parent.height, height)
|
||||
@@ -915,7 +983,7 @@ Item {
|
||||
flow: root.isVertical ? Flow.TopToBottom : Flow.LeftToRight
|
||||
|
||||
Repeater {
|
||||
model: showApplications ? localWorkspaces : null
|
||||
model: appVisible ? localWorkspaces : null
|
||||
delegate: groupedWorkspaceDelegate
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ ColumnLayout {
|
||||
|
||||
// Grouped mode settings
|
||||
property bool valueShowApplications: widgetData.showApplications !== undefined ? widgetData.showApplications : widgetMetadata.showApplications
|
||||
property bool valueShowApplicationsHover: widgetData.showApplicationsHover !== undefined ? widgetData.showApplicationsHover : widgetMetadata.showApplicationsHover
|
||||
property bool valueShowLabelsOnlyWhenOccupied: widgetData.showLabelsOnlyWhenOccupied !== undefined ? widgetData.showLabelsOnlyWhenOccupied : widgetMetadata.showLabelsOnlyWhenOccupied
|
||||
property bool valueColorizeIcons: widgetData.colorizeIcons !== undefined ? widgetData.colorizeIcons : widgetMetadata.colorizeIcons
|
||||
property real valueUnfocusedIconsOpacity: widgetData.unfocusedIconsOpacity !== undefined ? widgetData.unfocusedIconsOpacity : widgetMetadata.unfocusedIconsOpacity
|
||||
@@ -42,6 +43,7 @@ ColumnLayout {
|
||||
settings.characterCount = valueCharacterCount;
|
||||
settings.followFocusedScreen = valueFollowFocusedScreen;
|
||||
settings.showApplications = valueShowApplications;
|
||||
settings.showApplicationsHover = valueShowApplicationsHover;
|
||||
settings.showLabelsOnlyWhenOccupied = valueShowLabelsOnlyWhenOccupied;
|
||||
settings.colorizeIcons = valueColorizeIcons;
|
||||
settings.unfocusedIconsOpacity = valueUnfocusedIconsOpacity;
|
||||
@@ -201,6 +203,17 @@ ColumnLayout {
|
||||
}
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: I18n.tr("bar.workspace.show-applications-hover-label")
|
||||
description: I18n.tr("bar.workspace.show-applications-hover-description")
|
||||
checked: valueShowApplicationsHover
|
||||
onToggled: checked => {
|
||||
valueShowApplicationsHover = checked;
|
||||
saveSettings();
|
||||
}
|
||||
visible: valueShowApplications
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: I18n.tr("bar.workspace.show-badge-label")
|
||||
description: I18n.tr("bar.workspace.show-badge-description")
|
||||
|
||||
Reference in New Issue
Block a user