summaryrefslogtreecommitdiffstats
path: root/extensions/46/vertical-workspaces/lib/dash.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--extensions/46/vertical-workspaces/lib/dash.js (renamed from extensions/45/vertical-workspaces/lib/dash.js)667
1 files changed, 231 insertions, 436 deletions
diff --git a/extensions/45/vertical-workspaces/lib/dash.js b/extensions/46/vertical-workspaces/lib/dash.js
index f26151d..719c3de 100644
--- a/extensions/45/vertical-workspaces/lib/dash.js
+++ b/extensions/46/vertical-workspaces/lib/dash.js
@@ -3,10 +3,9 @@
* dash.js
*
* @author GdH <G-dH@github.com>
- * @copyright 2022-2023
+ * @copyright 2022-2024
* @license GPL-3.0
- * modified dash module of https://github.com/RensAlthuis/vertical-overview extension
- */
+ */
'use strict';
@@ -23,7 +22,6 @@ import * as AppFavorites from 'resource:///org/gnome/shell/ui/appFavorites.js';
import * as AppMenu from 'resource:///org/gnome/shell/ui/appMenu.js';
import * as BoxPointer from 'resource:///org/gnome/shell/ui/boxpointer.js';
import * as DND from 'resource:///org/gnome/shell/ui/dnd.js';
-import * as IconGrid from 'resource:///org/gnome/shell/ui/iconGrid.js';
import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js';
let Me;
@@ -39,6 +37,8 @@ export const BaseIconSizes = [16, 24, 32, 40, 44, 48, 56, 64, 72, 80, 96, 112, 1
const DASH_ITEM_LABEL_SHOW_TIME = 150;
+const shellVersion46 = !Clutter.Container; // Container has been removed in 46
+
export const DashModule = class {
constructor(me) {
Me = me;
@@ -130,32 +130,53 @@ export const DashModule = class {
this._overrides.addOverride('DashIcon', Dash.DashIcon.prototype, DashIconCommon);
this._overrides.addOverride('AppMenu', AppMenu.AppMenu.prototype, AppMenuCommon);
+ if (shellVersion46)
+ dash.add_style_class_name('dash-46');
+
if (opt.DASH_VERTICAL) {
// this._overrides.addOverride('Dash', Dash.Dash.prototype, DashVerticalOverride);
- dash.add_style_class_name('vertical');
+ dash.add_style_class_name(shellVersion46
+ ? 'vertical-46'
+ : 'vertical'
+ );
this._setOrientation(Clutter.Orientation.VERTICAL);
} else {
this._setOrientation(Clutter.Orientation.HORIZONTAL);
}
+ if (opt.DASH_VERTICAL && opt.DASH_BG_GS3_STYLE) {
+ if (opt.DASH_LEFT) {
+ dash.add_style_class_name(shellVersion46
+ ? 'vertical-46-gs3-left'
+ : 'vertical-gs3-left');
+ } else if (opt.DASH_RIGHT) {
+ dash.add_style_class_name(shellVersion46
+ ? 'vertical-46-gs3-right'
+ : 'vertical-gs3-right');
+ }
+ } else {
+ dash.remove_style_class_name('vertical-gs3-left');
+ dash.remove_style_class_name('vertical-gs3-right');
+ dash.remove_style_class_name('vertical-46-gs3-left');
+ dash.remove_style_class_name('vertical-46-gs3-right');
+ }
+
if (!this._customWorkId)
this._customWorkId = Main.initializeDeferredWork(dash._box, dash._redisplay.bind(dash));
dash._workId = this._customWorkId;
- this._updateSearchWindowsIcon();
- this._updateRecentFilesIcon();
- this._updateExtensionsIcon();
this._moveDashAppGridIcon();
this._connectShowAppsIcon();
dash.visible = opt.DASH_VISIBLE;
- dash._background.add_style_class_name('dash-background-reduced');
+ // dash._background.add_style_class_name('dash-background-reduced');
dash._queueRedisplay();
if (opt.DASH_ISOLATE_WS && !this._wmSwitchWsConId) {
this._wmSwitchWsConId = global.windowManager.connect('switch-workspace', () => dash._queueRedisplay());
this._newWindowConId = global.display.connect_after('window-created', () => dash._queueRedisplay());
}
+
console.debug(' DashModule - Activated');
}
@@ -181,9 +202,7 @@ export const DashModule = class {
this._setOrientation(Clutter.Orientation.HORIZONTAL);
this._moveDashAppGridIcon(reset);
this._connectShowAppsIcon(reset);
- this._updateSearchWindowsIcon(false);
- this._updateRecentFilesIcon(false);
- this._updateExtensionsIcon(false);
+
this._resetStyle(dash);
dash.visible = !this._conflict;
dash._background.opacity = 255;
@@ -194,8 +213,11 @@ export const DashModule = class {
_resetStyle(dash) {
dash.remove_style_class_name('vertical');
+ dash.remove_style_class_name('vertical-46');
dash.remove_style_class_name('vertical-gs3-left');
dash.remove_style_class_name('vertical-gs3-right');
+ dash.remove_style_class_name('vertical-46-gs3-left');
+ dash.remove_style_class_name('vertical-46-gs3-right');
dash.remove_style_class_name('vertical-left');
dash.remove_style_class_name('vertical-right');
dash._background.remove_style_class_name('dash-background-light');
@@ -237,16 +259,6 @@ export const DashModule = class {
dash._separator = null;
dash._queueRedisplay();
dash._adjustIconSize();
-
- if (orientation && opt.DASH_BG_GS3_STYLE) {
- if (opt.DASH_LEFT)
- dash.add_style_class_name('vertical-gs3-left');
- else if (opt.DASH_RIGHT)
- dash.add_style_class_name('vertical-gs3-right');
- } else {
- dash.remove_style_class_name('vertical-gs3-left');
- dash.remove_style_class_name('vertical-gs3-right');
- }
}
_moveDashAppGridIcon(reset = false) {
@@ -295,141 +307,6 @@ export const DashModule = class {
dash._showAppsIcon.reactive = false;
}
}
-
- _updateSearchWindowsIcon(show = opt.SHOW_WINDOWS_ICON, dash) {
- dash = dash ?? Main.overview._overview._controls.layoutManager._dash;
- const dashContainer = dash._dashContainer;
-
- if (dash._showWindowsIcon) {
- dashContainer.remove_child(dash._showWindowsIcon);
- if (dash._showWindowsIconClickedId) {
- dash._showWindowsIcon.toggleButton.disconnect(dash._showWindowsIconClickedId);
- dash._showWindowsIconClickedId = 0;
- }
- delete dash._showWindowsIconClickedId;
- if (dash._showWindowsIcon)
- dash._showWindowsIcon.destroy();
- delete dash._showWindowsIcon;
- }
-
- if (!show || !opt.get('windowSearchProviderModule'))
- return;
-
- if (!dash._showWindowsIcon) {
- dash._showWindowsIcon = new Dash.DashItemContainer();
- new Me.Util.Overrides().addOverride('showWindowsIcon', dash._showWindowsIcon, ShowWindowsIcon);
- dash._showWindowsIcon._afterInit();
- dash._showWindowsIcon.show(false);
- dashContainer.add_child(dash._showWindowsIcon);
- dash._hookUpLabel(dash._showWindowsIcon);
- }
-
- dash._showWindowsIcon.icon.setIconSize(dash.iconSize);
- if (opt.SHOW_WINDOWS_ICON === 1) {
- dashContainer.set_child_at_index(dash._showWindowsIcon, 0);
- } else if (opt.SHOW_WINDOWS_ICON === 2) {
- const index = dashContainer.get_children().length - 1;
- dashContainer.set_child_at_index(dash._showWindowsIcon, index);
- }
-
- Main.overview._overview._controls.layoutManager._dash._adjustIconSize();
-
- if (dash._showWindowsIcon && !dash._showWindowsIconClickedId) {
- dash._showWindowsIconClickedId = dash._showWindowsIcon.toggleButton.connect('clicked', () => {
- Me.Util.activateSearchProvider(Me.WSP_PREFIX);
- });
- }
- }
-
- _updateRecentFilesIcon(show = opt.SHOW_RECENT_FILES_ICON, dash) {
- dash = dash ?? Main.overview._overview._controls.layoutManager._dash;
- const dashContainer = dash._dashContainer;
-
- if (dash._recentFilesIcon) {
- dashContainer.remove_child(dash._recentFilesIcon);
- if (dash._recentFilesIconClickedId) {
- dash._recentFilesIcon.toggleButton.disconnect(dash._recentFilesIconClickedId);
- dash._recentFilesIconClickedId = 0;
- }
- delete dash._recentFilesIconClickedId;
- if (dash._recentFilesIcon)
- dash._recentFilesIcon.destroy();
- delete dash._recentFilesIcon;
- }
-
- if (!show || !opt.get('recentFilesSearchProviderModule'))
- return;
-
- if (!dash._recentFilesIcon) {
- dash._recentFilesIcon = new Dash.DashItemContainer();
- new Me.Util.Overrides().addOverride('recentFilesIcon', dash._recentFilesIcon, ShowRecentFilesIcon);
- dash._recentFilesIcon._afterInit();
- dash._recentFilesIcon.show(false);
- dashContainer.add_child(dash._recentFilesIcon);
- dash._hookUpLabel(dash._recentFilesIcon);
- }
-
- dash._recentFilesIcon.icon.setIconSize(dash.iconSize);
- if (opt.SHOW_RECENT_FILES_ICON === 1) {
- dashContainer.set_child_at_index(dash._recentFilesIcon, 0);
- } else if (opt.SHOW_RECENT_FILES_ICON === 2) {
- const index = dashContainer.get_children().length - 1;
- dashContainer.set_child_at_index(dash._recentFilesIcon, index);
- }
-
- Main.overview._overview._controls.layoutManager._dash._adjustIconSize();
-
- if (dash._recentFilesIcon && !dash._recentFilesIconClickedId) {
- dash._recentFilesIconClickedId = dash._recentFilesIcon.toggleButton.connect('clicked', () => {
- Me.Util.activateSearchProvider(Me.RFSP_PREFIX);
- });
- }
- }
-
- _updateExtensionsIcon(show = opt.SHOW_EXTENSIONS_ICON, dash) {
- dash = dash ?? Main.overview._overview._controls.layoutManager._dash;
- const dashContainer = dash._dashContainer;
-
- if (dash._extensionsIcon) {
- dashContainer.remove_child(dash._extensionsIcon);
- if (dash._extensionsIconClickedId) {
- dash._extensionsIcon.toggleButton.disconnect(dash._extensionsIconClickedId);
- dash._extensionsIconClickedId = 0;
- }
- delete dash._extensionsIconClickedId;
- if (dash._extensionsIcon)
- dash._extensionsIcon.destroy();
- delete dash._extensionsIcon;
- }
-
- if (!show || !opt.get('extensionsSearchProviderModule'))
- return;
-
- if (!dash._extensionsIcon) {
- dash._extensionsIcon = new Dash.DashItemContainer();
- new Me.Util.Overrides().addOverride('extensionsIcon', dash._extensionsIcon, ShowExtensionsIcon);
- dash._extensionsIcon._afterInit();
- dash._extensionsIcon.show(false);
- dashContainer.add_child(dash._extensionsIcon);
- dash._hookUpLabel(dash._extensionsIcon);
- }
-
- dash._extensionsIcon.icon.setIconSize(dash.iconSize);
- if (opt.SHOW_EXTENSIONS_ICON === 1) {
- dashContainer.set_child_at_index(dash._extensionsIcon, 0);
- } else if (opt.SHOW_EXTENSIONS_ICON === 2) {
- const index = dashContainer.get_children().length - 1;
- dashContainer.set_child_at_index(dash._extensionsIcon, index);
- }
-
- Main.overview._overview._controls.layoutManager._dash._adjustIconSize();
-
- if (dash._extensionsIcon && !dash._extensionsIconClickedId) {
- dash._extensionsIconClickedId = dash._extensionsIcon.toggleButton.connect('clicked', () => {
- Me.Util.activateSearchProvider(Me.ESP_PREFIX);
- });
- }
- }
};
function getAppFromSource(source) {
@@ -475,20 +352,20 @@ const DashItemContainerCommon = {
let y;
if (opt.DASH_TOP) {
- const yOffset = 0.75 * itemHeight + 3 * node.get_length('-y-offset');
+ const yOffset = itemHeight + (shellVersion46 ? 0 : -3);
y = stageY + yOffset;
} else if (opt.DASH_BOTTOM) {
const yOffset = node.get_length('-y-offset');
y = stageY - this.label.height - yOffset;
} else if (opt.DASH_RIGHT) {
const yOffset = Math.floor((itemHeight - labelHeight) / 2);
- xOffset = 4;
+ xOffset = shellVersion46 ? 8 : 4;
x = stageX - xOffset - this.label.width;
y = Math.clamp(stageY + yOffset, 0, global.stage.height - labelHeight);
} else if (opt.DASH_LEFT) {
const yOffset = Math.floor((itemHeight - labelHeight) / 2);
- xOffset = 4;
+ xOffset = shellVersion46 ? 8 : 4;
x = stageX + this.width + xOffset;
y = Math.clamp(stageY + yOffset, 0, global.stage.height - labelHeight);
@@ -744,15 +621,15 @@ const DashCommon = {
if (this._showAppsIcon.visible)
iconChildren.push(this._showAppsIcon);
+
+ // showWindowsIcon and extensionsIcon can be provided by the WSP and ESP extensions
if (this._showWindowsIcon)
iconChildren.push(this._showWindowsIcon);
- if (this._recentFilesIcon)
- iconChildren.push(this._recentFilesIcon);
-
if (this._extensionsIcon)
iconChildren.push(this._extensionsIcon);
+
if (!iconChildren.length)
return;
@@ -967,12 +844,15 @@ const DashIconCommon = {
this._scrollConId = this.connect('scroll-event', DashExtensions.onScrollEvent.bind(this));
this._leaveConId = this.connect('leave-event', DashExtensions.onLeaveEvent.bind(this));
}
+
+ if (this._updateRunningDotStyle)
+ this._updateRunningDotStyle();
},
- popupMenu() {
+ /* popupMenu() {
const side = opt.DASH_VERTICAL ? St.Side.LEFT : St.Side.BOTTOM;
AppIconCommon.popupMenu.bind(this)(side);
- },
+ },*/
_updateRunningStyle() {
const currentWs = global.workspace_manager.get_active_workspace();
@@ -985,193 +865,27 @@ const DashIconCommon = {
else
this._dot.hide();
},
-};
-
-const DashExtensions = {
- onScrollEvent(source, event) {
- if ((this.app && !opt.DASH_ICON_SCROLL) || (this._isSearchWindowsIcon && !opt.SEARCH_WINDOWS_ICON_SCROLL)) {
- if (this._scrollConId) {
- this.disconnect(this._scrollConId);
- this._scrollConId = 0;
- }
- if (this._leaveConId) {
- this.disconnect(this._leaveConId);
- this._leaveConId = 0;
- }
- return Clutter.EVENT_PROPAGATE;
- }
-
- if (Main.overview._overview.controls._stateAdjustment.value > 1)
- return Clutter.EVENT_PROPAGATE;
-
- let direction = Me.Util.getScrollDirection(event);
- if (direction === Clutter.ScrollDirection.UP)
- direction = 1;
- else if (direction === Clutter.ScrollDirection.DOWN)
- direction = -1;
- else
- return Clutter.EVENT_STOP;
-
- // avoid uncontrollable switching if smooth scroll wheel or trackpad is used
- if (this._lastScroll && Date.now() - this._lastScroll < 160)
- return Clutter.EVENT_STOP;
-
- this._lastScroll = Date.now();
-
- DashExtensions.switchWindow.bind(this)(direction);
- return Clutter.EVENT_STOP;
- },
-
- onLeaveEvent() {
- if (!this._selectedMetaWin || this.has_pointer || this.toggleButton?.has_pointer)
- return;
-
- this._selectedPreview._activateSelected = false;
- this._selectedMetaWin = null;
- this._scrolledWindows = null;
- DashExtensions.showWindowPreview.bind(this)(null);
- },
-
-
- switchWindow(direction) {
- if (!this._scrolledWindows) {
- this._initialSelection = true;
- // source is app icon
- if (this.app) {
- this._scrolledWindows = this.app.get_windows();
- if (opt.DASH_ISOLATE_WS) {
- const currentWs = global.workspaceManager.get_active_workspace();
- this._scrolledWindows = this._scrolledWindows.filter(w => w.get_workspace() === currentWs);
- }
-
- const wsList = [];
- this._scrolledWindows.forEach(w => {
- const ws = w.get_workspace();
- if (!wsList.includes(ws))
- wsList.push(ws);
- });
-
- // sort windows by workspaces in MRU order
- this._scrolledWindows.sort((a, b) => wsList.indexOf(a.get_workspace()) > wsList.indexOf(b.get_workspace()));
- // source is Search Windows icon
- } else if (this._isSearchWindowsIcon) {
- if (opt.SEARCH_WINDOWS_ICON_SCROLL === 1) // all windows
- this._scrolledWindows = Me.Util.getWindows(null);
- else
- this._scrolledWindows = Me.Util.getWindows(global.workspace_manager.get_active_workspace());
- }
- }
-
- let windows = this._scrolledWindows;
-
- if (!windows.length)
- return;
-
- // if window selection is in the process, the previewed window must be the current one
- let currentWin = this._selectedMetaWin ? this._selectedMetaWin : windows[0];
-
- const currentIdx = windows.indexOf(currentWin);
- let targetIdx = currentIdx;
- // const focusWindow = Me.Util.getWindows(null)[0]; // incompatible 45
- const focusWindow = Me.Util.getWindows(null)[0];
- const appFocused = this._scrolledWindows[0] === focusWindow && this._scrolledWindows[0].get_workspace() === global.workspace_manager.get_active_workspace();
- // only if the app has focus, immediately switch to the previous window
- // otherwise just set the current window above others
- if (!this._initialSelection || appFocused)
- targetIdx += direction;
- else
- this._initialSelection = false;
-
- if (targetIdx > windows.length - 1)
- targetIdx = 0;
- else if (targetIdx < 0)
- targetIdx = windows.length - 1;
-
- const metaWin = windows[targetIdx];
- DashExtensions.showWindowPreview.bind(this)(metaWin);
- this._selectedMetaWin = metaWin;
- },
-
- showWindowPreview(metaWin) {
- const views = Main.overview._overview.controls._workspacesDisplay._workspacesViews;
- const viewsIter = [views[0]];
- // secondary monitors use different structure
- views.forEach(v => {
- if (v._workspacesView)
- viewsIter.push(v._workspacesView);
- });
-
- viewsIter.forEach(view => {
- // if workspaces are on primary monitor only
- if (!view || !view._workspaces)
- return;
-
- view._workspaces.forEach(ws => {
- ws._windows.forEach(windowPreview => {
- // metaWin === null resets opacity
- let opacity = metaWin ? 50 : 255;
- windowPreview._activateSelected = false;
-
- // minimized windows are invisible if windows are not exposed (WORKSPACE_MODE === 0)
- if (!windowPreview.opacity)
- windowPreview.opacity = 255;
-
- // app windows set to lower opacity, so they can be recognized
- if (this._scrolledWindows && this._scrolledWindows.includes(windowPreview.metaWindow)) {
- if (opt.DASH_ICON_SCROLL === 2)
- opacity = 254;
- }
- if (windowPreview.metaWindow === metaWin) {
- if (metaWin && metaWin.get_workspace() !== global.workspace_manager.get_active_workspace()) {
- Main.wm.actionMoveWorkspace(metaWin.get_workspace());
- if (_timeouts.wsSwitcherAnimation)
- GLib.source_remove(_timeouts.wsSwitcherAnimation);
- // setting window preview above siblings before workspace switcher animation has no effect
- // we need to set the window above after the ws preview become visible on the screen
- // the default switcher animation time is 250, 200 ms delay should be enough
- _timeouts.wsSwitcherAnimation = GLib.timeout_add(0, 200 * St.Settings.get().slow_down_factor, () => {
- windowPreview.get_parent().set_child_above_sibling(windowPreview, null);
- _timeouts.wsSwitcherAnimation = 0;
- return GLib.SOURCE_REMOVE;
- });
- } else {
- windowPreview.get_parent().set_child_above_sibling(windowPreview, null);
- }
-
- opacity = 255;
- this._selectedPreview = windowPreview;
- windowPreview._activateSelected = true;
- }
-
- // if windows are exposed, highlight selected using opacity
- if ((opt.OVERVIEW_MODE && opt.WORKSPACE_MODE) || !opt.OVERVIEW_MODE) {
- if (metaWin && opacity === 255)
- windowPreview.showOverlay(true);
- else
- windowPreview.hideOverlay(true);
- windowPreview.ease({
- duration: 200,
- opacity,
- mode: Clutter.AnimationMode.EASE_OUT_QUAD,
- });
- }
- });
- });
- });
- },
-};
-const AppIconCommon = {
- after__init() {
+ /* after__init() {
if (this._updateRunningDotStyle)
this._updateRunningDotStyle();
- },
+ },*/
_updateRunningDotStyle() {
if (opt.RUNNING_DOT_STYLE)
this._dot.add_style_class_name('app-well-app-running-dot-custom');
else
this._dot.remove_style_class_name('app-well-app-running-dot-custom');
+
+ if (!this.label && shellVersion46) {
+ if (opt.DASH_VERTICAL) {
+ this._dot.translation_y = 0;
+ this._dot.translation_x = 0; // opt.DASH_LEFT ? -4 : 4;
+ } else {
+ this._dot.translation_y = 8;
+ this._dot.translation_x = 0;
+ }
+ }
},
activate(button) {
@@ -1243,6 +957,9 @@ const AppIconCommon = {
},
popupMenu(side = St.Side.LEFT) {
+ side = opt.DASH_VERTICAL ? St.Side.LEFT : St.Side.BOTTOM;
+ // AppIconCommon.popupMenu.bind(this)(side);
+
this.setForcedHighlight(true);
this._removeMenuTimeout();
this.fake_release();
@@ -1277,7 +994,7 @@ const AppIconCommon = {
this._hidingSigId = Main.overview.connect('hiding',
() => this._menu.close(), this);
- Main.uiGroup.add_actor(this._menu.actor);
+ Main.uiGroup.add_child(this._menu.actor);
this._menuManager.addMenu(this._menu);
}
@@ -1310,10 +1027,12 @@ const AppIconCommon = {
}]);
}
+
popupItems.push([_('Move App to Current Workspace ( Shift + Click )'), this._moveAppToCurrentWorkspace]);
- if (opt.WINDOW_THUMBNAIL_ENABLED) {
- popupItems.push([_('Create Window Thumbnail - PIP'), () => {
- Me.Modules.winTmbModule.createThumbnail(this.app.get_windows()[0]);
+ // WTMB (Windows Thumbnails) extension required
+ if (global.windowThumbnails) {
+ popupItems.push([_('Create Window Thumbnail/PiP'), () => {
+ global.windowThumbnails?.createThumbnail(this.app.get_windows()[0]);
}]);
}
}
@@ -1362,115 +1081,191 @@ const AppIconCommon = {
},
};
-const ShowWindowsIcon = {
- _afterInit() {
- this._isSearchWindowsIcon = true;
- this._labelText = _('Search Open Windows (Hotkey: Space)');
- this.toggleButton = new St.Button({
- style_class: 'show-apps',
- track_hover: true,
- can_focus: true,
- toggle_mode: false,
- });
+const DashExtensions = {
+ onScrollEvent(source, event) {
+ if ((this.app && !opt.DASH_ICON_SCROLL) || (this._isSearchWindowsIcon && !opt.SEARCH_WINDOWS_ICON_SCROLL)) {
+ if (this._scrollConId) {
+ this.disconnect(this._scrollConId);
+ this._scrollConId = 0;
+ }
+ if (this._leaveConId) {
+ this.disconnect(this._leaveConId);
+ this._leaveConId = 0;
+ }
+ return Clutter.EVENT_PROPAGATE;
+ }
- this._iconActor = null;
- this.icon = new IconGrid.BaseIcon(this.labelText, {
- setSizeManually: true,
- showLabel: false,
- createIcon: this._createIcon.bind(this),
- });
- this.icon.y_align = Clutter.ActorAlign.CENTER;
+ if (Main.overview._overview.controls._stateAdjustment.value > 1)
+ return Clutter.EVENT_PROPAGATE;
- this.toggleButton.add_actor(this.icon);
- this.toggleButton._delegate = this;
+ let direction = Me.Util.getScrollDirection(event);
+ if (direction === Clutter.ScrollDirection.UP)
+ direction = 1;
+ else if (direction === Clutter.ScrollDirection.DOWN)
+ direction = -1;
+ else
+ return Clutter.EVENT_STOP;
- this.setChild(this.toggleButton);
+ // avoid uncontrollable switching if smooth scroll wheel or trackpad is used
+ if (this._lastScroll && Date.now() - this._lastScroll < 160)
+ return Clutter.EVENT_STOP;
- if (opt.SEARCH_WINDOWS_ICON_SCROLL) {
- this.reactive = true;
- this._scrollConId = this.connect('scroll-event', DashExtensions.onScrollEvent.bind(this));
- this._leaveConId = this.connect('leave-event', DashExtensions.onLeaveEvent.bind(this));
- }
+ this._lastScroll = Date.now();
+
+ DashExtensions.switchWindow.bind(this)(direction);
+ return Clutter.EVENT_STOP;
},
- _createIcon(size) {
- this._iconActor = new St.Icon({
- icon_name: 'focus-windows-symbolic',
- icon_size: size,
- style_class: 'show-apps-icon',
- track_hover: true,
- });
- return this._iconActor;
+ onLeaveEvent() {
+ if (!this._selectedMetaWin || this.has_pointer || this.toggleButton?.has_pointer)
+ return;
+
+ this._selectedPreview._activateSelected = false;
+ this._selectedMetaWin = null;
+ this._scrolledWindows = null;
+ DashExtensions.showWindowPreview.bind(this)(null);
},
-};
-const ShowRecentFilesIcon = {
- _afterInit() {
- this._labelText = _('Search Recent Files (Hotkey: Ctrl + Space)');
- this.toggleButton = new St.Button({
- style_class: 'show-apps',
- track_hover: true,
- can_focus: true,
- toggle_mode: false,
- });
- this._iconActor = null;
- this.icon = new IconGrid.BaseIcon(this.labelText, {
- setSizeManually: true,
- showLabel: false,
- createIcon: this._createIcon.bind(this),
- });
- this.icon.y_align = Clutter.ActorAlign.CENTER;
+ switchWindow(direction) {
+ if (!this._scrolledWindows) {
+ this._initialSelection = true;
+ // source is app icon
+ if (this.app) {
+ this._scrolledWindows = this.app.get_windows();
+ if (opt.DASH_ISOLATE_WS) {
+ const currentWs = global.workspaceManager.get_active_workspace();
+ this._scrolledWindows = this._scrolledWindows.filter(w => w.get_workspace() === currentWs);
+ }
- this.toggleButton.add_actor(this.icon);
- this.toggleButton._delegate = this;
+ const wsList = [];
+ this._scrolledWindows.forEach(w => {
+ const ws = w.get_workspace();
+ if (!wsList.includes(ws))
+ wsList.push(ws);
+ });
- this.setChild(this.toggleButton);
- },
+ // sort windows by workspaces in MRU order
+ this._scrolledWindows.sort((a, b) => wsList.indexOf(a.get_workspace()) > wsList.indexOf(b.get_workspace()));
+ // source is Search Windows icon
+ } else if (this._isSearchWindowsIcon) {
+ if (opt.SEARCH_WINDOWS_ICON_SCROLL === 1) // all windows
+ this._scrolledWindows = Me.Util.getWindows(null);
+ else
+ this._scrolledWindows = Me.Util.getWindows(global.workspace_manager.get_active_workspace());
+ }
+ }
- _createIcon(size) {
- this._iconActor = new St.Icon({
- icon_name: 'document-open-recent-symbolic',
- icon_size: size,
- style_class: 'show-apps-icon',
- track_hover: true,
- });
- return this._iconActor;
+ let windows = this._scrolledWindows;
+
+ if (!windows.length)
+ return;
+
+ // if window selection is in the process, the previewed window must be the current one
+ let currentWin = this._selectedMetaWin ? this._selectedMetaWin : windows[0];
+
+ const currentIdx = windows.indexOf(currentWin);
+ let targetIdx = currentIdx;
+ // const focusWindow = Me.Util.getWindows(null)[0]; // incompatible 45
+ const focusWindow = Me.Util.getWindows(null)[0];
+ const appFocused = this._scrolledWindows[0] === focusWindow && this._scrolledWindows[0].get_workspace() === global.workspace_manager.get_active_workspace();
+ // only if the app has focus, immediately switch to the previous window
+ // otherwise just set the current window above others
+ if (!this._initialSelection || appFocused)
+ targetIdx += direction;
+ else
+ this._initialSelection = false;
+
+ if (targetIdx > windows.length - 1)
+ targetIdx = 0;
+ else if (targetIdx < 0)
+ targetIdx = windows.length - 1;
+
+ const metaWin = windows[targetIdx];
+ DashExtensions.showWindowPreview.bind(this)(metaWin);
+ this._selectedMetaWin = metaWin;
},
-};
-const ShowExtensionsIcon = {
- _afterInit() {
- this._labelText = _('Search Extensions (Hotkey: Ctrl + Shift + Space)');
- this.toggleButton = new St.Button({
- style_class: 'show-apps',
- track_hover: true,
- can_focus: true,
- toggle_mode: false,
+ showWindowPreview(metaWin) {
+ const views = Main.overview._overview.controls._workspacesDisplay._workspacesViews;
+ const viewsIter = [views[0]];
+ // secondary monitors use different structure
+ views.forEach(v => {
+ if (v._workspacesView)
+ viewsIter.push(v._workspacesView);
});
- this._iconActor = null;
- this.icon = new IconGrid.BaseIcon(this.labelText, {
- setSizeManually: true,
- showLabel: false,
- createIcon: this._createIcon.bind(this),
- });
- this.icon.y_align = Clutter.ActorAlign.CENTER;
+ viewsIter.forEach(view => {
+ // if workspaces are on primary monitor only
+ if (!view || !view._workspaces)
+ return;
- this.toggleButton.add_actor(this.icon);
- this.toggleButton._delegate = this;
+ view._workspaces.forEach(ws => {
+ ws._windows.forEach(windowPreview => {
+ // metaWin === null resets opacity
+ let opacity = metaWin ? 50 : 255;
+ windowPreview._activateSelected = false;
- this.setChild(this.toggleButton);
- },
+ // minimized windows are invisible if windows are not exposed (WORKSPACE_MODE === 0)
+ if (!windowPreview.opacity)
+ windowPreview.opacity = 255;
+
+ // app windows set to lower opacity, so they can be recognized
+ if (this._scrolledWindows && this._scrolledWindows.includes(windowPreview.metaWindow)) {
+ if (opt.DASH_ICON_SCROLL === 2)
+ opacity = 254;
+ }
+ if (windowPreview.metaWindow === metaWin) {
+ if (metaWin && metaWin.get_workspace() !== global.workspace_manager.get_active_workspace()) {
+ Main.wm.actionMoveWorkspace(metaWin.get_workspace());
+ if (_timeouts.wsSwitcherAnimation)
+ GLib.source_remove(_timeouts.wsSwitcherAnimation);
+ // setting window preview above siblings before workspace switcher animation has no effect
+ // we need to set the window above after the ws preview become visible on the screen
+ // the default switcher animation time is 250, 200 ms delay should be enough
+ _timeouts.wsSwitcherAnimation = GLib.timeout_add(0, 200 * St.Settings.get().slow_down_factor, () => {
+ windowPreview.get_parent().set_child_above_sibling(windowPreview, null);
+ _timeouts.wsSwitcherAnimation = 0;
+ return GLib.SOURCE_REMOVE;
+ });
+ } else {
+ windowPreview.get_parent().set_child_above_sibling(windowPreview, null);
+ }
- _createIcon(size) {
- this._iconActor = new St.Icon({
- icon_name: 'application-x-addon-symbolic',
- icon_size: size,
- style_class: 'show-apps-icon',
- track_hover: true,
+ opacity = 255;
+ this._selectedPreview = windowPreview;
+ windowPreview._activateSelected = true;
+ }
+
+ // if windows are exposed, highlight selected using opacity
+ if ((opt.OVERVIEW_MODE && opt.WORKSPACE_MODE) || !opt.OVERVIEW_MODE) {
+ if (metaWin && opacity === 255)
+ windowPreview.showOverlay(true);
+ else
+ windowPreview.hideOverlay(true);
+ windowPreview.ease({
+ duration: 200,
+ opacity,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ });
+ }
+ });
+ });
});
- return this._iconActor;
+ },
+};
+
+const AppIconCommon = {
+ after__init() {
+ if (this._updateRunningDotStyle)
+ this._updateRunningDotStyle();
+ },
+
+ _updateRunningDotStyle() {
+ if (opt.RUNNING_DOT_STYLE)
+ this._dot.add_style_class_name('app-well-app-running-dot-custom');
+ else
+ this._dot.remove_style_class_name('app-well-app-running-dot-custom');
},
};