quickshell: hover-to-switch between active dropdowns

When a dropdown is open, hovering another bar icon (clock,
network, battery, tray) instantly switches to that dropdown.
Also handles cancelling a close animation to reopen.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
rope 2026-05-26 17:26:44 +01:00
parent 1d45734a04
commit 53c9abb11a

View file

@ -469,12 +469,18 @@ in
if (dd.visible && !dd.closing) {
dd.animateClose();
activeDropdown = null;
} else if (!dd.visible) {
} else {
if (activeDropdown && activeDropdown !== dd && activeDropdown.visible) {
activeDropdown.animateClose();
}
if (setupFn) setupFn();
dd.visible = true;
if (dd.closing) {
// Cancel close animation, reopen
dd.closing = false;
dd.open = true;
} else {
dd.visible = true;
}
activeDropdown = dd;
}
}
@ -539,9 +545,9 @@ in
MouseArea {
anchors.fill: parent
onClicked: {
bar.toggleDropdown(calPopup);
}
hoverEnabled: true
onClicked: bar.toggleDropdown(calPopup)
onEntered: { if (bar.activeDropdown && bar.activeDropdown !== calPopup) bar.toggleDropdown(calPopup); }
}
}
@ -659,16 +665,20 @@ in
}
function openNetDropdown() {
bar.toggleDropdown(netDropdown, function() {
netWidget.wifiNetworks = [];
wifiScanProc.running = true;
let pos = netWidget.mapToItem(bar.contentItem, netWidget.width / 2, 0);
netDropdown.dropdownX = pos.x;
});
}
MouseArea {
anchors.fill: parent
onClicked: {
bar.toggleDropdown(netDropdown, function() {
netWidget.wifiNetworks = [];
wifiScanProc.running = true;
let pos = netWidget.mapToItem(bar.contentItem, netWidget.width / 2, 0);
netDropdown.dropdownX = pos.x;
});
}
hoverEnabled: true
onClicked: netWidget.openNetDropdown()
onEntered: { if (bar.activeDropdown && bar.activeDropdown !== netDropdown) netWidget.openNetDropdown(); }
}
}
@ -787,16 +797,20 @@ in
}
}
function openBatteryDropdown() {
bar.toggleDropdown(batteryDropdown, function() {
batteryProc.running = true;
profileProc.running = true;
let pos = batteryWidget.mapToItem(bar.contentItem, batteryWidget.width / 2, 0);
batteryDropdown.dropdownX = pos.x;
});
}
MouseArea {
anchors.fill: parent
onClicked: {
bar.toggleDropdown(batteryDropdown, function() {
batteryProc.running = true;
profileProc.running = true;
let pos = batteryWidget.mapToItem(bar.contentItem, batteryWidget.width / 2, 0);
batteryDropdown.dropdownX = pos.x;
});
}
hoverEnabled: true
onClicked: batteryWidget.openBatteryDropdown()
onEntered: { if (bar.activeDropdown && bar.activeDropdown !== batteryDropdown) batteryWidget.openBatteryDropdown(); }
}
}
''}
@ -835,6 +849,7 @@ in
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
hoverEnabled: true
onClicked: (event) => {
if (event.button === Qt.RightButton && modelData.hasMenu) {
bar.toggleDropdown(contextMenu, function() {
@ -847,6 +862,16 @@ in
modelData.activate();
}
}
onEntered: {
if (bar.activeDropdown && modelData.hasMenu) {
bar.toggleDropdown(contextMenu, function() {
let pos = parent.mapToItem(bar.contentItem, parent.width / 2, 0);
contextMenu.dropdownX = pos.x;
contextMenu.trayItem = modelData;
menuOpener.menu = modelData.menu;
});
}
}
}
}
}