Show windows in single spread when workspaces aren't isolated

This commit is contained in:
Charles Gagnon
2025-02-12 16:58:51 -05:00
parent 0120770221
commit 01fcfa211f
9 changed files with 153 additions and 99 deletions

View File

@@ -1850,11 +1850,9 @@ export function closeAllWindows(app, monitor) {
// Filter out unnecessary windows, for instance
// nautilus desktop window.
export function getInterestingWindows(app, monitor, isolateMonitors) {
let windows = (
app
? app.get_windows()
: global.get_window_actors().map((wa) => wa.get_meta_window())
).filter((w) => !w.skip_taskbar)
let windows = (app ? app.get_windows() : Utils.getAllMetaWindows()).filter(
(w) => !w.skip_taskbar,
)
// When using workspace or monitor isolation, we filter out windows
// that are not in the current workspace or on the same monitor as the appicon

View File

@@ -26,6 +26,7 @@ import * as PanelSettings from './panelSettings.js'
import * as PanelManager from './panelManager.js'
import * as AppIcons from './appIcons.js'
import * as Utils from './utils.js'
const UBUNTU_DOCK_UUID = 'ubuntu-dock@ubuntu.com'
@@ -138,14 +139,11 @@ export default class DashToPanelExtension extends Extension {
openPreferences() {
if (SETTINGS.get_boolean('prefs-opened')) {
let prefsWindow = global
.get_window_actors()
.map((wa) => wa.meta_window)
.find(
(w) =>
w.title == 'Dash to Panel' &&
w.wm_class == 'org.gnome.Shell.Extensions',
)
let prefsWindow = Utils.getAllMetaWindows().find(
(w) =>
w.title == 'Dash to Panel' &&
w.wm_class == 'org.gnome.Shell.Extensions',
)
if (prefsWindow) Main.activateWindow(prefsWindow)

View File

@@ -89,7 +89,6 @@ export const NotificationsMonitor = class extends EventEmitter {
knownIdMappings[k].some((regex) => appId.match(regex)),
) || appId
appId = `${appId}.desktop`
this._state[appId] = this._state[appId] || {}
this._mergeState(appId, state)

View File

@@ -523,14 +523,10 @@ export const Overview = class {
)
if (pickedActor) {
let parent = pickedActor.get_parent()
if (
(pickedActor.has_style_class_name &&
pickedActor.has_style_class_name('apps-scroll-view') &&
!pickedActor.has_style_pseudo_class('first-child')) ||
(parent?.has_style_class_name &&
parent.has_style_class_name('window-picker')) ||
Main.overview._overview._controls._searchEntryBin.contains(
pickedActor,
) ||

View File

@@ -452,7 +452,7 @@ export const Panel = GObject.registerClass(
source == Main.xdndHandler &&
Main.overview.shouldToggleByCornerOrButton()
) {
this.panelManager.showFocusedAppInOverview(null)
this.panelManager.showFocusedAppInOverview(null, true)
Main.overview.show()
}

View File

@@ -192,13 +192,6 @@ export const PanelManager = class {
Main.overview._overview._controls._workspacesDisplay,
)
Workspace.prototype._oldIsOverviewWindow =
Workspace.prototype._isOverviewWindow
Workspace.prototype._isOverviewWindow = (metaWindow) =>
!metaWindow.skip_taskbar &&
(!this.focusedApp ||
tracker.get_window_app(metaWindow) == this.focusedApp)
LookingGlass.LookingGlass.prototype._oldResize =
LookingGlass.LookingGlass.prototype._resize
LookingGlass.LookingGlass.prototype._resize = _newLookingGlassResize
@@ -373,10 +366,6 @@ export const PanelManager = class {
Main.overview._overview._controls._workspacesDisplay.setPrimaryWorkspaceVisible =
this._oldSetPrimaryWorkspaceVisible
Workspace.prototype._isOverviewWindow =
Workspace.prototype._oldIsOverviewWindow
delete Workspace.prototype._oldIsOverviewWindow
LookingGlass.LookingGlass.prototype._resize =
LookingGlass.LookingGlass.prototype._oldResize
delete LookingGlass.LookingGlass.prototype._oldResize
@@ -457,57 +446,95 @@ export const PanelManager = class {
}
}
showFocusedAppInOverview(app) {
if (app == this.focusedApp) return
showFocusedAppInOverview(app, keepOverviewOpen) {
if (app == this.focusedApp) {
if (!keepOverviewOpen && Main.overview._shown) Main.overview.hide()
return
}
let isolateWorkspaces = SETTINGS.get_boolean('isolate-workspaces')
let isolateMonitors = SETTINGS.get_boolean('isolate-monitors')
this.focusedApp = app
if (!this._signalsHandler.hasLabel('overview-spread'))
this._signalsHandler.addWithLabel('overview-spread', [
Main.overview,
'hidden',
() => {
Utils.getCurrentWorkspace()
.list_windows()
.forEach((w) => {
if (
!w.minimized &&
!w.customJS_ding &&
tracker.get_window_app(w) != this.focusedApp
) {
let window = w.get_compositor_private()
if (!this._signalsHandler.hasLabel('overview-spread')) {
let hasWorkspaces = Main.sessionMode.hasWorkspaces
let maybeDisableWorkspacesClick = () => {
if (!isolateWorkspaces)
Utils.getOverviewWorkspaces().forEach(
(w) => (w._container.get_actions()[0].enabled = false),
)
}
let isIncludedWindow = (metaWindow) =>
!this.focusedApp ||
tracker.get_window_app(metaWindow) == this.focusedApp
;(window.get_first_child() || window).opacity = 0
Main.sessionMode.hasWorkspaces = isolateWorkspaces
maybeDisableWorkspacesClick()
Utils.animateWindowOpacity(window, {
opacity: 255,
time: 0.25,
transition: 'easeOutQuad',
})
}
})
Workspace.prototype._oldIsMyWindow = Workspace.prototype._isMyWindow
Workspace.prototype._isMyWindow = function (metaWindow) {
if (!metaWindow) return false
this.focusedApp = null
this._signalsHandler.removeWithLabel('overview-spread')
},
])
return (
isIncludedWindow(metaWindow) &&
(this.metaWorkspace === null ||
(!isolateWorkspaces && this.metaWorkspace.active) ||
(isolateWorkspaces &&
metaWindow.located_on_workspace(this.metaWorkspace))) &&
(!isolateMonitors || metaWindow.get_monitor() === this.monitorIndex)
)
}
this.focusedWorkspace = !isolateWorkspaces
? Utils.getCurrentWorkspace()
: null
this._signalsHandler.addWithLabel(
'overview-spread',
[Main.overview, 'showing', maybeDisableWorkspacesClick],
[
Main.overview,
'hidden',
() => {
Utils.getCurrentWorkspace()
.list_windows()
.forEach((w) => {
if (
!w.minimized &&
!w.customJS_ding &&
global.display.focus_window != w &&
tracker.get_window_app(w) != this.focusedApp
) {
let window = w.get_compositor_private()
;(window.get_first_child() || window).opacity = 0
Utils.animateWindowOpacity(window, {
opacity: 255,
time: 0.25,
transition: 'easeOutQuad',
})
}
})
this.focusedApp = null
this.focusedWorkspace = null
this._signalsHandler.removeWithLabel('overview-spread')
Main.sessionMode.hasWorkspaces = hasWorkspaces
Workspace.prototype._isMyWindow = Workspace.prototype._oldIsMyWindow
delete Workspace.prototype._oldIsMyWindow
},
],
)
}
if (Main.overview._shown) {
let workspaces = []
Main.overview._overview._controls._workspacesDisplay._workspacesViews.forEach(
(wv) =>
(workspaces = [
...workspaces,
...(wv._workspaces || []), // WorkspacesDisplay --> WorkspacesView (primary monitor)
...(wv._workspacesView?._workspaces || []), // WorkspacesDisplay --> SecondaryMonitorDisplay --> WorkspacesView
...(wv._workspacesView?._workspace // WorkspacesDisplay --> SecondaryMonitorDisplay --> ExtraWorkspaceView
? [wv._workspacesView?._workspace]
: []),
]),
)
workspaces.forEach((w) => {
Utils.getOverviewWorkspaces().forEach((w) => {
let metaWindows = []
let metaWorkspace =
w.metaWorkspace ||
Utils.DisplayWrapper.getWorkspaceManager().get_active_workspace()
@@ -515,7 +542,13 @@ export const PanelManager = class {
w._container.layout_manager._windows.forEach((info, preview) =>
preview.destroy(),
)
metaWorkspace.list_windows().forEach((mw) => w._doAddWindow(mw))
if (this.focusedWorkspace && this.focusedWorkspace == metaWorkspace)
metaWindows = Utils.getAllMetaWindows()
else if (!this.focusedWorkspace)
metaWindows = metaWorkspace.list_windows()
metaWindows.forEach((mw) => w._doAddWindow(mw))
})
} else Main.overview.show()
}

View File

@@ -1206,11 +1206,11 @@ export const Taskbar = class extends EventEmitter {
_getRunningApps() {
let tracker = Shell.WindowTracker.get_default()
let windows = global.get_window_actors()
let windows = Utils.getAllMetaWindows()
let apps = []
for (let i = 0, l = windows.length; i < l; ++i) {
let app = tracker.get_window_app(windows[i].metaWindow)
let app = tracker.get_window_app(windows[i])
if (app && apps.indexOf(app) < 0) {
apps.push(app)

View File

@@ -242,6 +242,24 @@ export const getSystemMenuInfo = function () {
}
}
export function getOverviewWorkspaces() {
let workspaces = []
Main.overview._overview._controls._workspacesDisplay._workspacesViews.forEach(
(wv) =>
(workspaces = [
...workspaces,
...(wv._workspaces || []), // WorkspacesDisplay --> WorkspacesView (primary monitor)
...(wv._workspacesView?._workspaces || []), // WorkspacesDisplay --> SecondaryMonitorDisplay --> WorkspacesView
...(wv._workspacesView?._workspace // WorkspacesDisplay --> SecondaryMonitorDisplay --> ExtraWorkspaceView
? [wv._workspacesView?._workspace]
: []),
]),
)
return workspaces
}
export const getCurrentWorkspace = function () {
return DisplayWrapper.getWorkspaceManager().get_active_workspace()
}
@@ -395,6 +413,10 @@ export const getMouseScrollDirection = function (event) {
return direction
}
export function getAllMetaWindows() {
return global.get_window_actors().map((w) => w.meta_window)
}
export const checkIfWindowHasTransient = function (window) {
let hasTransient

View File

@@ -678,7 +678,10 @@ export const PreviewMenu = GObject.registerClass(
_peek(window) {
let currentWorkspace = Utils.getCurrentWorkspace()
let windowWorkspace = window.get_workspace()
let isAppSpread = !Main.sessionMode.hasWorkspaces
let windowWorkspace = isAppSpread
? currentWorkspace
: window.get_workspace()
let focusWindow = () =>
this._focusMetaWindow(SETTINGS.get_int('peek-mode-opacity'), window)
@@ -742,31 +745,36 @@ export const PreviewMenu = GObject.registerClass(
}
_focusMetaWindow(dimOpacity, window, immediate, ignoreFocus) {
window
.get_workspace()
.list_windows()
.forEach((mw) => {
let wa = mw.get_compositor_private()
let isFocused = !ignoreFocus && mw == window
let isAppSpread = !Main.sessionMode.hasWorkspaces
let windowWorkspace = isAppSpread
? Utils.getCurrentWorkspace()
: window.get_workspace()
let windows = isAppSpread
? Utils.getAllMetaWindows()
: windowWorkspace.list_windows()
if (wa) {
if (isFocused) {
mw[PEEK_INDEX_PROP] = wa.get_parent().get_children().indexOf(wa)
wa.get_parent().set_child_above_sibling(wa, null)
}
windows.forEach((mw) => {
let wa = mw.get_compositor_private()
let isFocused = !ignoreFocus && mw == window
if (isFocused && mw.minimized) {
wa.show()
}
this.animateWindowOpacity(
mw,
wa,
isFocused ? 255 : dimOpacity,
immediate,
)
if (wa) {
if (isFocused) {
mw[PEEK_INDEX_PROP] = wa.get_parent().get_children().indexOf(wa)
wa.get_parent().set_child_above_sibling(wa, null)
}
})
if (isFocused && mw.minimized) {
wa.show()
}
this.animateWindowOpacity(
mw,
wa,
isFocused ? 255 : dimOpacity,
immediate,
)
}
})
}
animateWindowOpacity(metaWindow, windowActor, opacity, immediate) {