summaryrefslogtreecommitdiffstats
path: root/extensions/vertical-workspaces/appDisplay.js
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/vertical-workspaces/appDisplay.js')
-rw-r--r--extensions/vertical-workspaces/appDisplay.js944
1 files changed, 0 insertions, 944 deletions
diff --git a/extensions/vertical-workspaces/appDisplay.js b/extensions/vertical-workspaces/appDisplay.js
deleted file mode 100644
index 4690fcf..0000000
--- a/extensions/vertical-workspaces/appDisplay.js
+++ /dev/null
@@ -1,944 +0,0 @@
-/**
- * Vertical Workspaces
- * appDisplay.js
- *
- * @author GdH <G-dH@github.com>
- * @copyright 2022 - 2023
- * @license GPL-3.0
- *
- */
-
-'use strict';
-
-const { Clutter, GLib, GObject, Graphene, Meta, Shell, St } = imports.gi;
-
-const DND = imports.ui.dnd;
-const Main = imports.ui.main;
-const AppDisplay = imports.ui.appDisplay;
-const IconGrid = imports.ui.iconGrid;
-const { AppMenu } = imports.ui.appMenu;
-const PopupMenu = imports.ui.popupMenu;
-const BoxPointer = imports.ui.boxpointer;
-
-const ExtensionUtils = imports.misc.extensionUtils;
-const Me = ExtensionUtils.getCurrentExtension();
-const IconGridOverride = Me.imports.iconGrid;
-
-const _Util = Me.imports.util;
-let _overrides;
-
-let _appGridLayoutSettings;
-let _appDisplayScrollConId;
-let _appSystemStateConId;
-let _appGridLayoutConId;
-let _updateAppGridTimeoutId;
-let _origAppDisplayAcceptDrop;
-let _origAppViewItemAcceptDrop;
-let _origAppViewItemHandleDragOver;
-
-let opt;
-let shellVersion = _Util.shellVersion;
-
-
-function update(reset = false) {
- if (_overrides) {
- _overrides.removeAll();
- }
-
- if (reset) {
- _setAppDisplayOrientation(false);
- _updateAppGridProperties(reset);
- _updateAppGridDND(reset);
- _restoreOverviewGroup();
- _overrides = null;
- opt = null;
- return;
- }
-
- opt = Me.imports.settings.opt;
-
- _overrides = new _Util.Overrides();
-
- if (opt.ORIENTATION === Clutter.Orientation.VERTICAL) {
- _overrides.addOverride('AppDisplayVertical', AppDisplay.AppDisplay.prototype, AppDisplayVertical);
- _overrides.addOverride('BaseAppViewVertical', AppDisplay.BaseAppView.prototype, BaseAppViewVertical);
- }
-
- _overrides.addOverride('AppSearchProvider', AppDisplay.AppSearchProvider.prototype, AppSearchProvider);
-
- // Custom App Grid
- _overrides.addOverride('AppFolderDialog', AppDisplay.AppFolderDialog.prototype, AppFolderDialog);
- if (shellVersion >= 43) {
- // const defined class needs to be touched before real access
- AppDisplay.BaseAppViewGridLayout;
- _overrides.addOverride('BaseAppViewGridLayout', AppDisplay.BaseAppViewGridLayout.prototype, BaseAppViewGridLayout);
- _overrides.addOverride('IconGrid', IconGrid.IconGrid.prototype, IconGridOverride.IconGrid);
- }
- _overrides.addOverride('FolderView', AppDisplay.FolderView.prototype, FolderView);
- _overrides.addInjection('AppFolderDialog', AppDisplay.AppFolderDialog.prototype, AppFolderDialogInjections);
- _overrides.addOverride('AppIcon', AppDisplay.AppIcon.prototype, AppIcon);
- _overrides.addOverride('BaseAppView', AppDisplay.BaseAppView.prototype, BaseAppView);
- _overrides.addOverride('AppDisplay', AppDisplay.AppDisplay.prototype, AppDisplayCommon);
-
-
- _setAppDisplayOrientation(opt.ORIENTATION === Clutter.Orientation.VERTICAL);
- _updateAppGridProperties();
- _updateAppGridDND();
-}
-
-//---------------------------------------------------------------------------------------------------------
-
-function _setAppDisplayOrientation(vertical = false) {
- const CLUTTER_ORIENTATION = vertical ? Clutter.Orientation.VERTICAL : Clutter.Orientation.HORIZONTAL;
- const scroll = vertical ? 'vscroll' : 'hscroll';
- // app display to vertical has issues - page indicator not working
- // global appDisplay orientation switch is not built-in
- let appDisplay = Main.overview._overview._controls._appDisplay;
- // following line itself only changes in which axis will operate overshoot detection which switches appDisplay pages while dragging app icon to vertical
- appDisplay._orientation = CLUTTER_ORIENTATION;
- appDisplay._grid.layoutManager._orientation = CLUTTER_ORIENTATION;
- appDisplay._swipeTracker.orientation = CLUTTER_ORIENTATION;
- appDisplay._swipeTracker._reset();
- if (vertical) {
- appDisplay._scrollView.set_policy(St.PolicyType.NEVER, St.PolicyType.EXTERNAL);
-
- // move and change orientation of page indicators
- // needs corrections in appgrid page calculations, e.g. appDisplay.adaptToSize() fnc,
- // which complicates use of super call inside the function
- const pageIndicators = appDisplay._pageIndicators;
- pageIndicators.vertical = true;
- appDisplay._box.vertical = false;
- pageIndicators.x_expand = false;
- pageIndicators.y_align = Clutter.ActorAlign.CENTER;
- pageIndicators.x_align = Clutter.ActorAlign.START;
-
- const scrollContainer = appDisplay._scrollView.get_parent();
- if (shellVersion < 43) {
- // remove touch friendly side navigation bars / arrows
- appDisplay._hintContainer && scrollContainer.remove_child(appDisplay._hintContainer);
- } else {
- // moving these bars needs more patching of the appDisplay's code
- // for now we just change bars style to be more like vertically oriented arrows indicating direction to prev/next page
- appDisplay._nextPageIndicator.add_style_class_name('nextPageIndicator');
- appDisplay._prevPageIndicator.add_style_class_name('prevPageIndicator');
- }
-
- // setting their x_scale to 0 removes the arrows and avoid allocation issues compared to .hide() them
- appDisplay._nextPageArrow.scale_x = 0;
- appDisplay._prevPageArrow.scale_x = 0;
- } else {
- appDisplay._scrollView.set_policy(St.PolicyType.EXTERNAL, St.PolicyType.NEVER);
- if (_appDisplayScrollConId) {
- appDisplay._adjustment.disconnect(_appDisplayScrollConId);
- _appDisplayScrollConId = 0;
- }
-
- // restore original page indicators
- const pageIndicators = appDisplay._pageIndicators;
- pageIndicators.vertical = false;
- appDisplay._box.vertical = true;
- pageIndicators.x_expand = true;
- pageIndicators.y_align = Clutter.ActorAlign.END;
- pageIndicators.x_align = Clutter.ActorAlign.CENTER;
-
- // put back touch friendly navigation bars/buttons
- const scrollContainer = appDisplay._scrollView.get_parent();
- appDisplay._hintContainer && appDisplay._hintContainer.get_parent() == null && scrollContainer.add_child(appDisplay._hintContainer);
- appDisplay._nextPageArrow.scale_x = 1;
- appDisplay._prevPageArrow.scale_x = 1;
-
- appDisplay._nextPageIndicator.remove_style_class_name('nextPageIndicator');
- appDisplay._prevPageIndicator.remove_style_class_name('prevPageIndicator');
- }
-
- // value for page indicator is calculated from scroll adjustment, horizontal needs to be replaced by vertical
- appDisplay._adjustment = appDisplay._scrollView[scroll].adjustment;
-
- // no need to connect already connected signal (wasn't removed the original one before)
- if (!vertical) {
- // reset used appdisplay properties
- Main.overview._overview._controls._appDisplay.scale_y = 1;
- Main.overview._overview._controls._appDisplay.scale_x = 1;
- Main.overview._overview._controls._appDisplay.opacity = 255;
- return;
- }
-
- // update appGrid dot pages indicators
- _appDisplayScrollConId = appDisplay._adjustment.connect('notify::value', adj => {
- const value = adj.value / adj.page_size;
- appDisplay._pageIndicators.setCurrentPosition(value);
- });
-}
-
-// Set App Grid columns, rows, icon size, incomplete pages
-function _updateAppGridProperties(reset = false) {
- // columns, rows, icon size
- const appDisplay = Main.overview._overview._controls._appDisplay;
- appDisplay.visible = true;
-
- // replace isFavorite function to always return false to allow dnd with favorite apps
- if (!reset && opt.APP_GRID_INCLUDE_DASH) {
- if (!appDisplay._appFavorites._backupIsFavorite) {
- appDisplay._appFavorites._backupIsFavorite = appDisplay._appFavorites.isFavorite;
- }
- appDisplay._appFavorites.isFavorite = () => false;
- } else {
- if (appDisplay._appFavorites._backupIsFavorite) {
- appDisplay._appFavorites.isFavorite = appDisplay._appFavorites._backupIsFavorite;
- appDisplay._appFavorites._backupIsFavorite = undefined;
- }
- }
-
- if (reset) {
- appDisplay._grid.layout_manager.fixedIconSize = -1;
- appDisplay._grid.layoutManager.allow_incomplete_pages = true;
- appDisplay._grid.setGridModes();
- if (_appGridLayoutSettings) {
- _appGridLayoutSettings.disconnect(_appGridLayoutConId);
- _appGridLayoutConId = 0;
- _appGridLayoutSettings = null;
- }
- appDisplay._redisplay();
- // secondary call is necessary to properly update app grid
- appDisplay._redisplay();
- } else {
- // update grid on layout reset
- if (!_appGridLayoutSettings) {
- _appGridLayoutSettings = ExtensionUtils.getSettings('org.gnome.shell');
- _appGridLayoutConId = _appGridLayoutSettings.connect('changed::app-picker-layout', _resetAppGrid);
- }
-
- // remove icons from App Grid
- _resetAppGrid();
-
- const updateGrid = function(rows, columns) {
- if (rows === -1 || columns === -1) {
- appDisplay._grid.setGridModes();
- } else {
- appDisplay._grid.setGridModes(
- [{ rows, columns }]
- );
- }
- appDisplay._grid._setGridMode(0);
- }
-
- appDisplay._grid._currentMode = -1;
- if (opt.APP_GRID_ALLOW_CUSTOM) {
- updateGrid(opt.APP_GRID_ROWS, opt.APP_GRID_COLUMNS);
- } else {
- appDisplay._grid.setGridModes();
- updateGrid(-1, -1);
- }
- appDisplay._grid.layoutManager.fixedIconSize = opt.APP_GRID_ICON_SIZE;
- appDisplay._grid.layoutManager.allow_incomplete_pages = opt.APP_GRID_ALLOW_INCOMPLETE_PAGES;
-
- // force rebuild icons. size shouldn't be the same as the current one, otherwise can be arbitrary
- appDisplay._grid.layoutManager.adaptToSize(200, 200);
- appDisplay._redisplay();
-
- _realizeAppDisplay();
- }
-}
-
-//------ App Grid - DND ----------------------------------------------------------
-
-function _updateAppGridDND(reset) {
- if (opt.APP_GRID_ORDER && !reset) {
- if (!_appSystemStateConId)
- _appSystemStateConId = Shell.AppSystem.get_default().connect('app-state-changed', () => Main.overview._overview._controls._appDisplay._redisplay());
-
- // deny dnd from dash to app grid
- if (!_origAppDisplayAcceptDrop)
- _origAppDisplayAcceptDrop = AppDisplay.AppDisplay.prototype.acceptDrop;
- AppDisplay.AppDisplay.prototype.acceptDrop = function() { return false; };
-
- // deny creating folders by dnd on other icon
- if (!_origAppViewItemHandleDragOver)
- _origAppViewItemHandleDragOver = AppDisplay.AppViewItem.prototype.handleDragOver;
- AppDisplay.AppViewItem.prototype.handleDragOver = () => DND.DragMotionResult.NO_DROP;
-
- if (!_origAppViewItemAcceptDrop)
- _origAppViewItemAcceptDrop = AppDisplay.AppViewItem.prototype.acceptDrop;
- AppDisplay.AppViewItem.prototype.acceptDrop = () => false;
- } else {
- if (_appSystemStateConId) {
- Shell.AppSystem.get_default().disconnect(_appSystemStateConId);
- _appSystemStateConId = 0;
- }
-
- if (_origAppDisplayAcceptDrop)
- AppDisplay.AppDisplay.prototype.acceptDrop = _origAppDisplayAcceptDrop;
-
- if (_origAppViewItemHandleDragOver)
- AppDisplay.AppViewItem.prototype.handleDragOver = _origAppViewItemHandleDragOver;
-
- if (_origAppViewItemAcceptDrop)
- AppDisplay.AppViewItem.prototype.acceptDrop = _origAppViewItemAcceptDrop;
- }
-}
-
-function _realizeAppDisplay() {
- // force app grid to build all icons before the first visible animation to remove possible stuttering
- // let the main loop realize previous changes before continuing
-
- // don't do this during shell startup
- if (Main.layoutManager._startingUp)
- return;
-
- if (_updateAppGridTimeoutId) {
- GLib.source_remove(_updateAppGridTimeoutId);
- }
-
- _updateAppGridTimeoutId = GLib.timeout_add(
- GLib.PRIORITY_DEFAULT,
- 1000,
- () => {
- Main.layoutManager.overviewGroup.opacity = 1;
- Main.layoutManager.overviewGroup.scale_x = 0.1;
- Main.layoutManager.overviewGroup.show();
- Main.overview.dash.showAppsButton.checked = true;
-
- GLib.source_remove(_updateAppGridTimeoutId);
-
- _updateAppGridTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
- 500,
- () => {
- _restoreOverviewGroup();
- _updateAppGridTimeoutId = 0;
- return GLib.SOURCE_REMOVE;
- });
- }
- );
-}
-
-function _restoreOverviewGroup() {
- Main.overview.dash.showAppsButton.checked = false;
- Main.layoutManager.overviewGroup.opacity = 255;
- Main.layoutManager.overviewGroup.scale_x = 1;
- Main.layoutManager.overviewGroup.hide();
-}
-
-//------ appDisplay - Vertical --------------------------------------------------------------------------------
-
-var AppDisplayVertical = {
- // correction of the appGrid size when page indicators were moved from the bottom to the right
- adaptToSize: function(width, height) {
- const [, indicatorWidth] = this._pageIndicators.get_preferred_width(-1);
- width -= indicatorWidth;
-
- this._grid.findBestModeForSize(width, height);
-
- const adaptToSize = AppDisplay.BaseAppView.prototype.adaptToSize.bind(this);
- adaptToSize(width, height);
- },
-}
-
-
-//------ AppDisplay.AppSearchProvider ----------------------------------------------------------------------------------
-
-// App search result size
-var AppSearchProvider = {
- createResultObject: function(resultMeta) {
- if (resultMeta.id.endsWith('.desktop')) {
- const icon = new AppDisplay.AppIcon(this._appSys.lookup_app(resultMeta['id']), {
- expandTitleOnHover: false,
- });
- icon.icon.setIconSize(opt.SEARCH_ICON_SIZE);
- return icon;
- } else {
- const icon = new AppDisplay.SystemActionIcon(this, resultMeta);
- icon.icon._setSizeManually = true;
- icon.icon.setIconSize(opt.SEARCH_ICON_SIZE);
- return icon;
- }
- }
-}
-
-var BaseAppViewVertical = {
- // this fixes dnd from appDisplay to the workspace thumbnail on the left if appDisplay is on page 1 because of appgrid left overshoot
- _pageForCoords: function(x, y) {
- return AppDisplay.SidePages.NONE;
- },
-}
-
-// ------ AppDisplay - Custom App Grid ------------------------------------------------------------------------
-
-var AppDisplayCommon = {
- _ensureDefaultFolders: function() {
- // disable creation of default folders if user deleted them
- },
-
- // apps load adapted for custom sorting and including dash items
- _loadApps: function() {
- let appIcons = [];
- this._appInfoList = Shell.AppSystem.get_default().get_installed().filter(appInfo => {
- try {
- appInfo.get_id(); // catch invalid file encodings
- } catch (e) {
- return false;
- }
- return (opt.APP_GRID_INCLUDE_DASH || !this._appFavorites.isFavorite(appInfo.get_id())) &&
- this._parentalControlsManager.shouldShowApp(appInfo);
- });
-
- let apps = this._appInfoList.map(app => app.get_id());
-
- let appSys = Shell.AppSystem.get_default();
-
- const appsInsideFolders = new Set();
- this._folderIcons = [];
- if (!opt.APP_GRID_ORDER) {
-
- let folders = this._folderSettings.get_strv('folder-children');
- folders.forEach(id => {
- let path = `${this._folderSettings.path}folders/${id}/`;
- let icon = this._items.get(id);
- if (!icon) {
- icon = new AppDisplay.FolderIcon(id, path, this);
- icon.connect('apps-changed', () => {
- this._redisplay();
- this._savePages();
- });
- icon.connect('notify::pressed', () => {
- if (icon.pressed)
- this.updateDragFocus(icon);
- });
- }
-
- // Don't try to display empty folders
- if (!icon.visible) {
- icon.destroy();
- return;
- }
-
- appIcons.push(icon);
- this._folderIcons.push(icon);
-
- icon.getAppIds().forEach(appId => appsInsideFolders.add(appId));
- });
- }
-
- // Allow dragging of the icon only if the Dash would accept a drop to
- // change favorite-apps. There are no other possible drop targets from
- // the app picker, so there's no other need for a drag to start,
- // at least on single-monitor setups.
- // This also disables drag-to-launch on multi-monitor setups,
- // but we hope that is not used much.
- const isDraggable =
- global.settings.is_writable('favorite-apps') ||
- global.settings.is_writable('app-picker-layout');
-
- apps.forEach(appId => {
- if (!opt.APP_GRID_ORDER && appsInsideFolders.has(appId))
- return;
-
- let icon = this._items.get(appId);
- if (!icon) {
- let app = appSys.lookup_app(appId);
-
- icon = new AppDisplay.AppIcon(app, { isDraggable });
- icon.connect('notify::pressed', () => {
- if (icon.pressed)
- this.updateDragFocus(icon);
- });
- }
-
- appIcons.push(icon);
- });
-
- // At last, if there's a placeholder available, add it
- if (this._placeholder)
- appIcons.push(this._placeholder);
-
- //const runningIDs = Shell.AppSystem.get_default().get_running().map(app => app.get_id());
-
- // remove running apps
- /*if (!APP_GRID_INCLUDE_DASH) { // !icon.app means folder
- appIcons = appIcons.filter((icon) => this._folderIcons.includes(icon) || !(runningIDs.includes(icon.app.id) || this._appFavorites.isFavorite(icon.id)));
- }*/
-
- return appIcons;
- },
-}
-
-var BaseAppView = {
- // adds sorting options and option to add favorites and running apps
- _redisplay: function() {
- let oldApps = this._orderedItems.slice();
- let oldAppIds = oldApps.map(icon => icon.id);
-
- let newApps = this._loadApps().sort(this._compareItems.bind(this));
- let newAppIds = newApps.map(icon => icon.id);
-
- let addedApps = newApps.filter(icon => !oldAppIds.includes(icon.id));
- let removedApps = oldApps.filter(icon => !newAppIds.includes(icon.id));
-
- // Remove old app icons
- removedApps.forEach(icon => {
- this._removeItem(icon);
- icon.destroy();
- });
-
- // Add new app icons, or move existing ones
- newApps.forEach(icon => {
- const [page, position] = this._getItemPosition(icon);
- if (addedApps.includes(icon))
- this._addItem(icon, page, position);
- else if (page !== -1 && position !== -1) {
- this._moveItem(icon, page, position);
- }
-
- });
-
- // Reorder App Grid by usage
- // sort all alphabetically
- if(opt.APP_GRID_ORDER > 0) {
- const { itemsPerPage } = this._grid;
- let appIcons = this._orderedItems;
- appIcons.sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()));
- // then sort used apps by usage
- if (opt.APP_GRID_ORDER === 2) {
- appIcons.sort((a, b) => Shell.AppUsage.get_default().compare(a.app.id, b.app.id));
- }
- // sort favorites first
- if (opt.APP_GRID_INCLUDE_DASH === 2) {
- const fav = Object.keys(this._appFavorites._favorites);
- appIcons.sort((a, b) => {
- let aFav = fav.indexOf(a.id);
- if (aFav < 0) aFav = 999;
- let bFav = fav.indexOf(b.id);
- if (bFav < 0) bFav = 999;
- return bFav < aFav;
- });
- }
-
- // sort running first
- if (opt.APP_GRID_INCLUDE_DASH === 2) {
- appIcons.sort((a, b) => a.app.get_state() !== Shell.AppState.RUNNING && b.app.get_state() === Shell.AppState.RUNNING);
- }
-
- appIcons.forEach((icon, i) => {
- const page = Math.floor(i / itemsPerPage);
- const position = i % itemsPerPage;
- this._moveItem(icon, page, position);
- });
-
- this._orderedItems = appIcons;
- }
-
- this.emit('view-loaded');
- },
-
- _canAccept: function(source) {
- return (opt.APP_GRID_ORDER ? false : source instanceof AppDisplay.AppViewItem);
- },
-
- // GS <= 42 only, Adapt app grid so it can use all available space
- adaptToSize(width, height) {
- let box = new Clutter.ActorBox({
- x2: width,
- y2: height,
- });
- box = this.get_theme_node().get_content_box(box);
- box = this._scrollView.get_theme_node().get_content_box(box);
- box = this._grid.get_theme_node().get_content_box(box);
-
- const availWidth = box.get_width();
- const availHeight = box.get_height();
-
- const gridRatio = this._grid.layout_manager.columnsPerPage /
- this._grid.layout_manager.rowsPerPage;
- const spaceRatio = availWidth / availHeight;
- let pageWidth, pageHeight;
-
- if (spaceRatio > gridRatio * 1.1) {
- // Enough room for some preview
- pageHeight = availHeight;
- pageWidth = Math.ceil(availHeight * gridRatio);
-
- if (spaceRatio > gridRatio * 1.5) {
- // Ultra-wide layout, give some extra space for
- // the page area, but up to an extent.
- const extraPageSpace = Math.min(
- Math.floor((availWidth - pageWidth) / 2), 200); // AppDisplay.MAX_PAGE_PADDING == 200
- pageWidth += extraPageSpace;
- this._grid.layout_manager.pagePadding.left =
- Math.floor(extraPageSpace / 2);
- this._grid.layout_manager.pagePadding.right =
- Math.ceil(extraPageSpace / 2);
- }
- } else {
- // Not enough room, needs to shrink horizontally
- pageWidth = Math.ceil(availWidth * 0.95); // width limiter, original is 0.8
- pageHeight = availHeight;
- this._grid.layout_manager.pagePadding.left =
- Math.floor(availWidth * 0.02);
- this._grid.layout_manager.pagePadding.right =
- Math.ceil(availWidth * 0.02);
- }
-
- this._grid.adaptToSize(pageWidth, pageHeight);
-
- const leftPadding = Math.floor(
- (availWidth - this._grid.layout_manager.pageWidth) / 2);
- const rightPadding = Math.ceil(
- (availWidth - this._grid.layout_manager.pageWidth) / 2);
- const topPadding = Math.floor(
- (availHeight - this._grid.layout_manager.pageHeight) / 2);
- const bottomPadding = Math.ceil(
- (availHeight - this._grid.layout_manager.pageHeight) / 2);
-
- this._scrollView.content_padding = new Clutter.Margin({
- left: leftPadding,
- right: rightPadding,
- top: topPadding,
- bottom: bottomPadding,
- });
-
- this._availWidth = availWidth;
- this._availHeight = availHeight;
-
- this._pageIndicatorOffset = leftPadding;
- this._pageArrowOffset = Math.max(
- leftPadding - 80, 0); // 80 is AppDisplay.PAGE_PREVIEW_MAX_ARROW_OFFSET
- }
-}
-
-var BaseAppViewGridLayout = {
- _getIndicatorsWidth(box) {
- const [width, height] = box.get_size();
- const arrows = [
- this._nextPageArrow,
- this._previousPageArrow,
- ];
-
- const minArrowsWidth = arrows.reduce(
- (previousWidth, accessory) => {
- const [min] = accessory.get_preferred_width(height);
- return Math.max(previousWidth, min);
- }, 0);
-
- const idealIndicatorWidth = (width * 0.1/*PAGE_PREVIEW_RATIO*/) / 2;
-
- return Math.max(idealIndicatorWidth, minArrowsWidth);
- }
-}
-
-// ------------------ AppDisplay.AppFolderDialog - injection --------------------------------------------------------------
-
-var AppFolderDialogInjections = {
- _init: function() {
- const iconSize = opt.APP_GRID_FOLDER_ICON_SIZE < 0 ? 96 : opt.APP_GRID_FOLDER_ICON_SIZE;
- let width = opt.APP_GRID_FOLDER_COLUMNS * (iconSize + 64);
- width = Math.max(640, Math.round(width + width / 10));
- let height = opt.APP_GRID_FOLDER_ROWS * (iconSize + 64) + 150;
- opt.APP_GRID_ALLOW_CUSTOM && this.child.set_style(`
- width: ${width}px;
- height: ${height}px;
- padding: 30px;
- `);
- }
-}
-
-
-// ------------------ AppDisplay.FolderGrid -----------------------------------------------------------------------
-
-var FolderView = {
- _createGrid: function() {
- let grid;
- if (shellVersion < 43) {
- grid = new FolderGrid();
- } else {
- grid = new FolderGrid43();
- }
- return grid;
- }
-}
-
-// folder columns and rows
-
-var FolderGrid = GObject.registerClass(
-class FolderGrid extends IconGrid.IconGrid {
- _init() {
- super._init({
- allow_incomplete_pages: false,
- columns_per_page: opt.APP_GRID_ALLOW_CUSTOM ? opt.APP_GRID_FOLDER_COLUMNS : 3,
- rows_per_page: opt.APP_GRID_ALLOW_CUSTOM ? opt.APP_GRID_FOLDER_ROWS : 3,
- page_halign: Clutter.ActorAlign.CENTER,
- page_valign: Clutter.ActorAlign.CENTER,
- });
-
- opt.APP_GRID_ALLOW_CUSTOM && this.set_style('column-spacing: 10px; row-spacing: 10px;');
- this.layout_manager.fixedIconSize = opt.APP_GRID_FOLDER_ICON_SIZE;
- }
-
- adaptToSize(width, height) {
- this.layout_manager.adaptToSize(width, height);
- }
-});
-
-
-// only the first access to the const AppDisplay.AppGrid throws an error, so touch it before it's really needed
-let FolderGrid43;
-AppDisplay.AppGrid;
-if (AppDisplay.AppGrid) {
- FolderGrid43 = GObject.registerClass(
- class FolderGrid43 extends AppDisplay.AppGrid {
- _init() {
- super._init({
- allow_incomplete_pages: false,
- columns_per_page: opt.APP_GRID_ALLOW_CUSTOM ? opt.APP_GRID_FOLDER_COLUMNS : 3,
- rows_per_page: opt.APP_GRID_ALLOW_CUSTOM ? opt.APP_GRID_FOLDER_ROWS : 3,
- page_halign: Clutter.ActorAlign.CENTER,
- page_valign: Clutter.ActorAlign.CENTER,
- });
-
- opt.APP_GRID_ALLOW_CUSTOM && this.set_style('column-spacing: 10px; row-spacing: 10px;');
- this.layout_manager.fixedIconSize = opt.APP_GRID_FOLDER_ICON_SIZE;
-
- this.setGridModes([
- {
- rows: opt.APP_GRID_ALLOW_CUSTOM ? opt.APP_GRID_FOLDER_ROWS : 3,
- columns: opt.APP_GRID_ALLOW_CUSTOM ? opt.APP_GRID_FOLDER_COLUMNS : 3,
- },
- ]);
- }
-
- adaptToSize(width, height) {
- this.layout_manager.adaptToSize(width, height);
- }
- });
-
-}
-
-var FOLDER_DIALOG_ANIMATION_TIME = 200; // AppDisplay.FOLDER_DIALOG_ANIMATION_TIME
-var AppFolderDialog = {
- _zoomAndFadeIn: function() {
- let [sourceX, sourceY] =
- this._source.get_transformed_position();
- let [dialogX, dialogY] =
- this.child.get_transformed_position();
-
- this.child.set({
- translation_x: sourceX - dialogX,
- translation_y: sourceY - dialogY,
- scale_x: this._source.width / this.child.width,
- scale_y: this._source.height / this.child.height,
- opacity: 0,
- });
-
- this.ease({
- background_color: Clutter.Color.from_pixel(0x00000033), // DIALOG_SHADE_NORMAL
- duration: FOLDER_DIALOG_ANIMATION_TIME,
- mode: Clutter.AnimationMode.EASE_OUT_QUAD,
- });
-
-
- this.child.ease({
- translation_x: 0,
- translation_y: 0,
- scale_x: 1,
- scale_y: 1,
- opacity: 255,
- duration: FOLDER_DIALOG_ANIMATION_TIME,
- mode: Clutter.AnimationMode.EASE_OUT_QUAD,
- });
-
- this._needsZoomAndFade = false;
-
- if (this._sourceMappedId === 0) {
- this._sourceMappedId = this._source.connect(
- 'notify::mapped', this._zoomAndFadeOut.bind(this));
- }
- },
-}
-
-function _resetAppGrid(settings = null, key = null) {
- if (settings) {
- const currentValue = JSON.stringify(settings.get_value('app-picker-layout').deep_unpack());
- const emptyValue = JSON.stringify([]);
- if (key === 'app-picker-layout' && currentValue != emptyValue)
- return;
- }
- const appDisplay = Main.overview._overview._controls._appDisplay;
- const items = appDisplay._orderedItems;
- for (let i = items.length - 1; i > -1; i--) {
- Main.overview._overview._controls._appDisplay._removeItem(items[i]);
- }
- // redisplay only from callback
- if (settings)
- appDisplay._redisplay();
-}
-
-// ------------------ AppDisplay.AppIcon - override ---------------------------------------------------------------
-
-function _getWindowApp(metaWin) {
- const tracker = Shell.WindowTracker.get_default();
- return tracker.get_window_app(metaWin);
-}
-
-function _getAppLastUsedWindow(app) {
- let recentWin;
- global.display.get_tab_list(Meta.TabList.NORMAL_ALL, null).forEach(metaWin => {
- const winApp = _getWindowApp(metaWin);
- if (!recentWin && winApp == app) {
- recentWin = metaWin;
- }
- });
- return recentWin;
-}
-
-function _getAppRecentWorkspace(app) {
- const recentWin = _getAppLastUsedWindow(app)
- if (recentWin)
- return recentWin.get_workspace();
-
- return null;
-}
-
-var AppIcon = {
- activate: function(button) {
- const event = Clutter.get_current_event();
- const modifiers = event ? event.get_state() : 0;
- const isMiddleButton = button && button == Clutter.BUTTON_MIDDLE;
- const isCtrlPressed = (modifiers & Clutter.ModifierType.CONTROL_MASK) != 0;
- const isShiftPressed = (modifiers & Clutter.ModifierType.SHIFT_MASK) != 0;
- const openNewWindow = this.app.can_open_new_window() &&
- this.app.state == Shell.AppState.RUNNING &&
- (isCtrlPressed || isMiddleButton);
-
- const currentWS = global.workspace_manager.get_active_workspace();
- const appRecentWorkspace = _getAppRecentWorkspace(this.app);
-
- let targetWindowOnCurrentWs = false;
- if (opt.DASH_FOLLOW_RECENT_WIN) {
- targetWindowOnCurrentWs = appRecentWorkspace === currentWS;
- } else {
- this.app.get_windows().forEach(
- w => targetWindowOnCurrentWs = targetWindowOnCurrentWs || (w.get_workspace() === currentWS)
- );
- }
-
- if ((this.app.state == Shell.AppState.STOPPED || openNewWindow) && !isShiftPressed)
- this.animateLaunch();
-
- if (openNewWindow) {
- this.app.open_new_window(-1);
- // if the app has more than one window (option: and has no window on the current workspace),
- // don't activate the app, only move the overview to the workspace with the app's recent window
- } else if (opt.DASH_SHOW_WINS_BEFORE && !isShiftPressed && this.app.get_n_windows() > 1 && !targetWindowOnCurrentWs) {
- this._scroll = true;
- this._scrollTime = Date.now();
- //const appWS = this.app.get_windows()[0].get_workspace();
- Main.wm.actionMoveWorkspace(appRecentWorkspace);
- Main.overview.dash.showAppsButton.checked = false;
- return;
- } else if (opt.DASH_SHIFT_CLICK_MV && isShiftPressed && this.app.get_windows().length) {
- this._moveAppToCurrentWorkspace();
- return;
- } else if (isShiftPressed) {
- return;
- } else {
- this.app.activate();
- }
-
- Main.overview.hide();
- },
-
- _moveAppToCurrentWorkspace: function() {
- this.app.get_windows().forEach(w => w.change_workspace(global.workspace_manager.get_active_workspace()));
- },
-
- popupMenu: function(side = St.Side.LEFT) {
- if (shellVersion >= 42)
- this.setForcedHighlight(true);
- this._removeMenuTimeout();
- this.fake_release();
-
- if (!this._getWindowsOnCurrentWs) {
- this._getWindowsOnCurrentWs = function() {
- const winList = [];
- this.app.get_windows().forEach(w => {
- if(w.get_workspace() === global.workspace_manager.get_active_workspace()) winList.push(w)
- });
- return winList;
- };
-
- this._windowsOnOtherWs = function() {
- return (this.app.get_windows().length - this._getWindowsOnCurrentWs().length) > 0;
- };
- }
-
- if (!this._menu) {
- this._menu = new AppMenu(this, side, {
- favoritesSection: true,
- showSingleWindows: true,
- });
-
- this._menu.setApp(this.app);
- this._openSigId = this._menu.connect('open-state-changed', (menu, isPoppedUp) => {
- if (!isPoppedUp)
- this._onMenuPoppedDown();
- });
- //Main.overview.connectObject('hiding',
- this._hidingSigId = Main.overview.connect('hiding',
- () => this._menu.close(), this);
-
- Main.uiGroup.add_actor(this._menu.actor);
- this._menuManager.addMenu(this._menu);
- }
-
- // once the menu is created, it stays unchanged and we need to modify our items based on current situation
- if (this._addedMenuItems && this._addedMenuItems.length) {
- this._addedMenuItems.forEach(i => i.destroy());
- }
-
- const popupItems =[];
-
- const separator = new PopupMenu.PopupSeparatorMenuItem();
- this._menu.addMenuItem(separator);
-
- if (this.app.get_n_windows()) {
- if (/*opt.APP_MENU_FORCE_QUIT*/true) {
- popupItems.push([_('Force Quit'), () => {
- this.app.get_windows()[0].kill();
- }]);
- }
-
- if (/*opt.APP_MENU_CLOSE_WS*/true) {
- const nWin = this._getWindowsOnCurrentWs().length;
- if (nWin) {
- popupItems.push([_(`Close ${nWin} Windows on Current Workspace`), () => {
- const windows = this._getWindowsOnCurrentWs();
- let time = global.get_current_time();
- for (let win of windows) {
- // increase time by 1 ms for each window to avoid errors from GS
- win.delete(time++);
- }
- }]);
- }
- }
-
- if (/*opt.APP_MENU_MV_TO_WS && */this._windowsOnOtherWs()) {
- popupItems.push([_('Move App to Current Workspace'), this._moveAppToCurrentWorkspace]);
- }
- }
-
- this._addedMenuItems = [];
- this._addedMenuItems.push(separator);
- popupItems.forEach(i => {
- let item = new PopupMenu.PopupMenuItem(i[0]);
- this._menu.addMenuItem(item);
- item.connect('activate', i[1].bind(this));
- this._addedMenuItems.push(item);
- });
-
- this.emit('menu-state-changed', true);
-
- this._menu.open(BoxPointer.PopupAnimation.FULL);
- this._menuManager.ignoreRelease();
- this.emit('sync-tooltip');
-
- return false;
- }
-}