mirror of
https://github.com/zoriya/noctalia-shell.git
synced 2026-06-05 03:30:03 +00:00
Taskbar/TaskbarGrouped: fix hyprland context menu (sort of)
This commit is contained in:
@@ -43,22 +43,26 @@ Rectangle {
|
||||
// Context menu state
|
||||
property var selectedWindow: null
|
||||
property string selectedAppName: ""
|
||||
property int modelUpdateTrigger: 0 // Dummy property to force model re-evaluation
|
||||
|
||||
NPopupContextMenu {
|
||||
id: contextMenu
|
||||
model: {
|
||||
// Reference modelUpdateTrigger to make binding reactive
|
||||
const _ = root.modelUpdateTrigger;
|
||||
|
||||
var items = [];
|
||||
if (selectedWindow) {
|
||||
if (root.selectedWindow) {
|
||||
items.push({
|
||||
"label": I18n.tr("context-menu.activate-app", {
|
||||
"app": selectedAppName
|
||||
"app": root.selectedAppName
|
||||
}),
|
||||
"action": "activate",
|
||||
"icon": "focus"
|
||||
});
|
||||
items.push({
|
||||
"label": I18n.tr("context-menu.close-app", {
|
||||
"app": selectedAppName
|
||||
"app": root.selectedAppName
|
||||
}),
|
||||
"action": "close",
|
||||
"icon": "x"
|
||||
@@ -203,6 +207,7 @@ Rectangle {
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
preventStealing: true
|
||||
|
||||
onPressed: function (mouse) {
|
||||
if (!taskbarItem.modelData)
|
||||
@@ -213,16 +218,25 @@ Rectangle {
|
||||
} catch (error) {
|
||||
Logger.e("Taskbar", "Failed to activate toplevel: " + error);
|
||||
}
|
||||
} else if (mouse.button === Qt.RightButton) {
|
||||
}
|
||||
}
|
||||
|
||||
onReleased: function (mouse) {
|
||||
if (!taskbarItem.modelData)
|
||||
return;
|
||||
if (mouse.button === Qt.RightButton) {
|
||||
mouse.accepted = true;
|
||||
TooltipService.hide();
|
||||
root.selectedWindow = taskbarItem.modelData;
|
||||
root.selectedAppName = CompositorService.getCleanAppName(taskbarItem.modelData.appId, taskbarItem.modelData.title);
|
||||
var popupMenuWindow = PanelService.getPopupMenuWindow(screen);
|
||||
if (popupMenuWindow) {
|
||||
const pos = BarService.getContextMenuPosition(taskbarItem, contextMenu.implicitWidth, contextMenu.implicitHeight);
|
||||
contextMenu.openAtItem(taskbarItem, pos.x, pos.y);
|
||||
popupMenuWindow.showContextMenu(contextMenu);
|
||||
}
|
||||
|
||||
// Store position and size for timer callback
|
||||
const globalPos = taskbarItem.mapToItem(root, 0, 0);
|
||||
contextMenuOpenTimer.globalX = globalPos.x;
|
||||
contextMenuOpenTimer.globalY = globalPos.y;
|
||||
contextMenuOpenTimer.itemWidth = taskbarItem.width;
|
||||
contextMenuOpenTimer.itemHeight = taskbarItem.height;
|
||||
contextMenuOpenTimer.restart();
|
||||
}
|
||||
}
|
||||
onEntered: TooltipService.show(taskbarItem, taskbarItem.modelData.title || taskbarItem.modelData.appId || "Unknown app.", BarService.getTooltipDirection())
|
||||
@@ -231,4 +245,71 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: contextMenuOpenTimer
|
||||
interval: 10
|
||||
repeat: false
|
||||
property real globalX: 0
|
||||
property real globalY: 0
|
||||
property real itemWidth: 0
|
||||
property real itemHeight: 0
|
||||
|
||||
onTriggered: {
|
||||
// Directly build and set model as a new array (bypass binding issues)
|
||||
var items = [];
|
||||
if (root.selectedWindow) {
|
||||
items.push({
|
||||
"label": I18n.tr("context-menu.activate-app", {
|
||||
"app": root.selectedAppName
|
||||
}),
|
||||
"action": "activate",
|
||||
"icon": "focus"
|
||||
});
|
||||
items.push({
|
||||
"label": I18n.tr("context-menu.close-app", {
|
||||
"app": root.selectedAppName
|
||||
}),
|
||||
"action": "close",
|
||||
"icon": "x"
|
||||
});
|
||||
}
|
||||
items.push({
|
||||
"label": I18n.tr("context-menu.widget-settings"),
|
||||
"action": "widget-settings",
|
||||
"icon": "settings"
|
||||
});
|
||||
|
||||
// Set the model directly
|
||||
contextMenu.model = items;
|
||||
|
||||
var popupMenuWindow = PanelService.getPopupMenuWindow(screen);
|
||||
if (popupMenuWindow) {
|
||||
popupMenuWindow.open();
|
||||
|
||||
// Calculate menu position relative to the clicked item with consistent spacing
|
||||
const barPosition = Settings.data.bar.position;
|
||||
const spacing = Style.barHeight * 0.5;
|
||||
let menuX, menuY;
|
||||
|
||||
if (barPosition === "top") {
|
||||
menuX = globalX + (itemWidth / 2) - (contextMenu.implicitWidth / 2);
|
||||
menuY = globalY + itemHeight + spacing;
|
||||
} else if (barPosition === "bottom") {
|
||||
menuX = globalX + (itemWidth / 2) - (contextMenu.implicitWidth / 2);
|
||||
menuY = globalY - contextMenu.implicitHeight - (Style.barHeight * 2);
|
||||
} else if (barPosition === "left") {
|
||||
menuX = globalX + itemWidth + spacing;
|
||||
menuY = globalY + (itemHeight / 2) - (contextMenu.implicitHeight / 2);
|
||||
} else {
|
||||
// right
|
||||
menuX = globalX - contextMenu.implicitWidth - spacing;
|
||||
menuY = globalY + (itemHeight / 2) - (contextMenu.implicitHeight / 2);
|
||||
}
|
||||
|
||||
contextMenu.openAtItem(root, menuX, menuY);
|
||||
popupMenuWindow.contentItem = contextMenu;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ Item {
|
||||
// Context menu state
|
||||
property var selectedWindow: null
|
||||
property string selectedAppName: ""
|
||||
property int modelUpdateTrigger: 0 // Dummy property to force model re-evaluation
|
||||
|
||||
function refreshWorkspaces() {
|
||||
localWorkspaces.clear();
|
||||
@@ -167,18 +168,21 @@ Item {
|
||||
id: contextMenu
|
||||
|
||||
model: {
|
||||
// Reference modelUpdateTrigger to make binding reactive
|
||||
const _ = root.modelUpdateTrigger;
|
||||
|
||||
var items = [];
|
||||
if (selectedWindow) {
|
||||
if (root.selectedWindow) {
|
||||
items.push({
|
||||
"label": I18n.tr("context-menu.activate-app", {
|
||||
"app": selectedAppName
|
||||
"app": root.selectedAppName
|
||||
}),
|
||||
"action": "activate",
|
||||
"icon": "focus"
|
||||
});
|
||||
items.push({
|
||||
"label": I18n.tr("context-menu.close-app", {
|
||||
"app": selectedAppName
|
||||
"app": root.selectedAppName
|
||||
}),
|
||||
"action": "close",
|
||||
"icon": "x"
|
||||
@@ -273,21 +277,28 @@ Item {
|
||||
enabled: !hasWindows
|
||||
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
preventStealing: true
|
||||
onPressed: mouse => {
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
CompositorService.switchToWorkspace(workspaceModel);
|
||||
} else if (mouse.button === Qt.RightButton) {
|
||||
TooltipService.hide();
|
||||
root.selectedWindow = "";
|
||||
root.selectedAppName = "";
|
||||
var popupMenuWindow = PanelService.getPopupMenuWindow(screen);
|
||||
if (popupMenuWindow) {
|
||||
const pos = BarService.getContextMenuPosition(container, contextMenu.implicitWidth, contextMenu.implicitHeight);
|
||||
contextMenu.openAtItem(container, pos.x, pos.y);
|
||||
popupMenuWindow.showContextMenu(contextMenu);
|
||||
}
|
||||
}
|
||||
}
|
||||
onReleased: mouse => {
|
||||
if (mouse.button === Qt.RightButton) {
|
||||
mouse.accepted = true;
|
||||
TooltipService.hide();
|
||||
root.selectedWindow = "";
|
||||
root.selectedAppName = "";
|
||||
|
||||
// Store position and size for timer callback
|
||||
const globalPos = container.mapToItem(root, 0, 0);
|
||||
contextMenuOpenTimer1.globalX = globalPos.x;
|
||||
contextMenuOpenTimer1.globalY = globalPos.y;
|
||||
contextMenuOpenTimer1.itemWidth = container.width;
|
||||
contextMenuOpenTimer1.itemHeight = container.height;
|
||||
contextMenuOpenTimer1.restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Flow {
|
||||
@@ -359,6 +370,7 @@ Item {
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
preventStealing: true
|
||||
|
||||
onPressed: mouse => {
|
||||
if (!model) {
|
||||
@@ -367,18 +379,29 @@ Item {
|
||||
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
CompositorService.focusWindow(model);
|
||||
} else if (mouse.button === Qt.RightButton) {
|
||||
TooltipService.hide();
|
||||
root.selectedWindow = model;
|
||||
root.selectedAppName = CompositorService.getCleanAppName(model.appId, model.title);
|
||||
var popupMenuWindow = PanelService.getPopupMenuWindow(screen);
|
||||
if (popupMenuWindow) {
|
||||
const pos = BarService.getContextMenuPosition(taskbarItem, contextMenu.implicitWidth, contextMenu.implicitHeight);
|
||||
contextMenu.openAtItem(taskbarItem, pos.x, pos.y);
|
||||
popupMenuWindow.showContextMenu(contextMenu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onReleased: mouse => {
|
||||
if (!model) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mouse.button === Qt.RightButton) {
|
||||
mouse.accepted = true;
|
||||
TooltipService.hide();
|
||||
root.selectedWindow = model;
|
||||
root.selectedAppName = CompositorService.getCleanAppName(model.appId, model.title);
|
||||
|
||||
// Store position and size for timer callback
|
||||
const globalPos = taskbarItem.mapToItem(root, 0, 0);
|
||||
contextMenuOpenTimer2.globalX = globalPos.x;
|
||||
contextMenuOpenTimer2.globalY = globalPos.y;
|
||||
contextMenuOpenTimer2.itemWidth = taskbarItem.width;
|
||||
contextMenuOpenTimer2.itemHeight = taskbarItem.height;
|
||||
contextMenuOpenTimer2.restart();
|
||||
}
|
||||
}
|
||||
onEntered: {
|
||||
taskbarItem.itemHovered = true;
|
||||
TooltipService.show(taskbarItem, model.title || model.appId || "Unknown app.", BarService.getTooltipDirection());
|
||||
@@ -533,4 +556,138 @@ Item {
|
||||
delegate: workspaceRepeaterDelegate
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: contextMenuOpenTimer1
|
||||
interval: 10
|
||||
repeat: false
|
||||
property real globalX: 0
|
||||
property real globalY: 0
|
||||
property real itemWidth: 0
|
||||
property real itemHeight: 0
|
||||
|
||||
onTriggered: {
|
||||
// Directly build and set model as a new array (bypass binding issues)
|
||||
var items = [];
|
||||
if (root.selectedWindow) {
|
||||
items.push({
|
||||
"label": I18n.tr("context-menu.activate-app", {
|
||||
"app": root.selectedAppName
|
||||
}),
|
||||
"action": "activate",
|
||||
"icon": "focus"
|
||||
});
|
||||
items.push({
|
||||
"label": I18n.tr("context-menu.close-app", {
|
||||
"app": root.selectedAppName
|
||||
}),
|
||||
"action": "close",
|
||||
"icon": "x"
|
||||
});
|
||||
}
|
||||
items.push({
|
||||
"label": I18n.tr("context-menu.widget-settings"),
|
||||
"action": "widget-settings",
|
||||
"icon": "settings"
|
||||
});
|
||||
|
||||
// Set the model directly
|
||||
contextMenu.model = items;
|
||||
|
||||
var popupMenuWindow = PanelService.getPopupMenuWindow(screen);
|
||||
if (popupMenuWindow) {
|
||||
popupMenuWindow.open();
|
||||
|
||||
// Calculate menu position relative to the clicked item with consistent spacing
|
||||
const barPosition = Settings.data.bar.position;
|
||||
const spacing = Style.barHeight * 0.5;
|
||||
let menuX, menuY;
|
||||
|
||||
if (barPosition === "top") {
|
||||
menuX = globalX + (itemWidth / 2) - (contextMenu.implicitWidth / 2);
|
||||
menuY = globalY + itemHeight + spacing;
|
||||
} else if (barPosition === "bottom") {
|
||||
menuX = globalX + (itemWidth / 2) - (contextMenu.implicitWidth / 2);
|
||||
menuY = globalY - contextMenu.implicitHeight - (Style.barHeight * 2);
|
||||
} else if (barPosition === "left") {
|
||||
menuX = globalX + itemWidth + spacing;
|
||||
menuY = globalY + (itemHeight / 2) - (contextMenu.implicitHeight / 2);
|
||||
} else {
|
||||
// right
|
||||
menuX = globalX - contextMenu.implicitWidth - spacing;
|
||||
menuY = globalY + (itemHeight / 2) - (contextMenu.implicitHeight / 2);
|
||||
}
|
||||
|
||||
contextMenu.openAtItem(root, menuX, menuY);
|
||||
popupMenuWindow.contentItem = contextMenu;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: contextMenuOpenTimer2
|
||||
interval: 10
|
||||
repeat: false
|
||||
property real globalX: 0
|
||||
property real globalY: 0
|
||||
property real itemWidth: 0
|
||||
property real itemHeight: 0
|
||||
|
||||
onTriggered: {
|
||||
// Directly build and set model as a new array (bypass binding issues)
|
||||
var items = [];
|
||||
if (root.selectedWindow) {
|
||||
items.push({
|
||||
"label": I18n.tr("context-menu.activate-app", {
|
||||
"app": root.selectedAppName
|
||||
}),
|
||||
"action": "activate",
|
||||
"icon": "focus"
|
||||
});
|
||||
items.push({
|
||||
"label": I18n.tr("context-menu.close-app", {
|
||||
"app": root.selectedAppName
|
||||
}),
|
||||
"action": "close",
|
||||
"icon": "x"
|
||||
});
|
||||
}
|
||||
items.push({
|
||||
"label": I18n.tr("context-menu.widget-settings"),
|
||||
"action": "widget-settings",
|
||||
"icon": "settings"
|
||||
});
|
||||
|
||||
// Set the model directly
|
||||
contextMenu.model = items;
|
||||
|
||||
var popupMenuWindow = PanelService.getPopupMenuWindow(screen);
|
||||
if (popupMenuWindow) {
|
||||
popupMenuWindow.open();
|
||||
|
||||
// Calculate menu position relative to the clicked item with consistent spacing
|
||||
const barPosition = Settings.data.bar.position;
|
||||
const spacing = Style.barHeight * 0.5;
|
||||
let menuX, menuY;
|
||||
|
||||
if (barPosition === "top") {
|
||||
menuX = globalX + (itemWidth / 2) - (contextMenu.implicitWidth / 2);
|
||||
menuY = globalY + itemHeight + spacing;
|
||||
} else if (barPosition === "bottom") {
|
||||
menuX = globalX + (itemWidth / 2) - (contextMenu.implicitWidth / 2);
|
||||
menuY = globalY - contextMenu.implicitHeight - (Style.barHeight * 2);
|
||||
} else if (barPosition === "left") {
|
||||
menuX = globalX + itemWidth + spacing;
|
||||
menuY = globalY + (itemHeight / 2) - (contextMenu.implicitHeight / 2);
|
||||
} else {
|
||||
// right
|
||||
menuX = globalX - contextMenu.implicitWidth - spacing;
|
||||
menuY = globalY + (itemHeight / 2) - (contextMenu.implicitHeight / 2);
|
||||
}
|
||||
|
||||
contextMenu.openAtItem(root, menuX, menuY);
|
||||
popupMenuWindow.contentItem = contextMenu;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user