summaryrefslogtreecommitdiff
path: root/raveos-theme/gnome/theme-data/extensions/installed/dash-to-dock@micxgx.gmail.com/dash.js
diff options
context:
space:
mode:
authorAlexanderCurl <alexc@alexc.hu>2026-04-18 17:46:06 +0100
committerAlexanderCurl <alexc@alexc.hu>2026-04-18 17:46:06 +0100
commit70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69 (patch)
treeab1123d4067c1b086dd6faa7ee4ea643236b565a /raveos-theme/gnome/theme-data/extensions/installed/dash-to-dock@micxgx.gmail.com/dash.js
parent5d94c0a7d44a2255b81815a52a7056a94a39842d (diff)
downloadRaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.tar.gz
RaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.zip
Replaced file structures for themes in the correct format
Diffstat (limited to 'raveos-theme/gnome/theme-data/extensions/installed/dash-to-dock@micxgx.gmail.com/dash.js')
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/dash-to-dock@micxgx.gmail.com/dash.js1177
1 files changed, 0 insertions, 1177 deletions
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/dash-to-dock@micxgx.gmail.com/dash.js b/raveos-theme/gnome/theme-data/extensions/installed/dash-to-dock@micxgx.gmail.com/dash.js
deleted file mode 100644
index 956bbeb..0000000
--- a/raveos-theme/gnome/theme-data/extensions/installed/dash-to-dock@micxgx.gmail.com/dash.js
+++ /dev/null
@@ -1,1177 +0,0 @@
-// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
-
-import {
- Clutter,
- Gio,
- GLib,
- GObject,
- Shell,
- St,
-} from './dependencies/gi.js';
-
-import {
- AppFavorites,
- Dash,
- DND,
- Main,
-} from './dependencies/shell/ui.js';
-
-import {
- Util,
-} from './dependencies/shell/misc.js';
-
-import {
- AppIcons,
- Docking,
- Theming,
- Utils,
-} from './imports.js';
-
-// module "Dash" did not export DASH_ANIMATION_TIME in old versions
-// so we just define it like it is defined in Dash;
-// taken from https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/dash.js
-const DASH_ANIMATION_TIME = Dash.DASH_ANIMATION_TIME ?? 200;
-const DASH_VISIBILITY_TIMEOUT = 3;
-
-const Labels = Object.freeze({
- SHOW_MOUNTS: Symbol('show-mounts'),
- FIRST_LAST_CHILD_WORKAROUND: Symbol('first-last-child-workaround'),
-});
-
-/**
- * Extend DashItemContainer
- *
- * - set label position based on dash orientation
- *
- */
-const DockDashItemContainer = GObject.registerClass(
-class DockDashItemContainer extends Dash.DashItemContainer {
- _init(position) {
- super._init();
-
- this.label?.add_style_class_name(Theming.PositionStyleClass[position]);
- if (Docking.DockManager.settings.customThemeShrink)
- this.label?.add_style_class_name('shrink');
- }
-
- showLabel() {
- return AppIcons.itemShowLabel.call(this);
- }
-
- // we override the method show taken from:
- // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/dash.js
- // in order to apply a little modification at the end of the animation
- // which makes sure that the icon background is not blurry
- show(animate) {
- if (this.child == null)
- return;
-
- this.ease({
- scale_x: 1,
- scale_y: 1,
- opacity: 255,
- duration: animate ? DASH_ANIMATION_TIME : 0,
- mode: Clutter.AnimationMode.EASE_OUT_QUAD,
- onComplete: () => {
- // when the animation is ended, we simulate
- // a hover to gain back focus and unblur the
- // background
- this.set_hover(true);
- },
- });
- }
-});
-
-const DockDashIconsVerticalLayout = GObject.registerClass(
- class DockDashIconsVerticalLayout extends Clutter.BoxLayout {
- _init() {
- super._init({
- orientation: Clutter.Orientation.VERTICAL,
- });
- }
-
- vfunc_get_preferred_height(container, forWidth) {
- const [natHeight] = super.vfunc_get_preferred_height(container, forWidth);
- return [natHeight, 0];
- }
- });
-
-
-const baseIconSizes = [16, 22, 24, 32, 48, 64, 96, 128];
-
-/**
- * This class is a fork of the upstream dash class (ui.dash.js)
- *
- * Summary of changes:
- * - disconnect global signals adding a destroy method;
- * - play animations even when not in overview mode
- * - set a maximum icon size
- * - show running and/or favorite applications
- * - hide showApps label when the custom menu is shown.
- * - add scrollview
- * ensure actor is visible on keyfocus inseid the scrollview
- * - add 128px icon size, might be useful for hidpi display
- * - sync minimization application target position.
- * - keep running apps ordered.
- */
-export const DockDash = GObject.registerClass({
- Properties: {
- 'requires-visibility': GObject.ParamSpec.boolean(
- 'requires-visibility', 'requires-visibility', 'requires-visibility',
- GObject.ParamFlags.READWRITE,
- false),
- },
- Signals: {
- 'menu-opened': {},
- 'menu-closed': {},
- 'icon-size-changed': {},
- },
-}, class DockDash extends St.Widget {
- _init(monitorIndex) {
- // Initialize icon variables and size
- super._init({
- name: 'dash',
- offscreen_redirect: Clutter.OffscreenRedirect.ALWAYS,
- layout_manager: new Clutter.BinLayout(),
- });
-
- this._maxWidth = -1;
- this._maxHeight = -1;
- this.iconSize = Docking.DockManager.settings.dashMaxIconSize;
- this._availableIconSizes = baseIconSizes;
- this._shownInitially = false;
- this._initializeIconSize(this.iconSize);
- this._signalsHandler = new Utils.GlobalSignalsHandler(this);
-
- this._separator = null;
-
- this._monitorIndex = monitorIndex;
- this._position = Utils.getPosition();
- this._isHorizontal = (this._position === St.Side.TOP) ||
- (this._position === St.Side.BOTTOM);
-
- this._dragPlaceholder = null;
- this._dragPlaceholderPos = -1;
- this._animatingPlaceholdersCount = 0;
- this._showLabelTimeoutId = 0;
- this._resetHoverTimeoutId = 0;
- this._labelShowing = false;
-
- this._dashContainer = new St.BoxLayout({
- name: 'dashtodockDashContainer',
- x_align: Clutter.ActorAlign.CENTER,
- y_align: Clutter.ActorAlign.CENTER,
- vertical: !this._isHorizontal,
- y_expand: this._isHorizontal,
- x_expand: !this._isHorizontal,
- });
-
- this._scrollView = new St.ScrollView({
- name: 'dashtodockDashScrollview',
- hscrollbar_policy: this._isHorizontal ? St.PolicyType.EXTERNAL : St.PolicyType.NEVER,
- vscrollbar_policy: this._isHorizontal ? St.PolicyType.NEVER : St.PolicyType.EXTERNAL,
- x_expand: this._isHorizontal,
- y_expand: !this._isHorizontal,
- enable_mouse_scrolling: false,
- });
-
- this._scrollView.connect('scroll-event', this._onScrollEvent.bind(this));
-
- this._boxContainer = new St.BoxLayout({
- name: 'dashtodockBoxContainer',
- x_align: Clutter.ActorAlign.FILL,
- y_align: Clutter.ActorAlign.FILL,
- vertical: !this._isHorizontal,
- });
- this._boxContainer.add_style_class_name(Theming.PositionStyleClass[this._position]);
-
- const rtl = Clutter.get_default_text_direction() === Clutter.TextDirection.RTL;
- this._box = new St.BoxLayout({
- vertical: !this._isHorizontal,
- clip_to_allocation: false,
- ...!this._isHorizontal ? {layout_manager: new DockDashIconsVerticalLayout()} : {},
- x_align: rtl ? Clutter.ActorAlign.END : Clutter.ActorAlign.START,
- y_align: this._isHorizontal ? Clutter.ActorAlign.CENTER : Clutter.ActorAlign.START,
- y_expand: !this._isHorizontal,
- x_expand: this._isHorizontal,
- });
- this._box._delegate = this;
- this._boxContainer.add_child(this._box);
- Utils.addActor(this._scrollView, this._boxContainer);
- this._dashContainer.add_child(this._scrollView);
-
- this._showAppsIcon = new AppIcons.DockShowAppsIcon(this._position);
- this._showAppsIcon.show(false);
- this._showAppsIcon.icon.setIconSize(this.iconSize);
- this._showAppsIcon.x_expand = false;
- this._showAppsIcon.y_expand = false;
- this.showAppsButton.connect('notify::hover', a => {
- if (this._showAppsIcon.get_parent() === this._boxContainer)
- this._ensureItemVisibility(a);
- });
- if (!this._isHorizontal)
- this._showAppsIcon.y_align = Clutter.ActorAlign.START;
- this._hookUpLabel(this._showAppsIcon);
- this._showAppsIcon.connect('menu-state-changed', (_icon, opened) => {
- this._itemMenuStateChanged(this._showAppsIcon, opened);
- });
- this.updateShowAppsButton();
-
- this._background = new St.Widget({
- style_class: 'dash-background',
- y_expand: this._isHorizontal,
- x_expand: !this._isHorizontal,
- });
-
- const sizerBox = new Clutter.Actor();
- sizerBox.add_constraint(new Clutter.BindConstraint({
- source: this._isHorizontal ? this._showAppsIcon.icon : this._dashContainer,
- coordinate: Clutter.BindCoordinate.HEIGHT,
- }));
- sizerBox.add_constraint(new Clutter.BindConstraint({
- source: this._isHorizontal ? this._dashContainer : this._showAppsIcon.icon,
- coordinate: Clutter.BindCoordinate.WIDTH,
- }));
- this._background.add_child(sizerBox);
-
- this.add_child(this._background);
- this.add_child(this._dashContainer);
-
- this._workId = Main.initializeDeferredWork(this._box, this._redisplay.bind(this));
-
- this._shellSettings = new Gio.Settings({
- schema_id: 'org.gnome.shell',
- });
-
- this._appSystem = Shell.AppSystem.get_default();
-
- this.iconAnimator = new Docking.IconAnimator(this);
-
- this._signalsHandler.add([
- this._appSystem,
- 'installed-changed',
- () => {
- AppFavorites.getAppFavorites().reload();
- this._queueRedisplay();
- },
- ], [
- AppFavorites.getAppFavorites(),
- 'changed',
- this._queueRedisplay.bind(this),
- ], [
- this._appSystem,
- 'app-state-changed',
- this._queueRedisplay.bind(this),
- ], [
- Main.overview,
- 'item-drag-begin',
- this._onItemDragBegin.bind(this),
- ], [
- Main.overview,
- 'item-drag-end',
- this._onItemDragEnd.bind(this),
- ], [
- Main.overview,
- 'item-drag-cancelled',
- this._onItemDragCancelled.bind(this),
- ], [
- Main.overview,
- 'window-drag-begin',
- this._onWindowDragBegin.bind(this),
- ], [
- Main.overview,
- 'window-drag-cancelled',
- this._onWindowDragEnd.bind(this),
- ], [
- Main.overview,
- 'window-drag-end',
- this._onWindowDragEnd.bind(this),
- ]);
-
- this.connect('destroy', this._onDestroy.bind(this));
- }
-
- vfunc_get_preferred_height(forWidth) {
- const [minHeight, natHeight] = super.vfunc_get_preferred_height.call(this, forWidth);
- if (!this._isHorizontal && this._maxHeight !== -1 && natHeight > this._maxHeight)
- return [minHeight, this._maxHeight];
- else
- return [minHeight, natHeight];
- }
-
- vfunc_get_preferred_width(forHeight) {
- const [minWidth, natWidth] = super.vfunc_get_preferred_width.call(this, forHeight);
- if (this._isHorizontal && this._maxWidth !== -1 && natWidth > this._maxWidth)
- return [minWidth, this._maxWidth];
- else
- return [minWidth, natWidth];
- }
-
- get _container() {
- return this._dashContainer;
- }
-
- _onDestroy() {
- this.iconAnimator.destroy();
-
- if (this._requiresVisibilityTimeout) {
- GLib.source_remove(this._requiresVisibilityTimeout);
- delete this._requiresVisibilityTimeout;
- }
-
- if (this._ensureActorVisibilityTimeoutId) {
- GLib.source_remove(this._ensureActorVisibilityTimeoutId);
- delete this._ensureActorVisibilityTimeoutId;
- }
- }
-
-
- _onItemDragBegin(...args) {
- return Dash.Dash.prototype._onItemDragBegin.call(this, ...args);
- }
-
- _onItemDragCancelled(...args) {
- return Dash.Dash.prototype._onItemDragCancelled.call(this, ...args);
- }
-
- _onItemDragEnd(...args) {
- return Dash.Dash.prototype._onItemDragEnd.call(this, ...args);
- }
-
- _endItemDrag(...args) {
- return Dash.Dash.prototype._endItemDrag.call(this, ...args);
- }
-
- _onItemDragMotion(...args) {
- return Dash.Dash.prototype._onItemDragMotion.call(this, ...args);
- }
-
- _appIdListToHash(...args) {
- return Dash.Dash.prototype._appIdListToHash.call(this, ...args);
- }
-
- _queueRedisplay(...args) {
- return Dash.Dash.prototype._queueRedisplay.call(this, ...args);
- }
-
- _hookUpLabel(...args) {
- return Dash.Dash.prototype._hookUpLabel.call(this, ...args);
- }
-
- _syncLabel(...args) {
- return Dash.Dash.prototype._syncLabel.call(this, ...args);
- }
-
- _clearDragPlaceholder(...args) {
- return Dash.Dash.prototype._clearDragPlaceholder.call(this, ...args);
- }
-
- _clearEmptyDropTarget(...args) {
- return Dash.Dash.prototype._clearEmptyDropTarget.call(this, ...args);
- }
-
- handleDragOver(source, actor, x, y, time) {
- let ret;
- if (this._isHorizontal) {
- ret = Dash.Dash.prototype.handleDragOver.call(this, source, actor, x, y, time);
-
- if (ret === DND.DragMotionResult.CONTINUE)
- return ret;
- } else {
- const propertyInjections = new Utils.PropertyInjectionsHandler();
- propertyInjections.add(this._box, 'width', {
- get: () => this._box.get_children().reduce((a, c) => a + c.height, 0),
- });
-
- if (this._dragPlaceholder) {
- propertyInjections.add(this._dragPlaceholder, 'width', {
- get: () => this._dragPlaceholder.height,
- });
- }
-
- ret = Dash.Dash.prototype.handleDragOver.call(this, source, actor, y, x, time);
- propertyInjections.destroy();
-
- if (ret === DND.DragMotionResult.CONTINUE)
- return ret;
-
- if (this._dragPlaceholder) {
- this._dragPlaceholder.child.set_width(this.iconSize / 2);
- this._dragPlaceholder.child.set_height(this.iconSize);
-
- let pos = this._dragPlaceholderPos;
- if (this._isHorizontal &&
- Clutter.get_default_text_direction() === Clutter.TextDirection.RTL)
- pos = this._box.get_children() - 1 - pos;
-
- if (pos !== this._dragPlaceholderPos) {
- this._dragPlaceholderPos = pos;
- this._box.set_child_at_index(this._dragPlaceholder,
- this._dragPlaceholderPos);
- }
- }
- }
-
- if (this._dragPlaceholder) {
- // Ensure the next and previous icon are visible when moving the
- // placeholder (we're assuming there's room for both of them)
- const children = this._box.get_children();
- if (this._dragPlaceholderPos > 0) {
- ensureActorVisibleInScrollView(this._scrollView,
- children[this._dragPlaceholderPos - 1]);
- }
-
- if (this._dragPlaceholderPos >= -1 &&
- this._dragPlaceholderPos < children.length - 1) {
- ensureActorVisibleInScrollView(this._scrollView,
- children[this._dragPlaceholderPos + 1]);
- }
- }
-
- return ret;
- }
-
- acceptDrop(...args) {
- return Dash.Dash.prototype.acceptDrop.call(this, ...args);
- }
-
- _onWindowDragBegin(...args) {
- return Dash.Dash.prototype._onWindowDragBegin.call(this, ...args);
- }
-
- _onWindowDragEnd(...args) {
- return Dash.Dash.prototype._onWindowDragEnd.call(this, ...args);
- }
-
- _onScrollEvent(actor, event) {
- // If scroll is not used because the icon is resized, let the scroll event propagate.
- if (!Docking.DockManager.settings.iconSizeFixed)
- return Clutter.EVENT_PROPAGATE;
-
- // reset timeout to avid conflicts with the mousehover event
- this._ensureItemVisibility(null);
-
- // Skip to avoid double events mouse
- if (event.get_scroll_direction() !== Clutter.ScrollDirection.SMOOTH)
- return Clutter.EVENT_STOP;
-
-
- let adjustment, delta = 0;
-
- if (this._isHorizontal) {
- adjustment = this._scrollView.get_hadjustment
- ? this._scrollView.get_hadjustment()
- : this._scrollView.get_hscroll_bar().get_adjustment();
- } else {
- adjustment = this._scrollView.get_vadjustment
- ? this._scrollView.get_vadjustment()
- : this._scrollView.get_vscroll_bar().get_adjustment();
- }
-
- const increment = adjustment.step_increment;
- const [dx, dy] = event.get_scroll_delta();
-
- if (this._isHorizontal)
- delta = (Math.abs(dx) > Math.abs(dy) ? dx : dy) * increment;
- else
- delta = dy * increment;
-
- const value = adjustment.get_value();
-
- // TODO: Remove this if possible.
- if (Number.isNaN(value))
- adjustment.set_value(delta);
- else
- adjustment.set_value(value + delta);
-
- return Clutter.EVENT_STOP;
- }
-
- _ensureItemVisibility(actor) {
- if (actor?.hover) {
- const destroyId =
- actor.connect('destroy', () => this._ensureItemVisibility(null));
- this._ensureActorVisibilityTimeoutId = GLib.timeout_add(
- GLib.PRIORITY_DEFAULT, 100, () => {
- actor.disconnect(destroyId);
- ensureActorVisibleInScrollView(this._scrollView, actor);
- this._ensureActorVisibilityTimeoutId = 0;
- return GLib.SOURCE_REMOVE;
- });
- } else if (this._ensureActorVisibilityTimeoutId) {
- GLib.source_remove(this._ensureActorVisibilityTimeoutId);
- this._ensureActorVisibilityTimeoutId = 0;
- }
- }
-
- _createAppItem(app) {
- const appIcon = new AppIcons.makeAppIcon(app, this._monitorIndex, this.iconAnimator);
-
- if (appIcon._draggable) {
- appIcon._draggable.connect('drag-begin', () => {
- appIcon.opacity = 50;
- });
- appIcon._draggable.connect('drag-end', () => {
- appIcon.opacity = 255;
- });
- }
-
- appIcon.connectObject('menu-state-changed', (_, opened) => {
- this._itemMenuStateChanged(item, opened);
- }, this);
-
- const item = new DockDashItemContainer(this._position);
- item.setChild(appIcon);
-
- appIcon.connectObject('notify::hover', a => this._ensureItemVisibility(a), this);
- appIcon.connectObject('clicked', actor => {
- ensureActorVisibleInScrollView(this._scrollView, actor);
- }, this);
-
- appIcon.connectObject('key-focus-in', actor => {
- const [xShift, yShift] = ensureActorVisibleInScrollView(this._scrollView, actor);
-
- // This signal is triggered also by mouse click. The popup menu is opened at the original
- // coordinates. Thus correct for the shift which is going to be applied to the scrollview.
- if (appIcon._menu) {
- appIcon._menu._boxPointer.xOffset = -xShift;
- appIcon._menu._boxPointer.yOffset = -yShift;
- }
- }, this);
-
- appIcon.connectObject('notify::focused', () => {
- const {settings} = Docking.DockManager;
- if (appIcon.focused && settings.scrollToFocusedApplication)
- ensureActorVisibleInScrollView(this._scrollView, item);
- }, this);
-
- appIcon.connectObject('notify::urgent', () => {
- if (appIcon.urgent) {
- ensureActorVisibleInScrollView(this._scrollView, item);
- if (Docking.DockManager.settings.showDockUrgentNotify)
- this._requireVisibility();
- }
- }, this);
-
- // Override default AppIcon label_actor, now the
- // accessible_name is set at DashItemContainer.setLabelText
- appIcon.label_actor = null;
- item.setLabelText(app.get_name());
-
- appIcon.icon.setIconSize(this.iconSize);
- this._hookUpLabel(item, appIcon);
-
- item.connectObject('notify::position', () => appIcon.updateIconGeometry(), appIcon);
- item.connectObject('notify::size', () => appIcon.updateIconGeometry(), appIcon);
-
- return item;
- }
-
- _requireVisibility() {
- this.requiresVisibility = true;
-
- if (this._requiresVisibilityTimeout)
- GLib.source_remove(this._requiresVisibilityTimeout);
-
- this._requiresVisibilityTimeout = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT,
- DASH_VISIBILITY_TIMEOUT, () => {
- this._requiresVisibilityTimeout = 0;
- this.requiresVisibility = false;
- });
- }
-
- /**
- * Return an array with the "proper" appIcons currently in the dash
- */
- getAppIcons() {
- // Only consider children which are "proper"
- // icons (i.e. ignoring drag placeholders) and which are not
- // animating out (which means they will be destroyed at the end of
- // the animation)
- const iconChildren = this._box.get_children().filter(actor => {
- return actor.child &&
- !!actor.child.icon &&
- !actor.animatingOut;
- });
-
- const appIcons = iconChildren.map(actor => {
- return actor.child;
- });
-
- return appIcons;
- }
-
- _itemMenuStateChanged(item, opened) {
- Dash.Dash.prototype._itemMenuStateChanged.call(this, item, opened);
-
- if (opened) {
- this.emit('menu-opened');
- } else {
- // I want to listen from outside when a menu is closed. I used to
- // add a custom signal to the appIcon, since gnome 3.8 the signal
- // calling this callback was added upstream.
- this.emit('menu-closed');
- }
- }
-
- _adjustIconSize() {
- // For the icon size, we only consider children which are "proper"
- // icons (i.e. ignoring drag placeholders) and which are not
- // animating out (which means they will be destroyed at the end of
- // the animation)
- const iconChildren = this._box.get_children().filter(actor => {
- return actor.child &&
- actor.child._delegate &&
- actor.child._delegate.icon &&
- !actor.animatingOut;
- });
-
- iconChildren.push(this._showAppsIcon);
-
- if (this._maxWidth === -1 && this._maxHeight === -1)
- return;
-
- // Check if the container is present in the stage. This avoids critical
- // errors when unlocking the screen
- if (!this._container.get_stage())
- return;
-
- const themeNode = this._dashContainer.get_theme_node();
- const maxAllocation = new Clutter.ActorBox({
- x1: 0,
- y1: 0,
- x2: this._isHorizontal ? this._maxWidth : 42 /* whatever */,
- y2: this._isHorizontal ? 42 : this._maxHeight,
- });
- const maxContent = themeNode.get_content_box(maxAllocation);
- let availSpace;
- if (this._isHorizontal)
- availSpace = maxContent.get_width();
- else
- availSpace = maxContent.get_height();
-
- const spacing = themeNode.get_length('spacing');
-
- const [{child: firstButton}] = iconChildren;
- const {child: firstIcon} = firstButton?.icon ?? {child: null};
-
- // if no icons there's nothing to adjust
- if (!firstIcon)
- return;
-
- // Enforce valid spacings during the size request
- firstIcon.ensure_style();
- const [, , iconWidth, iconHeight] = firstIcon.get_preferred_size();
- const [, , buttonWidth, buttonHeight] = firstButton.get_preferred_size();
-
- if (this._isHorizontal) {
- // Subtract icon padding and box spacing from the available width
- availSpace -= iconChildren.length * (buttonWidth - iconWidth) +
- (iconChildren.length - 1) * spacing;
-
- if (this._separator) {
- const [, , separatorWidth] = this._separator.get_preferred_size();
- availSpace -= separatorWidth + spacing;
- }
- } else {
- // Subtract icon padding and box spacing from the available height
- availSpace -= iconChildren.length * (buttonHeight - iconHeight) +
- (iconChildren.length - 1) * spacing;
-
- if (this._separator) {
- const [, , , separatorHeight] = this._separator.get_preferred_size();
- availSpace -= separatorHeight + spacing;
- }
- }
-
- const maxIconSize = availSpace / iconChildren.length;
- const {scaleFactor} = St.ThemeContext.get_for_stage(global.stage);
- const iconSizes = this._availableIconSizes.map(s => s * scaleFactor);
-
- let [newIconSize] = this._availableIconSizes;
- for (let i = 0; i < iconSizes.length; i++) {
- if (iconSizes[i] <= maxIconSize)
- newIconSize = this._availableIconSizes[i];
- }
-
- if (newIconSize === this.iconSize)
- return;
-
- const oldIconSize = this.iconSize;
- this.iconSize = newIconSize;
- this.emit('icon-size-changed');
-
- const scale = oldIconSize / newIconSize;
- for (let i = 0; i < iconChildren.length; i++) {
- const {icon} = iconChildren[i].child._delegate;
-
- // Set the new size immediately, to keep the icons' sizes
- // in sync with this.iconSize
- icon.setIconSize(this.iconSize);
-
- // Don't animate the icon size change when the overview
- // is transitioning, not visible or when initially filling
- // the dash
- if (!Main.overview.visible || Main.overview.animationInProgress ||
- !this._shownInitially)
- continue;
-
- const [targetWidth, targetHeight] = icon.icon.get_size();
-
- // Scale the icon's texture to the previous size and
- // tween to the new size
- icon.icon.set_size(icon.icon.width * scale,
- icon.icon.height * scale);
-
- icon.icon.ease({
- width: targetWidth,
- height: targetHeight,
- duration: DASH_ANIMATION_TIME,
- mode: Clutter.AnimationMode.EASE_OUT_QUAD,
- });
- }
-
- if (this._separator) {
- const animateProperties = this._isHorizontal
- ? {height: this.iconSize} : {width: this.iconSize};
-
- this._separator.ease({
- ...animateProperties,
- duration: DASH_ANIMATION_TIME,
- mode: Clutter.AnimationMode.EASE_OUT_QUAD,
- });
- }
- }
-
- _redisplay() {
- const favorites = AppFavorites.getAppFavorites().getFavoriteMap();
-
- let running = this._appSystem.get_running();
- const dockManager = Docking.DockManager.getDefault();
- const {settings} = dockManager;
-
- this._scrollView.set({
- xAlign: Clutter.ActorAlign.FILL,
- yAlign: Clutter.ActorAlign.FILL,
- });
- if (dockManager.settings.dockExtended) {
- if (!this._isHorizontal) {
- this._scrollView.yAlign = dockManager.settings.alwaysCenterIcons
- ? Clutter.ActorAlign.CENTER : Clutter.ActorAlign.START;
- } else {
- this._scrollView.xAlign = dockManager.settings.alwaysCenterIcons
- ? Clutter.ActorAlign.CENTER : Clutter.ActorAlign.START;
- }
- }
-
- if (settings.isolateWorkspaces ||
- settings.isolateMonitors) {
- // When using isolation, we filter out apps that have no windows in
- // the current workspace
- const monitorIndex = this._monitorIndex;
- running = running.filter(app =>
- AppIcons.getInterestingWindows(app.get_windows(), monitorIndex).length);
- }
-
- const children = this._box.get_children().filter(actor => {
- return actor.child &&
- actor.child._delegate &&
- actor.child._delegate.app;
- });
- // Apps currently in the dash
- let oldApps = children.map(actor => actor.child._delegate.app);
- // Apps supposed to be in the dash
- const newApps = [];
-
- const {showFavorites} = settings;
- if (showFavorites)
- newApps.push(...Object.values(favorites));
-
- if (settings.showRunning) {
- // We reorder the running apps so that they don't change position on the
- // dash with every redisplay() call
-
- // First: add the apps from the oldApps list that are still running
- oldApps.forEach(oldApp => {
- const index = running.indexOf(oldApp);
- if (index > -1) {
- const [app] = running.splice(index, 1);
- if (!showFavorites || !(app.get_id() in favorites))
- newApps.push(app);
- }
- });
-
- // Second: add the new apps
- running.forEach(app => {
- if (!showFavorites || !(app.get_id() in favorites))
- newApps.push(app);
- });
- }
-
- this._signalsHandler.removeWithLabel(Labels.SHOW_MOUNTS);
- if (dockManager.removables) {
- this._signalsHandler.addWithLabel(Labels.SHOW_MOUNTS,
- dockManager.removables, 'changed', this._queueRedisplay.bind(this));
- dockManager.removables.getApps().forEach(removable => {
- if (!newApps.includes(removable))
- newApps.push(removable);
- });
- } else {
- oldApps = oldApps.filter(app => !app.location || app.isTrash);
- }
-
- if (dockManager.trash) {
- const trashApp = dockManager.trash.getApp();
- if (!newApps.includes(trashApp))
- newApps.push(trashApp);
- } else {
- oldApps = oldApps.filter(app => !app.isTrash);
- }
-
- // Temporary remove the separator so that we don't compute to position icons
- const oldSeparatorPos = this._box.get_children().indexOf(this._separator);
- if (this._separator)
- this._box.remove_child(this._separator);
-
- // Figure out the actual changes to the list of items; we iterate
- // over both the list of items currently in the dash and the list
- // of items expected there, and collect additions and removals.
- // Moves are both an addition and a removal, where the order of
- // the operations depends on whether we encounter the position
- // where the item has been added first or the one from where it
- // was removed.
- // There is an assumption that only one item is moved at a given
- // time; when moving several items at once, everything will still
- // end up at the right position, but there might be additional
- // additions/removals (e.g. it might remove all the launchers
- // and add them back in the new order even if a smaller set of
- // additions and removals is possible).
- // If above assumptions turns out to be a problem, we might need
- // to use a more sophisticated algorithm, e.g. Longest Common
- // Subsequence as used by diff.
-
- const addedItems = [];
- const removedActors = [];
-
- let newIndex = 0;
- let oldIndex = 0;
- while (newIndex < newApps.length || oldIndex < oldApps.length) {
- const oldApp = oldApps.length > oldIndex ? oldApps[oldIndex] : null;
- const newApp = newApps.length > newIndex ? newApps[newIndex] : null;
-
- // No change at oldIndex/newIndex
- if (oldApp === newApp) {
- oldIndex++;
- newIndex++;
- continue;
- }
-
- // App removed at oldIndex
- if (oldApp && !newApps.includes(oldApp)) {
- removedActors.push(children[oldIndex]);
- oldIndex++;
- continue;
- }
-
- // App added at newIndex
- if (newApp && !oldApps.includes(newApp)) {
- addedItems.push({
- app: newApp,
- item: this._createAppItem(newApp),
- pos: newIndex,
- });
- newIndex++;
- continue;
- }
-
- // App moved
- const nextApp = newApps.length > newIndex + 1
- ? newApps[newIndex + 1] : null;
- const insertHere = nextApp && nextApp === oldApp;
- const alreadyRemoved = removedActors.reduce((result, actor) => {
- const removedApp = actor.child._delegate.app;
- return result || removedApp === newApp;
- }, false);
-
- if (insertHere || alreadyRemoved) {
- const newItem = this._createAppItem(newApp);
- addedItems.push({
- app: newApp,
- item: newItem,
- pos: newIndex + removedActors.length,
- });
- newIndex++;
- } else {
- removedActors.push(children[oldIndex]);
- oldIndex++;
- }
- }
-
- for (let i = 0; i < addedItems.length; i++) {
- this._box.insert_child_at_index(addedItems[i].item,
- addedItems[i].pos);
- }
-
- for (let i = 0; i < removedActors.length; i++) {
- const item = removedActors[i];
-
- // Don't animate item removal when the overview is transitioning
- // or hidden
- if (!Main.overview.animationInProgress)
- item.animateOutAndDestroy();
- else
- item.destroy();
- }
-
- // Update separator
- const nFavorites = Object.keys(favorites).length;
- const nIcons = children.length + addedItems.length - removedActors.length;
- if (nFavorites > 0 && nFavorites < nIcons) {
- if (!this._separator) {
- this._separator = new St.Widget({
- style_class: 'dash-separator',
- x_align: this._isHorizontal
- ? Clutter.ActorAlign.FILL : Clutter.ActorAlign.CENTER,
- y_align: this._isHorizontal
- ? Clutter.ActorAlign.CENTER : Clutter.ActorAlign.FILL,
- width: this._isHorizontal ? -1 : this.iconSize,
- height: this._isHorizontal ? this.iconSize : -1,
- reactive: true,
- track_hover: true,
- });
- this._separator.connect('notify::hover', a => this._ensureItemVisibility(a));
- }
- let pos = nFavorites + this._animatingPlaceholdersCount;
- if (this._dragPlaceholder)
- pos++;
- const removedFavorites = removedActors.filter(a =>
- children.indexOf(a) < oldSeparatorPos);
- pos += removedFavorites.length;
- this._box.insert_child_at_index(this._separator, pos);
- } else if (this._separator) {
- this._separator.destroy();
- this._separator = null;
- }
-
- this._adjustIconSize();
-
- // Skip animations on first run when adding the initial set
- // of items, to avoid all items zooming in at once
- const animate = this._shownInitially &&
- !Main.layoutManager._startingUp;
-
- if (!this._shownInitially)
- this._shownInitially = true;
-
- addedItems.forEach(({item}) => item.show(animate));
-
- // Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=692744
- // Without it, StBoxLayout may use a stale size cache
- this._box.queue_relayout();
-
- // This will update the size, and the corresponding number for each icon
- this._updateNumberOverlay();
-
- this.updateShowAppsButton();
- }
-
- _updateNumberOverlay() {
- const appIcons = this.getAppIcons();
- let counter = 1;
- appIcons.forEach(icon => {
- if (counter < 10) {
- icon.setNumberOverlay(counter);
- counter++;
- } else if (counter === 10) {
- icon.setNumberOverlay(0);
- counter++;
- } else {
- // No overlay after 10
- icon.setNumberOverlay(-1);
- }
- icon.updateNumberOverlay();
- });
- }
-
- toggleNumberOverlay(activate) {
- const appIcons = this.getAppIcons();
- appIcons.forEach(icon => {
- icon.toggleNumberOverlay(activate);
- });
- }
-
- _initializeIconSize(maxSize) {
- const maxAllowed = baseIconSizes[baseIconSizes.length - 1];
- maxSize = Math.min(maxSize, maxAllowed);
-
- if (Docking.DockManager.settings.iconSizeFixed) {
- this._availableIconSizes = [maxSize];
- } else {
- this._availableIconSizes = baseIconSizes.filter(val => {
- return val < maxSize;
- });
- this._availableIconSizes.push(maxSize);
- }
- }
-
- setIconSize(maxSize, doNotAnimate) {
- this._initializeIconSize(maxSize);
-
- if (doNotAnimate)
- this._shownInitially = false;
-
- this._queueRedisplay();
- }
-
- /**
- * Reset the displayed apps icon to maintain the correct order when changing
- * show favorites/show running settings
- */
- resetAppIcons() {
- const children = this._box.get_children().filter(actor => {
- return actor.child &&
- !!actor.child.icon;
- });
- for (let i = 0; i < children.length; i++) {
- const item = children[i];
- item.destroy();
- }
-
- // to avoid ugly animations, just suppress them like when dash is first loaded.
- this._shownInitially = false;
- this._redisplay();
- }
-
- get showAppsButton() {
- return this._showAppsIcon.toggleButton;
- }
-
- showShowAppsButton() {
- this._showAppsIcon.visible = true;
- this._showAppsIcon.show(true);
- this.updateShowAppsButton();
- }
-
- hideShowAppsButton() {
- this._showAppsIcon.visible = false;
- }
-
- setMaxSize(maxWidth, maxHeight) {
- if (this._maxWidth === maxWidth &&
- this._maxHeight === maxHeight)
- return;
-
- this._maxWidth = maxWidth;
- this._maxHeight = maxHeight;
- this._queueRedisplay();
- }
-
- updateShowAppsButton() {
- if (this._showAppsIcon.get_parent() && !this._showAppsIcon.visible)
- return;
-
- const {settings} = Docking.DockManager;
- const notifiedProperties = [];
- const showAppsContainer = settings.showAppsAlwaysInTheEdge || !settings.dockExtended
- ? this._dashContainer : this._boxContainer;
-
- this._signalsHandler.addWithLabel(Labels.FIRST_LAST_CHILD_WORKAROUND,
- showAppsContainer, 'notify',
- (_obj, pspec) => notifiedProperties.push(pspec.name));
-
- if (this._showAppsIcon.get_parent() !== showAppsContainer) {
- this._showAppsIcon.get_parent()?.remove_child(this._showAppsIcon);
-
- if (Docking.DockManager.settings.showAppsAtTop)
- showAppsContainer.insert_child_below(this._showAppsIcon, null);
- else
- showAppsContainer.insert_child_above(this._showAppsIcon, null);
- } else if (settings.showAppsAtTop) {
- showAppsContainer.set_child_below_sibling(this._showAppsIcon, null);
- } else {
- showAppsContainer.set_child_above_sibling(this._showAppsIcon, null);
- }
-
- this._signalsHandler.removeWithLabel(Labels.FIRST_LAST_CHILD_WORKAROUND);
-
- // This is indeed ugly, but we need to ensure that the last and first
- // visible widgets are re-computed by St, that is buggy because of a
- // mutter issue that is being fixed:
- // https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2047
- if (!notifiedProperties.includes('first-child'))
- showAppsContainer.notify('first-child');
- if (!notifiedProperties.includes('last-child'))
- showAppsContainer.notify('last-child');
- }
-});
-
-
-/**
- * This is a copy of the same function in utils.js, but also adjust horizontal scrolling
- * and perform few further checks on the current value to avoid changing the values when
- * it would be clamp to the current one in any case.
- * Return the amount of shift applied
- *
- * @param scrollView
- * @param actor
- */
-function ensureActorVisibleInScrollView(scrollView, actor) {
- // access to scrollView.[hv]scroll was deprecated in gnome 46
- // instead, adjustment can be accessed directly
- // keep old way for backwards compatibility (gnome <= 45)
- const vAdjustment = scrollView.vadjustment ?? scrollView.vscroll.adjustment;
- const hAdjustment = scrollView.hadjustment ?? scrollView.hscroll.adjustment;
- const {value: vValue0, pageSize: vPageSize, upper: vUpper} = vAdjustment;
- const {value: hValue0, pageSize: hPageSize, upper: hUpper} = hAdjustment;
- let [hValue, vValue] = [hValue0, vValue0];
- let vOffset = 0;
- let hOffset = 0;
-
- const fade = scrollView.get_effect('fade');
- if (fade) {
- vOffset = fade.fade_margins.top;
- hOffset = fade.fade_margins.left;
- }
-
- const box = actor.get_allocation_box();
- let {y1} = box, {y2} = box, {x1} = box, {x2} = box;
-
- let parent = actor.get_parent();
- while (parent !== scrollView) {
- if (!parent)
- throw new Error('Actor not in scroll view');
-
- const parentBox = parent.get_allocation_box();
- y1 += parentBox.y1;
- y2 += parentBox.y1;
- x1 += parentBox.x1;
- x2 += parentBox.x1;
- parent = parent.get_parent();
- }
-
- if (y1 < vValue + vOffset)
- vValue = Math.max(0, y1 - vOffset);
- else if (vValue < vUpper - vPageSize && y2 > vValue + vPageSize - vOffset)
- vValue = Math.min(vUpper - vPageSize, y2 + vOffset - vPageSize);
-
- if (x1 < hValue + hOffset)
- hValue = Math.max(0, x1 - hOffset);
- else if (hValue < hUpper - hPageSize && x2 > hValue + hPageSize - hOffset)
- hValue = Math.min(hUpper - hPageSize, x2 + hOffset - hPageSize);
-
- if (vValue !== vValue0) {
- vAdjustment.ease(vValue, {
- mode: Clutter.AnimationMode.EASE_OUT_QUAD,
- duration: Util.SCROLL_TIME,
- });
- }
-
- if (hValue !== hValue0) {
- hAdjustment.ease(hValue, {
- mode: Clutter.AnimationMode.EASE_OUT_QUAD,
- duration: Util.SCROLL_TIME,
- });
- }
-
- return [hValue - hValue0, vValue - vValue0];
-}