diff --git a/NEWS b/NEWS index 434dcd4..11fbe6d 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,16 @@ +3.38.2 +====== +* window-list: Honor changes in skip-taskbar property [Sergio; !130] +* window-list, workspace-indicator: Improve previews in workspace thumbs + [Florian; #260, !142] +* window-list, workspace-indicator: Adjust to 3.38 changes [Florian; !133] +* auto-move: Improve behavior on multi-monitor setups [Florian; !135] +* windowNavigator: Adjust to 3.38 changes [Thun; #259] +* Misc. bug fixes [Ray; !145] + +Contributors: + Sergio Costas, Florian Müllner, Thun Pin, Ray Strode + 3.38.1 ====== diff --git a/data/gnome-shell-sass/widgets/_app-grid.scss b/data/gnome-shell-sass/widgets/_app-grid.scss index c183cfe..c98980e 100644 --- a/data/gnome-shell-sass/widgets/_app-grid.scss +++ b/data/gnome-shell-sass/widgets/_app-grid.scss @@ -8,6 +8,10 @@ column-spacing: $base_spacing * 6; max-row-spacing: $base_spacing * 12; max-column-spacing: $base_spacing * 12; + page-padding-top: $base_padding * 6; + page-padding-bottom: $base_padding * 6; + page-padding-left: $base_padding * 6; + page-padding-right: $base_padding * 6; } /* App Icons */ @@ -71,6 +75,10 @@ & .icon-grid { row-spacing: $base_spacing * 2; column-spacing: $base_spacing * 5; + page-padding-top: 0; + page-padding-bottom: 0; + page-padding-left: 0; + page-padding-right: 0; } & .page-indicators { diff --git a/data/gnome-shell-sass/widgets/_dialogs.scss b/data/gnome-shell-sass/widgets/_dialogs.scss index fc77920..0f568b7 100644 --- a/data/gnome-shell-sass/widgets/_dialogs.scss +++ b/data/gnome-shell-sass/widgets/_dialogs.scss @@ -135,10 +135,6 @@ spacing: 8px; margin-bottom: 6px; - .polkit-dialog-user-icon { - border-radius: 99px; - background-size: contain; - } .polkit-dialog-user-root-label { color: $warning_color; } } diff --git a/extensions/auto-move-windows/extension.js b/extensions/auto-move-windows/extension.js index d99244c..b9bc3a0 100644 --- a/extensions/auto-move-windows/extension.js +++ b/extensions/auto-move-windows/extension.js @@ -116,10 +116,12 @@ let keepAliveWorkspaces = []; let foundNonEmpty = false; for (let i = this._workspaces.length - 1; i >= 0; i--) { - if (!foundNonEmpty) - foundNonEmpty = this._workspaces[i].list_windows().length > 0; - else if (!this._workspaces[i]._keepAliveId) + if (!foundNonEmpty) { + foundNonEmpty = this._workspaces[i].list_windows().some( + w => !w.is_on_all_workspaces()); + } else if (!this._workspaces[i]._keepAliveId) { keepAliveWorkspaces.push(this._workspaces[i]); + } } // make sure the original method only removes empty workspaces at the end diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js index 523ffb2..8babbae 100644 --- a/extensions/window-list/extension.js +++ b/extensions/window-list/extension.js @@ -352,6 +352,9 @@ super._init(perMonitor, monitorIndex); this.metaWindow = metaWindow; + this._skipTaskbarId = metaWindow.connect('notify::skip-taskbar', () => { + this._updateVisibility(); + }); this._updateVisibility(); this._windowTitle = new WindowTitle(this.metaWindow); @@ -412,6 +415,7 @@ _onDestroy() { super._onDestroy(); + this.metaWindow.disconnect(this._skipTaskbarId); this.metaWindow.disconnect(this._workspaceChangedId); global.display.disconnect(this._notifyFocusId); this._contextMenu.destroy(); @@ -783,9 +787,9 @@ }); this._dragBeginId = Main.xdndHandler.connect('drag-begin', - this._onDragBegin.bind(this)); + this._monitorDrag.bind(this)); this._dragEndId = Main.xdndHandler.connect('drag-end', - this._onDragEnd.bind(this)); + this._stopMonitoringDrag.bind(this)); this._dragMonitor = { dragMotion: this._onDragMotion.bind(this), }; @@ -948,9 +952,6 @@ } _onWindowAdded(ws, win) { - if (win.skip_taskbar) - return; - if (!this._grouped) this._checkGrouping(); @@ -1016,11 +1017,11 @@ } } - _onDragBegin() { + _monitorDrag() { DND.addDragMonitor(this._dragMonitor); } - _onDragEnd() { + _stopMonitoringDrag() { DND.removeDragMonitor(this._dragMonitor); this._removeActivateTimeout(); } @@ -1094,6 +1095,7 @@ global.display.disconnect(this._fullscreenChangedId); + this._stopMonitoringDrag(); Main.xdndHandler.disconnect(this._dragBeginId); Main.xdndHandler.disconnect(this._dragEndId); diff --git a/extensions/window-list/workspaceIndicator.js b/extensions/window-list/workspaceIndicator.js index ca3dc61..37d1ff0 100644 --- a/extensions/window-list/workspaceIndicator.js +++ b/extensions/window-list/workspaceIndicator.js @@ -24,27 +24,14 @@ this.connect('destroy', this._onDestroy.bind(this)); this._sizeChangedId = this._window.connect('size-changed', - this._relayout.bind(this)); + () => this.queue_relayout()); this._positionChangedId = this._window.connect('position-changed', - this._relayout.bind(this)); + () => { + this._updateVisible(); + this.queue_relayout(); + }); this._minimizedChangedId = this._window.connect('notify::minimized', - this._relayout.bind(this)); - this._monitorEnteredId = global.display.connect('window-entered-monitor', - this._relayout.bind(this)); - this._monitorLeftId = global.display.connect('window-left-monitor', - this._relayout.bind(this)); - - // Do initial layout when we get a parent - let id = this.connect('parent-set', () => { - this.disconnect(id); - if (!this.get_parent()) - return; - this._laterId = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => { - this._laterId = 0; - this._relayout(); - return false; - }); - }); + this._updateVisible.bind(this)); this._focusChangedId = global.display.connect('notify::focus-window', this._onFocusChanged.bind(this)); @@ -52,19 +39,15 @@ } // needed for DND - get realWindow() { - return this._window.get_compositor_private(); + get metaWindow() { + return this._window; } _onDestroy() { this._window.disconnect(this._sizeChangedId); this._window.disconnect(this._positionChangedId); this._window.disconnect(this._minimizedChangedId); - global.display.disconnect(this._monitorEnteredId); - global.display.disconnect(this._monitorLeftId); global.display.disconnect(this._focusChangedId); - if (this._laterId) - Meta.later_remove(this._laterId); } _onFocusChanged() { @@ -74,26 +57,42 @@ this.remove_style_class_name('active'); } - _relayout() { - let monitor = Main.layoutManager.findIndexForActor(this); - this.visible = monitor === this._window.get_monitor() && + _updateVisible() { + const monitor = Main.layoutManager.findIndexForActor(this); + const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor); + this.visible = this._window.get_frame_rect().overlap(workArea) && this._window.window_type !== Meta.WindowType.DESKTOP && this._window.showing_on_its_workspace(); - - if (!this.visible) - return; - - let workArea = Main.layoutManager.getWorkAreaForMonitor(monitor); - let hscale = this.get_parent().allocation.get_width() / workArea.width; - let vscale = this.get_parent().allocation.get_height() / workArea.height; - - let frameRect = this._window.get_frame_rect(); - this.set_size( - Math.round(Math.min(frameRect.width, workArea.width) * hscale), - Math.round(Math.min(frameRect.height, workArea.height) * vscale)); - this.set_position( - Math.round(frameRect.x * hscale), - Math.round(frameRect.y * vscale)); + } +}); + +let WorkspaceLayout = GObject.registerClass( +class WorkspaceLayout extends Clutter.LayoutManager { + vfunc_get_preferred_width() { + return [0, 0]; + } + + vfunc_get_preferred_height() { + return [0, 0]; + } + + vfunc_allocate(container, box) { + const monitor = Main.layoutManager.findIndexForActor(container); + const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor); + const hscale = box.get_width() / workArea.width; + const vscale = box.get_height() / workArea.height; + + for (const child of container) { + const childBox = new Clutter.ActorBox(); + const frameRect = child.metaWindow.get_frame_rect(); + childBox.set_size( + Math.round(Math.min(frameRect.width, workArea.width) * hscale), + Math.round(Math.min(frameRect.height, workArea.height) * vscale)); + childBox.set_origin( + Math.round((frameRect.x - workArea.x) * hscale), + Math.round((frameRect.y - workArea.y) * vscale)); + child.allocate(childBox); + } } }); @@ -103,7 +102,7 @@ super._init({ style_class: 'workspace', child: new Clutter.Actor({ - layout_manager: new Clutter.BinLayout(), + layout_manager: new WorkspaceLayout(), clip_to_allocation: true, }), }); @@ -134,16 +133,15 @@ } acceptDrop(source) { - if (!source.realWindow) + if (!source.metaWindow) return false; - let window = source.realWindow.get_meta_window(); - this._moveWindow(window); + this._moveWindow(source.metaWindow); return true; } handleDragOver(source) { - if (source.realWindow) + if (source.metaWindow) return DND.DragMotionResult.MOVE_DROP; else return DND.DragMotionResult.CONTINUE; diff --git a/extensions/windowsNavigator/extension.js b/extensions/windowsNavigator/extension.js index 088cd3f..e4513d8 100644 --- a/extensions/windowsNavigator/extension.js +++ b/extensions/windowsNavigator/extension.js @@ -1,45 +1,12 @@ /* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */ /* exported init */ -const { Clutter, GObject, St } = imports.gi; +const { Clutter, Graphene, GObject, St } = imports.gi; const Main = imports.ui.main; const Workspace = imports.ui.workspace; const WorkspacesView = imports.ui.workspacesView; -class MyWindowOverlay extends Workspace.WindowOverlay { - constructor(windowClone, parentActor) { - super(windowClone, parentActor); - - this._id = null; - this._text = new St.Label({ - style_class: 'extension-windowsNavigator-window-tooltip', - visible: false, - }); - parentActor.add_actor(this._text); - } - - showTooltip() { - this._parentActor.set_child_below_sibling(this._text, null); - this._text.show(); - this._text.text = (this._windowClone.slotId + 1).toString(); - } - - hideTooltip() { - if (this._text && this._text.visible) - this._text.hide(); - } - - relayout(animate) { - super.relayout(animate); - - let [cloneX, cloneY, cloneWidth_, cloneHeight_] = this._windowClone.slot; - - let textX = cloneX - 2; - let textY = cloneY - 2; - this._text.set_position(Math.floor(textX) + 5, Math.floor(textY) + 5); - this._parentActor.set_child_below_sibling(this._text, null); - } -} +const WINDOW_SLOT = 4; var MyWorkspace = GObject.registerClass( class MyWorkspace extends Workspace.Workspace { @@ -61,56 +28,88 @@ } } + vfunc_allocate(box) { + super.vfunc_allocate(box); + + if (this._tip) + this._tip.allocate_preferred_size(0, 0); + } + showTooltip() { - if (!this._tip || !this._actualGeometry) + if (!this._tip) return; this._tip.text = (this.metaWorkspace.index() + 1).toString(); - - // Hand code this instead of using _getSpacingAndPadding - // because that fails on empty workspaces - let node = this.get_theme_node(); - let padding = { - left: node.get_padding(St.Side.LEFT), - top: node.get_padding(St.Side.TOP), - bottom: node.get_padding(St.Side.BOTTOM), - right: node.get_padding(St.Side.RIGHT), - }; - - let area = Workspace.padArea(this._actualGeometry, padding); - this._tip.x = area.x; - this._tip.y = area.y; this._tip.show(); this.set_child_below_sibling(this._tip, null); } hideTooltip() { - if (!this._tip) - return; - if (!this._tip.get_parent()) - return; - this._tip.hide(); + if (this._tip) + this._tip.hide(); } getWindowWithTooltip(id) { - for (let i = 0; i < this._windows.length; i++) { - if (this._windows[i].slotId + 1 === id) - return this._windows[i].metaWindow; - } - return null; + const slot = this.layout_manager._windowSlots[id - 1]; + return slot ? slot[WINDOW_SLOT].metaWindow : null; } showWindowsTooltips() { - for (let i in this._windowOverlays) { - if (this._windowOverlays[i]) - this._windowOverlays[i].showTooltip(); + for (let i = 0; i < this.layout_manager._windowSlots.length; i++) { + if (this.layout_manager._windowSlots[i]) + this.layout_manager._windowSlots[i][WINDOW_SLOT].showTooltip(`${i + 1}`); } } hideWindowsTooltips() { - for (let i in this._windowOverlays) { - if (this._windowOverlays[i]) - this._windowOverlays[i].hideTooltip(); - } + for (let i in this.layout_manager._windowSlots) { + if (this.layout_manager._windowSlots[i]) + this.layout_manager._windowSlots[i][WINDOW_SLOT].hideTooltip(); + } + } + + // overriding _addWindowClone to apply the tooltip patch on the cloned + // windowPreview + _addWindowClone(metaWindow) { + const clone = super._addWindowClone(metaWindow); + + // appling the tooltip patch + (function patchPreview() { + this._text = new St.Label({ + style_class: 'extension-windowsNavigator-window-tooltip', + visible: false, + }); + + this._text.add_constraint(new Clutter.BindConstraint({ + source: this._borderCenter, + coordinate: Clutter.BindCoordinate.POSITION, + })); + this._text.add_constraint(new Clutter.AlignConstraint({ + source: this._borderCenter, + align_axis: Clutter.AlignAxis.X_AXIS, + pivot_point: new Graphene.Point({ x: 0.5, y: -1 }), + factor: this._closeButtonSide === St.Side.LEFT ? 1 : 0, + })); + this._text.add_constraint(new Clutter.AlignConstraint({ + source: this._borderCenter, + align_axis: Clutter.AlignAxis.Y_AXIS, + pivot_point: new Graphene.Point({ x: -1, y: 0.5 }), + factor: 0, + })); + + this.add_child(this._text); + }).call(clone); + + clone.showTooltip = function (text) { + this._text.set({ text }); + this._text.show(); + }; + + clone.hideTooltip = function () { + if (this._text && this._text.visible) + this._text.hide(); + }; + + return clone; } }); @@ -244,19 +243,16 @@ class Extension { constructor() { - this._origWindowOverlay = Workspace.WindowOverlay; this._origWorkspace = Workspace.Workspace; this._origWorkspacesView = WorkspacesView.WorkspacesView; } enable() { - Workspace.WindowOverlay = MyWindowOverlay; Workspace.Workspace = MyWorkspace; WorkspacesView.WorkspacesView = MyWorkspacesView; } disable() { - Workspace.WindowOverlay = this._origWindowOverlay; Workspace.Workspace = this._origWorkspace; WorkspacesView.WorkspacesView = this._origWorkspacesView; } diff --git a/extensions/workspace-indicator/extension.js b/extensions/workspace-indicator/extension.js index 6d13acf..76b35df 100644 --- a/extensions/workspace-indicator/extension.js +++ b/extensions/workspace-indicator/extension.js @@ -30,27 +30,14 @@ this.connect('destroy', this._onDestroy.bind(this)); this._sizeChangedId = this._window.connect('size-changed', - this._relayout.bind(this)); + () => this.queue_relayout()); this._positionChangedId = this._window.connect('position-changed', - this._relayout.bind(this)); + () => { + this._updateVisible(); + this.queue_relayout(); + }); this._minimizedChangedId = this._window.connect('notify::minimized', - this._relayout.bind(this)); - this._monitorEnteredId = global.display.connect('window-entered-monitor', - this._relayout.bind(this)); - this._monitorLeftId = global.display.connect('window-left-monitor', - this._relayout.bind(this)); - - // Do initial layout when we get a parent - let id = this.connect('parent-set', () => { - this.disconnect(id); - if (!this.get_parent()) - return; - this._laterId = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => { - this._laterId = 0; - this._relayout(); - return false; - }); - }); + this._updateVisible.bind(this)); this._focusChangedId = global.display.connect('notify::focus-window', this._onFocusChanged.bind(this)); @@ -58,19 +45,15 @@ } // needed for DND - get realWindow() { - return this._window.get_compositor_private(); + get metaWindow() { + return this._window; } _onDestroy() { this._window.disconnect(this._sizeChangedId); this._window.disconnect(this._positionChangedId); this._window.disconnect(this._minimizedChangedId); - global.display.disconnect(this._monitorEnteredId); - global.display.disconnect(this._monitorLeftId); global.display.disconnect(this._focusChangedId); - if (this._laterId) - Meta.later_remove(this._laterId); } _onFocusChanged() { @@ -80,26 +63,42 @@ this.remove_style_class_name('active'); } - _relayout() { - let monitor = Main.layoutManager.findIndexForActor(this); - this.visible = monitor === this._window.get_monitor() && + _updateVisible() { + const monitor = Main.layoutManager.findIndexForActor(this); + const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor); + this.visible = this._window.get_frame_rect().overlap(workArea) && this._window.window_type !== Meta.WindowType.DESKTOP && this._window.showing_on_its_workspace(); - - if (!this.visible) - return; - - let workArea = Main.layoutManager.getWorkAreaForMonitor(monitor); - let hscale = this.get_parent().allocation.get_width() / workArea.width; - let vscale = this.get_parent().allocation.get_height() / workArea.height; - - let frameRect = this._window.get_frame_rect(); - this.set_size( - Math.round(Math.min(frameRect.width, workArea.width) * hscale), - Math.round(Math.min(frameRect.height, workArea.height) * vscale)); - this.set_position( - Math.round(frameRect.x * hscale), - Math.round(frameRect.y * vscale)); + } +}); + +let WorkspaceLayout = GObject.registerClass( +class WorkspaceLayout extends Clutter.LayoutManager { + vfunc_get_preferred_width() { + return [0, 0]; + } + + vfunc_get_preferred_height() { + return [0, 0]; + } + + vfunc_allocate(container, box) { + const monitor = Main.layoutManager.findIndexForActor(container); + const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor); + const hscale = box.get_width() / workArea.width; + const vscale = box.get_height() / workArea.height; + + for (const child of container) { + const childBox = new Clutter.ActorBox(); + const frameRect = child.metaWindow.get_frame_rect(); + childBox.set_size( + Math.round(Math.min(frameRect.width, workArea.width) * hscale), + Math.round(Math.min(frameRect.height, workArea.height) * vscale)); + childBox.set_origin( + Math.round((frameRect.x - workArea.x) * hscale), + Math.round((frameRect.y - workArea.y) * vscale)); + child.allocate(childBox); + } } }); @@ -109,7 +108,7 @@ super._init({ style_class: 'workspace', child: new Clutter.Actor({ - layout_manager: new Clutter.BinLayout(), + layout_manager: new WorkspaceLayout(), clip_to_allocation: true, }), }); @@ -140,16 +139,15 @@ } acceptDrop(source) { - if (!source.realWindow) + if (!source.metaWindow) return false; - let window = source.realWindow.get_meta_window(); - this._moveWindow(window); + this._moveWindow(source.metaWindow); return true; } handleDragOver(source) { - if (source.realWindow) + if (source.metaWindow) return DND.DragMotionResult.MOVE_DROP; else return DND.DragMotionResult.CONTINUE; diff --git a/meson.build b/meson.build index f07b82e..2e26532 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('gnome-shell-extensions', - version: '3.38.1', + version: '3.38.2', meson_version: '>= 0.44.0', license: 'GPL2+' )