2025-05-09 09:48:24 +02:00

831 lines
30 KiB
JavaScript

import Clutter from 'gi://Clutter';
import GLib from 'gi://GLib';
import GObject from 'gi://GObject';
import Graphene from 'gi://Graphene';
import Shell from 'gi://Shell';
import St from 'gi://St';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import * as PanelMenu from 'resource:///org/gnome/shell/ui/panelMenu.js';
import * as PointerWatcher from 'resource:///org/gnome/shell/ui/pointerWatcher.js';
import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js';
import * as SystemActions from 'resource:///org/gnome/shell/misc/systemActions.js';
import {ArcMenuManager} from './arcmenuManager.js';
import * as Constants from './constants.js';
import * as LayoutHandler from './menulayouts/layoutHandler.js';
import * as MW from './menuWidgets.js';
import * as Utils from './utils.js';
import {Extension, gettext as _} from 'resource:///org/gnome/shell/extensions/extension.js';
class MenuButtonWidget extends St.BoxLayout {
static {
GObject.registerClass(this);
}
constructor() {
super({
style_class: 'panel-status-menu-box',
});
this._icon = new St.Icon({
style_class: 'arcmenu-menu-button',
track_hover: true,
reactive: true,
});
this._label = new St.Label({
text: _('Apps'),
y_expand: true,
style_class: 'arcmenu-menu-button',
y_align: Clutter.ActorAlign.CENTER,
});
this.add_child(this._icon);
this.add_child(this._label);
}
addStylePseudoClass(style) {
this._icon.add_style_pseudo_class(style);
this._label.add_style_pseudo_class(style);
}
removeStylePseudoClass(style) {
this._icon.remove_style_pseudo_class(style);
this._label.remove_style_pseudo_class(style);
}
showIcon() {
this._icon.show();
this._label.hide();
this.set_child_at_index(this._icon, 0);
}
showText() {
this._icon.hide();
this._label.show();
this.set_child_at_index(this._label, 0);
}
showIconText() {
this._icon.show();
this._label.show();
this.set_child_at_index(this._icon, 0);
}
showTextIcon() {
this._icon.show();
this._label.show();
this.set_child_at_index(this._label, 0);
}
getPanelLabel() {
return this._label;
}
getPanelIcon() {
return this._icon;
}
setLabelStyle(style) {
this._label.style = style;
}
}
export const MenuButton = GObject.registerClass(
class ArcMenuMenuButton extends PanelMenu.Button {
_init(panelInfo, monitorIndex) {
super._init(0.5, null, true);
this.set({
x_expand: false,
});
this.add_style_class_name('arcmenu-panel-menu');
// Link search providers to this menu
this.searchProviderDisplayId = `ArcMenu_${monitorIndex}`;
this._panel = panelInfo.panel;
this._panelBox = panelInfo.panelBox;
this._panelParent = panelInfo.panelParent;
this._monitorIndex = monitorIndex;
this.menu.destroy();
this.menu = null;
this.tooltipShowing = false;
this.tooltipShowingID = null;
this.tooltip = new MW.Tooltip(this);
this._dtpNeedsRelease = false;
// Create Main Menus - ArcMenu and ArcMenu's context menu
this.arcMenu = new ArcMenu(this, 0.5, St.Side.TOP);
this.arcMenu.connectObject('open-state-changed', this._onOpenStateChanged.bind(this), this);
this.arcMenuContextMenu = new ArcMenuContextMenu(this, 0.5, St.Side.TOP);
this.arcMenuContextMenu.connectObject('open-state-changed', this._onOpenStateChanged.bind(this), this);
this.menuManager = new PopupMenu.PopupMenuManager();
this.menuManager._changeMenu = () => {};
this.menuManager.addMenu(this.arcMenu);
this.menuManager.addMenu(this.arcMenuContextMenu);
// Context Menus for applications and other menu items
this.contextMenuManager = new PopupMenu.PopupMenuManager();
this.contextMenuManager._changeMenu = () => {};
// Sub Menu Manager - Control all other popup menus
this.subMenuManager = new PopupMenu.PopupMenuManager();
this.subMenuManager._changeMenu = () => {};
this.menuButtonWidget = new MenuButtonWidget();
this.add_child(this.menuButtonWidget);
}
initiate() {
this._dtp = Main.extensionManager.lookup(Constants.DASH_TO_PANEL_UUID);
if (this._dtp?.state === Utils.ExtensionState.ACTIVE && global.dashToPanel)
this.syncWithDashToPanel();
Main.layoutManager.connectObject('monitors-changed', () => this.updateHeight(), this);
Main.layoutManager.connectObject('startup-complete', () => this.updateHeight(), this);
this.setMenuPositionAlignment();
this.createMenuLayout();
}
syncWithDashToPanel() {
const dtp = Extension.lookupByUUID(Constants.DASH_TO_PANEL_UUID);
this._dtpSettings = dtp.getSettings('org.gnome.shell.extensions.dash-to-panel');
this._dtpActive = true;
const side = this._panelParent.getPosition();
this.updateArrowSide(side);
this._dtpSettings.connectObject('changed::panel-positions', () => {
const newSide = this._panelParent.getPosition();
this.updateArrowSide(newSide);
}, this);
}
createMenuLayout() {
this._clearTooltipShowingId();
this._clearTooltip();
this._destroyMenuLayout();
const layout = ArcMenuManager.settings.get_enum('menu-layout');
this._menuLayout = LayoutHandler.createMenuLayout(this, layout);
if (this._menuLayout) {
this.arcMenu.box.add_child(this._menuLayout);
this.setMenuPositionAlignment();
this.forceMenuLocation();
this.updateHeight();
}
}
setMenuPositionAlignment() {
const layout = ArcMenuManager.settings.get_enum('menu-layout');
const arrowAlignment = 1 - (ArcMenuManager.settings.get_int('menu-position-alignment') / 100);
const panelPosition = ArcMenuManager.settings.get_enum('position-in-panel');
if (layout !== Constants.MenuLayout.RUNNER) {
if (panelPosition === Constants.MenuPosition.CENTER) {
this.arcMenuContextMenu._arrowAlignment = arrowAlignment;
this.arcMenu._arrowAlignment = arrowAlignment;
this.arcMenuContextMenu._boxPointer.setSourceAlignment(.5);
this.arcMenu._boxPointer.setSourceAlignment(.5);
} else if (this._dtpActive) {
const side = this._panelParent.getPosition();
this.updateArrowSide(side, false);
} else {
this.updateArrowSide(St.Side.TOP, false);
}
} else {
this.updateArrowSide(St.Side.TOP, false);
if (panelPosition === Constants.MenuPosition.CENTER) {
this.arcMenuContextMenu._arrowAlignment = arrowAlignment;
this.arcMenuContextMenu._boxPointer.setSourceAlignment(.5);
}
}
}
updateArrowSide(side, setAlignment = true) {
let arrowAlignment;
if (side === St.Side.RIGHT || side === St.Side.LEFT)
arrowAlignment = 1.0;
else
arrowAlignment = 0.5;
const menus = [this.arcMenu, this.arcMenuContextMenu];
for (const menu of menus) {
menu._arrowSide = side;
menu._boxPointer._arrowSide = side;
menu._boxPointer._userArrowSide = side;
menu._boxPointer.setSourceAlignment(arrowAlignment);
menu._arrowAlignment = arrowAlignment;
menu._boxPointer._border.queue_repaint();
}
if (setAlignment)
this.setMenuPositionAlignment();
}
_getDashToPanelGeom() {
if (!this._dtpActive || !this._panelParent.intellihide?.enabled)
return {width: 0, height: 0};
const dtpPostion = this._panelParent.getPosition();
const menuLocation = ArcMenuManager.settings.get_enum('force-menu-location');
const width = this._panelParent.geom?.w ?? 0;
const height = this._panelParent.geom?.h ?? 0;
const {MenuLocation} = Constants;
const topLocations = [MenuLocation.TOP_CENTERED, MenuLocation.TOP_LEFT, MenuLocation.TOP_RIGHT];
const bottomLocations = [MenuLocation.BOTTOM_CENTERED, MenuLocation.BOTTOM_LEFT, MenuLocation.BOTTOM_RIGHT];
const leftLocations = [MenuLocation.BOTTOM_LEFT, MenuLocation.TOP_LEFT, MenuLocation.LEFT_CENTERED];
const rightLocations = [MenuLocation.BOTTOM_RIGHT, MenuLocation.TOP_RIGHT, MenuLocation.RIGHT_CENTERED];
const xCenterLocations = [MenuLocation.BOTTOM_CENTERED, MenuLocation.TOP_CENTERED];
const yCenterLocations = [MenuLocation.LEFT_CENTERED, MenuLocation.RIGHT_CENTERED];
const needsTopAdjustment = topLocations.includes(menuLocation) || yCenterLocations.includes(menuLocation);
const needsBottomAdjustment = bottomLocations.includes(menuLocation) || yCenterLocations.includes(menuLocation);
const needsLeftAdjustment = leftLocations.includes(menuLocation) || xCenterLocations.includes(menuLocation);
const needsRightAdjustment = rightLocations.includes(menuLocation) || xCenterLocations.includes(menuLocation);
if (dtpPostion === St.Side.TOP && needsTopAdjustment)
return {width: 0, height};
if (dtpPostion === St.Side.BOTTOM && needsBottomAdjustment)
return {width: 0, height};
if (dtpPostion === St.Side.LEFT && needsLeftAdjustment)
return {width, height: 0};
if (dtpPostion === St.Side.RIGHT && needsRightAdjustment)
return {width, height: 0};
return {width: 0, height: 0};
}
forceMenuLocation() {
const layout = ArcMenuManager.settings.get_enum('menu-layout');
if (layout === Constants.MenuLayout.RUNNER ||
layout === Constants.MenuLayout.RAVEN ||
layout === Constants.MenuLayout.GNOME_OVERVIEW)
return;
this.arcMenu.actor.remove_style_class_name('bottomOfScreenMenu');
const newMenuLocation = ArcMenuManager.settings.get_enum('force-menu-location');
if (this._menuLocation !== newMenuLocation) {
this._menuLocation = newMenuLocation;
if (newMenuLocation === Constants.MenuLocation.OFF) {
this.arcMenu.sourceActor = this.arcMenu.focusActor = this;
this.arcMenu._boxPointer.setPosition(this, 0.5);
this.setMenuPositionAlignment();
return;
}
this.arcMenu.sourceActor = this.arcMenu.focusActor = Main.layoutManager.dummyCursor;
this.arcMenu._boxPointer.setPosition(Main.layoutManager.dummyCursor, 0.5);
this.arcMenu._boxPointer.setSourceAlignment(0.5);
this.arcMenu._arrowAlignment = 0.5;
}
if (newMenuLocation === Constants.MenuLocation.OFF)
return;
const monitor = Main.layoutManager.findMonitorForActor(this);
const workArea = Main.layoutManager.getWorkAreaForMonitor(this._monitorIndex);
const menuHeight = ArcMenuManager.settings.get_int('menu-height');
// Offset width and height of DtP when intellihide is enabled.
const {width: dtpWidth, height: dtpHeight} = this._getDashToPanelGeom();
const xLeft = workArea.x + dtpWidth;
const xRight = workArea.x + workArea.width - 1 - dtpWidth;
const yTop = workArea.y + dtpHeight;
const yBottom = workArea.y + workArea.height - 1 - dtpHeight;
const xCentered = Math.round(monitor.x + (monitor.width / 2));
const yCentered = Math.round(monitor.y + (monitor.height / 2) - (menuHeight / 2));
let x, y;
let side = St.Side.TOP;
if (newMenuLocation === Constants.MenuLocation.TOP_CENTERED) {
x = xCentered;
y = yTop;
} else if (newMenuLocation === Constants.MenuLocation.TOP_LEFT) {
side = St.Side.LEFT;
x = xLeft;
y = yTop;
} else if (newMenuLocation === Constants.MenuLocation.TOP_RIGHT) {
side = St.Side.RIGHT;
x = xRight;
y = yTop;
} else if (newMenuLocation === Constants.MenuLocation.BOTTOM_CENTERED) {
x = xCentered;
y = yBottom;
this.arcMenu.actor.add_style_class_name('bottomOfScreenMenu');
} else if (newMenuLocation === Constants.MenuLocation.BOTTOM_LEFT) {
side = St.Side.LEFT;
x = xLeft;
y = yBottom;
this.arcMenu.actor.add_style_class_name('bottomOfScreenMenu');
} else if (newMenuLocation === Constants.MenuLocation.BOTTOM_RIGHT) {
side = St.Side.RIGHT;
x = xRight;
y = yBottom;
this.arcMenu.actor.add_style_class_name('bottomOfScreenMenu');
} else if (newMenuLocation === Constants.MenuLocation.LEFT_CENTERED) {
x = xLeft;
y = yCentered;
} else if (newMenuLocation === Constants.MenuLocation.RIGHT_CENTERED) {
x = xRight;
y = yCentered;
} else if (newMenuLocation === Constants.MenuLocation.MONITOR_CENTERED) {
x = xCentered;
y = yCentered;
}
this.updateArrowSide(side, false);
Main.layoutManager.setDummyCursorGeometry(x, y, 0, 0);
}
vfunc_event(event) {
if (event.type() === Clutter.EventType.BUTTON_PRESS) {
const clickAction = this._getClickActionForButton(event.get_button());
if (clickAction === Constants.MenuButtonClickAction.ARCMENU)
this.toggleMenu();
else if (clickAction === Constants.MenuButtonClickAction.CONTEXT_MENU)
this.arcMenuContextMenu.toggle();
} else if (event.type() === Clutter.EventType.TOUCH_BEGIN) {
this.toggleMenu();
}
return Clutter.EVENT_PROPAGATE;
}
_getClickActionForButton(button) {
if (button === Clutter.BUTTON_PRIMARY)
return ArcMenuManager.settings.get_enum('menu-button-left-click-action');
else if (button === Clutter.BUTTON_SECONDARY)
return ArcMenuManager.settings.get_enum('menu-button-right-click-action');
else if (button === Clutter.BUTTON_MIDDLE)
return ArcMenuManager.settings.get_enum('menu-button-middle-click-action');
else
return -1;
}
closeOtherMenus() {
if (this.contextMenuManager.activeMenu)
this.contextMenuManager.activeMenu.toggle();
if (this.subMenuManager.activeMenu)
this.subMenuManager.activeMenu.toggle();
}
closeContextMenu() {
if (this.arcMenuContextMenu.isOpen)
this.arcMenuContextMenu.toggle();
}
toggleMenu() {
this.closeOtherMenus();
const layout = ArcMenuManager.settings.get_enum('menu-layout');
if (layout === Constants.MenuLayout.GNOME_OVERVIEW) {
if (ArcMenuManager.settings.get_boolean('gnome-dash-show-applications'))
Main.overview._overview._controls._toggleAppsPage();
else
Main.overview.toggle();
return;
}
if (!this.arcMenu.isOpen) {
if (this._menuLayout?.updateLocation)
this._menuLayout.updateLocation();
if (this._menuLayout?.updateStyle)
this._menuLayout.updateStyle();
this._maybeShowPanel();
}
this.arcMenu.toggle();
if (this.arcMenu.isOpen) {
this._menuLayout?.grab_key_focus();
this.forceMenuLocation();
}
}
updateHeight() {
if (!this._menuLayout)
return;
const layout = ArcMenuManager.settings.get_enum('menu-layout');
if (layout === Constants.MenuLayout.RUNNER || layout === Constants.MenuLayout.RAVEN) {
this._menuLayout.style = '';
return;
}
const height = ArcMenuManager.settings.get_int('menu-height');
this._menuLayout.style = `height: ${height}px;`;
}
updateWidth() {
if (this._menuLayout?.updateWidth)
this._menuLayout.updateWidth(true);
}
_clearTooltipShowingId() {
if (this.tooltipShowingID) {
GLib.source_remove(this.tooltipShowingID);
this.tooltipShowingID = null;
}
}
_clearTooltip() {
this.tooltipShowing = false;
if (this.tooltip) {
this.tooltip.hide();
this.tooltip.sourceActor = null;
}
}
_onDestroy() {
this._stopTrackingMouse();
Main.layoutManager.disconnectObject(this);
this._clearTooltipShowingId();
if (this._dtpSettings) {
this._dtpSettings.disconnectObject(this);
this._dtpSettings = null;
}
if (this.dtp)
this.dtp = null;
this._destroyMenuLayout();
this.tooltip?.destroy();
this.tooltip = null;
this.arcMenu?.destroy();
this.arcMenu = null;
this.arcMenuContextMenu?.destroy();
this.arcMenuContextMenu = null;
this.menuManager = null;
this.contextMenuManager = null;
this.subMenuManager = null;
this.menuButtonWidget.destroy();
this.menuButtonWidget = null;
this._panel.statusArea['ArcMenu'] = null;
this._panel = null;
this._panelBox = null;
this._panelParent = null;
super._onDestroy();
}
_destroyMenuLayout() {
if (this._menuLayout) {
this._menuLayout.destroy();
this._menuLayout = null;
}
}
updateLocation() {
if (this._menuLayout && this._menuLayout.updateLocation)
this._menuLayout.updateLocation();
}
getActiveCategoryType() {
return this._menuLayout?.activeCategoryType;
}
reloadApplications() {
this._menuLayout?.reloadApplications();
}
displayPinnedApps() {
this._menuLayout?.displayPinnedApps();
}
loadPinnedApps() {
this._menuLayout?.loadPinnedApps();
}
setDefaultMenuView() {
if (!this._menuLayout)
return;
if (!this._menuLayout.reloadQueued)
this._menuLayout.setDefaultMenuView();
}
_onOpenStateChanged(_menu, open) {
if (open) {
this.menuButtonWidget.addStylePseudoClass('active');
this.add_style_pseudo_class('active');
if (Main.panel.menuManager && Main.panel.menuManager.activeMenu)
Main.panel.menuManager.activeMenu.toggle();
if (!this._dtpNeedsRelease && this._panelParent.intellihide?.enabled)
this._dtpNeedsRelease = true;
} else {
if (!this.arcMenu.isOpen) {
this._clearTooltipShowingId();
this._clearTooltip();
}
if (!this.arcMenu.isOpen && !this.arcMenuContextMenu.isOpen) {
this.menuButtonWidget.removeStylePseudoClass('active');
this.remove_style_pseudo_class('active');
if (this._dtpNeedsRelease && !this._panelNeedsHiding) {
this._dtpNeedsRelease = false;
const hidePanel = () => this._panelParent.intellihide?.release(1);
const isMouseOnPanel = this._isMouseOnPanel();
if (isMouseOnPanel)
this._startTrackingMouse(hidePanel);
else
hidePanel();
}
if (this._panelNeedsHiding) {
this._panelNeedsHiding = false;
// Hide panel if monitor inFullscreen, else show it
const hidePanel = () => {
const monitor = Main.layoutManager.findMonitorForActor(this);
this._panelBox.visible = !(global.window_group.visible &&
monitor &&
monitor.inFullscreen);
};
const isMouseOnPanel = this._isMouseOnPanel();
if (isMouseOnPanel)
this._startTrackingMouse(hidePanel);
else
hidePanel();
}
}
}
}
_maybeShowPanel() {
if (this._panelParent.intellihide && this._panelParent.intellihide.enabled) {
this._panelParent.intellihide._revealPanel(true);
this._panelParent.intellihide.revealAndHold(1);
} else if (!this._panelBox.visible) {
this._panelBox.visible = true;
this._panelNeedsHiding = true;
}
}
_isMouseOnPanel() {
const [x, y] = global.get_pointer();
const mouseOnPanel = this._panelHasMousePointer(x, y);
if (mouseOnPanel)
return true;
return false;
}
_panelHasMousePointer(x, y) {
const panelBoxRect = this._panelBox.get_transformed_extents();
const cursorLocation = new Graphene.Point({x, y});
return panelBoxRect.contains_point(cursorLocation);
}
_startTrackingMouse(callback) {
if (this._pointerWatch)
return;
this._pointerWatch = PointerWatcher.getPointerWatcher().addWatch(500, (pX, pY) => {
if (!this._panelHasMousePointer(pX, pY)) {
callback();
this._stopTrackingMouse();
}
});
}
_stopTrackingMouse() {
if (this._pointerWatch) {
PointerWatcher.getPointerWatcher()._removeWatch(this._pointerWatch);
this._pointerWatch = null;
}
}
});
export const ArcMenu = class ArcMenuArcMenu extends PopupMenu.PopupMenu {
constructor(sourceActor, arrowAlignment, arrowSide, parent) {
super(sourceActor, arrowAlignment, arrowSide);
this._menuButton = parent || sourceActor;
Main.uiGroup.add_child(this.actor);
this.actor.add_style_class_name('panel-menu arcmenu-menu');
this.actor.hide();
this._menuClosedID = this.connect('menu-closed', () => this._menuButton.setDefaultMenuView());
this.actor.connectObject('captured-event', this._onCapturedEvent.bind(this), this);
this._dimEffect = new Clutter.BrightnessContrastEffect({
enabled: false,
});
this._boxPointer.add_effect_with_name('dim', this._dimEffect);
}
_onCapturedEvent(actor, event) {
if (Main.keyboard.maybeHandleEvent(event))
return Clutter.EVENT_STOP;
return Clutter.EVENT_PROPAGATE;
}
open(animate) {
if (!this.isOpen) {
this._menuButton.arcMenu.actor._muteInput = false;
this._menuButton.arcMenu.actor._muteKeys = false;
}
super.open(animate);
}
close(animate) {
if (this.isOpen)
this._menuButton?.closeOtherMenus();
super.close(animate);
}
destroy() {
this._boxPointer.remove_effect_by_name('dim');
if (this._menuClosedID) {
this.disconnect(this._menuClosedID);
this._menuClosedID = null;
}
super.destroy();
this._dimEffect = null;
this._menuButton = null;
}
};
var ArcMenuContextMenu = class ArcMenuArcMenuContextMenu extends PopupMenu.PopupMenu {
constructor(sourceActor, arrowAlignment, arrowSide) {
super(sourceActor, arrowAlignment, arrowSide);
this._systemActions = SystemActions.getDefault();
this.actor.add_style_class_name('panel-menu app-menu');
Main.uiGroup.add_child(this.actor);
this.actor.hide();
ArcMenuManager.settings.connectObject('changed::context-menu-items',
() => this.populateMenuItems(), this);
this.populateMenuItems();
}
destroy() {
this.disconnectPowerOptions();
ArcMenuManager.settings.disconnectObject(this);
this._systemActions = null;
super.destroy();
}
populateMenuItems() {
this.disconnectPowerOptions();
this.removeAll();
const contextMenuShortcuts = ArcMenuManager.settings.get_value('context-menu-items').deep_unpack();
for (let i = 0; i < contextMenuShortcuts.length; i++) {
const {name, id} = contextMenuShortcuts[i];
if (id.endsWith('.desktop')) {
this.addSettingsAction(name, id);
} else if (id === Constants.ShortcutCommands.SEPARATOR) {
this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
} else if (id === Constants.ShortcutCommands.SETTINGS) {
this.addAction(_('ArcMenu Settings'), () => ArcMenuManager.extension.openPreferences());
} else if (id.includes(Constants.ShortcutCommands.SETTINGS)) {
const settingsPage = id.replace(Constants.ShortcutCommands.SETTINGS, '');
if (settingsPage === 'About')
this.addArcMenuSettingsItem(name, Constants.SettingsPage.ABOUT);
else if (settingsPage === 'Menu')
this.addArcMenuSettingsItem(name, Constants.SettingsPage.CUSTOMIZE_MENU);
else if (settingsPage === 'Layout')
this.addArcMenuSettingsItem(name, Constants.SettingsPage.MENU_LAYOUT);
else if (settingsPage === 'Button')
this.addArcMenuSettingsItem(name, Constants.SettingsPage.BUTTON_APPEARANCE);
else if (settingsPage === 'Theme')
this.addArcMenuSettingsItem(name, Constants.SettingsPage.MENU_THEME);
} else if (id === Constants.ShortcutCommands.OVERVIEW) {
this.addAction(_('Activities Overview'), () => Main.overview.toggle());
} else if (id === Constants.ShortcutCommands.POWER_OPTIONS) {
this.addPowerOptionsMenuItem();
} else if (id === Constants.ShortcutCommands.SHOW_DESKTOP) {
this.addShowDekstopItem();
} else if (id === Constants.ShortcutCommands.PANEL_EXTENSION_SETTINGS) {
this.addExtensionSettings();
}
}
}
addArcMenuSettingsItem(title, prefsVisiblePage) {
const item = new PopupMenu.PopupMenuItem(_(title));
item.connect('activate', () => {
ArcMenuManager.settings.set_int('prefs-visible-page', prefsVisiblePage);
ArcMenuManager.extension.openPreferences();
});
this.addMenuItem(item);
}
disconnectPowerOptions() {
if (this.canSuspendId)
this._systemActions.disconnect(this.canSuspendId);
if (this.canSwitchUserId)
this._systemActions.disconnect(this.canSwitchUserId);
this.canSuspendId = null;
this.canSwitchUserId = null;
}
addShowDekstopItem() {
this.addAction(_('Show Desktop'), () => {
const currentWorkspace = global.workspace_manager.get_active_workspace();
let windows = currentWorkspace.list_windows().filter(w => {
return w.showing_on_its_workspace() && !w.skip_taskbar;
});
windows = global.display.sort_windows_by_stacking(windows);
windows.forEach(w => {
w.minimize();
});
});
}
addPowerOptionsMenuItem() {
const powerOptionsItem = new PopupMenu.PopupSubMenuMenuItem(_('Power Off / Log Out'));
const suspendItem = powerOptionsItem.menu.addAction(_('Suspend'),
() => this._systemActions.activateSuspend());
suspendItem.visible = this._systemActions.canSuspend;
powerOptionsItem.menu.addAction(_('Restart...'), () => this._systemActions.activateRestart());
powerOptionsItem.menu.addAction(_('Power Off...'), () => this._systemActions.activatePowerOff());
powerOptionsItem.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
powerOptionsItem.menu.addAction(_('Lock'), () => this._systemActions.activateLockScreen());
powerOptionsItem.menu.addAction(_('Log Out...'), () => this._systemActions.activateLogout());
const switchUserItem = powerOptionsItem.menu.addAction(_('Switch User'),
() => this._systemActions.activateSwitchUser());
switchUserItem.visible = this._systemActions.canSwitchUser;
this.canSuspendId = this._systemActions.connect('notify::can-suspend',
() => (suspendItem.visible = this._systemActions.canSuspend));
this.canSwitchUserId = this._systemActions.connect('notify::can-switch-user',
() => (switchUserItem.visible = this._systemActions.canSwitchUser));
this.addMenuItem(powerOptionsItem);
}
addSettingsAction(title, desktopFile) {
const app = Shell.AppSystem.get_default().lookup_app(desktopFile);
if (!app)
return;
if (!title)
title = app.get_name();
super.addSettingsAction(title, desktopFile);
}
addExtensionSettings() {
const dashToPanel = Main.extensionManager.lookup(Constants.DASH_TO_PANEL_UUID);
const azTaskbar = Main.extensionManager.lookup(Constants.AZTASKBAR_UUID);
if (dashToPanel?.state === Utils.ExtensionState.ACTIVE && global.dashToPanel) {
const item = new PopupMenu.PopupMenuItem(_('Dash to Panel Settings'));
item.connect('activate', () => Utils.openPrefs(Constants.DASH_TO_PANEL_UUID));
this.addMenuItem(item);
} else if (azTaskbar?.state === Utils.ExtensionState.ACTIVE && global.azTaskbar) {
const item = new PopupMenu.PopupMenuItem(_('App Icons Taskbar Settings'));
item.connect('activate', () => Utils.openPrefs(Constants.AZTASKBAR_UUID));
this.addMenuItem(item);
}
}
};