Add window spread as click action

gh-1741
This commit is contained in:
Charles Gagnon
2025-02-11 18:26:49 -05:00
parent 7ae5e86e12
commit 0120770221
7 changed files with 113 additions and 20 deletions

View File

@@ -23,6 +23,7 @@
<value value='5' nick='QUIT'/>
<value value='6' nick='TOGGLE-SHOWPREVIEW'/>
<value value='7' nick='TOGGLE-CYCLE'/>
<value value='8' nick='TOGGLE-SPREAD'/>
</enum>
<enum id='org.gnome.shell.extensions.dash-to-panel.scrollAction'>
<value value='0' nick='NOTHING'/>

View File

@@ -1156,17 +1156,21 @@ export const TaskbarAppIcon = GObject.registerClass(
if (this.window && !handleAsGrouped) {
//ungrouped applications behaviors
switch (buttonAction) {
case 'RAISE':
case 'CYCLE':
case 'CYCLE-MIN':
case 'MINIMIZE':
case 'TOGGLE-SHOWPREVIEW':
case 'TOGGLE-CYCLE':
case 'LAUNCH':
this._launchNewInstance()
break
case 'QUIT':
this.window.delete(global.get_current_time())
break
default:
if (
!Main.overview._shown &&
(buttonAction == 'MINIMIZE' ||
buttonAction == 'TOGGLE-SHOWPREVIEW' ||
buttonAction == 'TOGGLE-CYCLE' ||
buttonAction == 'TOGGLE-SPREAD' ||
buttonAction == 'CYCLE-MIN') &&
(this._isFocusedWindow() ||
(buttonAction == 'MINIMIZE' &&
@@ -1177,16 +1181,6 @@ export const TaskbarAppIcon = GObject.registerClass(
} else {
Main.activateWindow(this.window)
}
break
case 'LAUNCH':
this._launchNewInstance()
break
case 'QUIT':
this.window.delete(global.get_current_time())
break
}
} else {
//grouped application behaviors
@@ -1279,6 +1273,16 @@ export const TaskbarAppIcon = GObject.registerClass(
case 'QUIT':
closeAllWindows(this.app, monitor)
break
case 'TOGGLE-SPREAD':
if (appCount == 1) {
if (appHasFocus && !Main.overview._shown)
minimizeWindow(this.app, false, monitor)
else activateFirstWindow(this.app, monitor)
} else
// return so the overview stays open if it already is
return this.dtpPanel.panelManager.showFocusedAppInOverview(
this.app,
)
}
}
} else {
@@ -1680,8 +1684,9 @@ export const TaskbarAppIcon = GObject.registerClass(
// still visible. The border radius is large to make the shape circular
let panelSize =
this.dtpPanel.geom[this.dtpPanel.checkIfVertical() ? 'w' : 'h']
let minFontSize = panelSize >= 32 ? 12 : 10
let fontSize = Math.round(
Math.max(11, 0.3 * panelSize) / Utils.getScaleFactor(),
Math.max(minFontSize, 0.3 * panelSize) / Utils.getScaleFactor(),
)
let size = Math.round(fontSize * 1.3)
let style = `
@@ -1713,9 +1718,9 @@ export const TaskbarAppIcon = GObject.registerClass(
this.window
? Main.activateWindow(this.window)
: activateFirstWindow(this.app, this.monitor)
} else this.dtpPanel.panelManager.showFocusedAppInOverview(this.app)
return DND.DragMotionResult.MOVE_DROP
}
return DND.DragMotionResult.MOVE_DROP
}
return DND.DragMotionResult.CONTINUE

View File

@@ -451,8 +451,10 @@ export const Panel = GObject.registerClass(
if (
source == Main.xdndHandler &&
Main.overview.shouldToggleByCornerOrButton()
)
) {
this.panelManager.showFocusedAppInOverview(null)
Main.overview.show()
}
return DND.DragMotionResult.CONTINUE
}

View File

@@ -46,6 +46,7 @@ import * as LookingGlass from 'resource:///org/gnome/shell/ui/lookingGlass.js'
import * as Main from 'resource:///org/gnome/shell/ui/main.js'
import * as PanelMenu from 'resource:///org/gnome/shell/ui/panelMenu.js'
import { NotificationsMonitor } from './notificationsMonitor.js'
import { Workspace } from 'resource:///org/gnome/shell/ui/workspace.js'
import * as Layout from 'resource:///org/gnome/shell/ui/layout.js'
import { InjectionManager } from 'resource:///org/gnome/shell/extensions/extension.js'
import { SETTINGS } from './extension.js'
@@ -54,6 +55,8 @@ import {
WorkspacesView,
} from 'resource:///org/gnome/shell/ui/workspacesView.js'
let tracker = Shell.WindowTracker.get_default()
export const PanelManager = class {
constructor() {
this.overview = new Overview.Overview()
@@ -189,6 +192,13 @@ 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
@@ -363,6 +373,10 @@ 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
@@ -443,6 +457,69 @@ export const PanelManager = class {
}
}
showFocusedAppInOverview(app) {
if (app == this.focusedApp) return
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()
;(window.get_first_child() || window).opacity = 0
Utils.animateWindowOpacity(window, {
opacity: 255,
time: 0.25,
transition: 'easeOutQuad',
})
}
})
this.focusedApp = null
this._signalsHandler.removeWithLabel('overview-spread')
},
])
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) => {
let metaWorkspace =
w.metaWorkspace ||
Utils.DisplayWrapper.getWorkspaceManager().get_active_workspace()
w._container.layout_manager._windows.forEach((info, preview) =>
preview.destroy(),
)
metaWorkspace.list_windows().forEach((mw) => w._doAddWindow(mw))
})
} else Main.overview.show()
}
_newSetPrimaryWorkspaceVisible(visible) {
if (this._primaryVisible === visible) return

View File

@@ -79,6 +79,10 @@ export const BasicHandler = class {
}
}
hasLabel(label) {
return !!this._storage[label]
}
/* Virtual methods to be implemented by subclass */
// create single element to be stored in the storage structure
_create() {

View File

@@ -29,6 +29,7 @@
<item id="CYCLE-MIN" translatable="yes">Cycle windows + minimize</item>
<item id="TOGGLE-SHOWPREVIEW" translatable="yes">Toggle single / Preview multiple</item>
<item id="TOGGLE-CYCLE" translatable="yes">Toggle single / Cycle multiple</item>
<item id="TOGGLE-SPREAD" translatable="yes">Toggle single / Spread multiple</item>
<item id="QUIT" translatable="yes">Quit</item>
</items>
</object>
@@ -57,6 +58,7 @@
<item id="CYCLE-MIN" translatable="yes">Cycle windows + minimize</item>
<item id="TOGGLE-SHOWPREVIEW" translatable="yes">Toggle single / Preview multiple</item>
<item id="TOGGLE-CYCLE" translatable="yes">Toggle single / Cycle multiple</item>
<item id="TOGGLE-SPREAD" translatable="yes">Toggle single / Spread multiple</item>
<item id="QUIT" translatable="yes">Quit</item>
</items>
</object>
@@ -85,6 +87,7 @@
<item id="CYCLE-MIN" translatable="yes">Cycle windows + minimize</item>
<item id="TOGGLE-SHOWPREVIEW" translatable="yes">Toggle single / Preview multiple</item>
<item id="TOGGLE-CYCLE" translatable="yes">Toggle single / Cycle multiple</item>
<item id="TOGGLE-SPREAD" translatable="yes">Toggle single / Spread multiple</item>
<item id="QUIT" translatable="yes">Quit</item>
</items>
</object>

View File

@@ -37,6 +37,7 @@
<item id="CYCLE" translatable="yes">Cycle through windows</item>
<item id="TOGGLE-SHOWPREVIEW" translatable="yes">Toggle single / Preview multiple</item>
<item id="TOGGLE-CYCLE" translatable="yes">Toggle single / Cycle multiple</item>
<item id="TOGGLE-SPREAD" translatable="yes">Toggle single / Spread multiple</item>
<item id="MINIMIZE" translatable="yes">Toggle windows</item>
<item id="RAISE" translatable="yes">Raise windows</item>
<item id="LAUNCH" translatable="yes">Launch new instance</item>