Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions schemas/org.gnome.shell.extensions.dash-to-panel.gschema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1380,6 +1380,20 @@
<description>
Keybinding to either show or launch the 10th application in the dash.
</description>
</key>
<key name="switch-to-next-window" type="as">
<default><![CDATA[[]]]></default>
<summary>Switch to next window in taskbar order</summary>
<description>
Keybinding to switch to the next window based on the taskbar order.
</description>
</key>
<key name="switch-to-previous-window" type="as">
<default><![CDATA[[]]]></default>
<summary>Switch to previous window in taskbar order</summary>
<description>
Keybinding to switch to the previous window based on the taskbar order.
</description>
</key>
<key type="b" name="progress-show-bar">
<default>true</default>
Expand Down
61 changes: 61 additions & 0 deletions src/overview.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export const Overview = class {
this._optionalHotKeys()
this._optionalNumberOverlay()
this._optionalClickToExit()
this._enableWindowSwitchingKeybindings()

this.toggleDash()
this._adaptAlloc()
Expand All @@ -87,6 +88,7 @@ export const Overview = class {
this._disableHotKeys()
this._disableExtraShortcut()
this._disableClickToExit()
this._disableWindowSwitchingKeybindings()
}

toggleDash(visible) {
Expand Down Expand Up @@ -302,6 +304,47 @@ export const Overview = class {
}
}

_switchToWindow(direction) {
// Get all windows from taskbar in order
let windows = []
this.taskbar._getAppIcons().forEach((appIcon) => {
if (appIcon.window) {
windows.push(appIcon.window)
} else if (appIcon._nWindows > 0) {
windows.push(...appIcon.getInterestingWindows())
}
})

if (windows.length === 0) return

// Find current window index
let currentIndex = global.display.focus_window
? windows.indexOf(global.display.focus_window)
: -1

// Calculate next index with wrapping

// Calculate the next window index
let nextIndex
if (currentIndex === -1) {
// No window focused or focused window not in taskbar - go to first/last
nextIndex = direction === 1 ? 0 : windows.length - 1
} else {
nextIndex = (currentIndex + direction + windows.length) % windows.length
}

// Activate the next window
Main.activateWindow(windows[nextIndex])
}

_switchToNextWindow() {
this._switchToWindow(1)
}

_switchToPreviousWindow() {
this._switchToWindow(-1)
}

_optionalHotKeys() {
this._hotKeysEnabled = false
if (SETTINGS.get_boolean('hot-keys')) this._enableHotKeys()
Expand Down Expand Up @@ -567,6 +610,24 @@ export const Overview = class {
this._clickToExitEnabled = false
}

_enableWindowSwitchingKeybindings() {
Utils.addKeybinding(
'switch-to-next-window',
SETTINGS,
this._switchToNextWindow.bind(this),
)
Utils.addKeybinding(
'switch-to-previous-window',
SETTINGS,
this._switchToPreviousWindow.bind(this),
)
}

_disableWindowSwitchingKeybindings() {
Utils.removeKeybinding('switch-to-next-window')
Utils.removeKeybinding('switch-to-previous-window')
}

_onSwipeBegin() {
this._swiping = true
return true
Expand Down
33 changes: 33 additions & 0 deletions src/prefs.js
Original file line number Diff line number Diff line change
Expand Up @@ -3247,6 +3247,39 @@ const Preferences = class {
dialog.set_default_size(600, 1)
})

// Setup window switching keybindings
const setupKeybindingEntry = (entryId, settingKey) => {
const entry = this._builder.get_object(entryId)

// Load current keybinding
const currentBindings = this._settings.get_strv(settingKey)
if (currentBindings.length > 0) {
entry.set_text(currentBindings[0])
}

// Save on change
entry.connect('changed', () => {
const text = entry.get_text()
const [success, key, mods] = Gtk.accelerator_parse(text)

if (success && Gtk.accelerator_valid(key, mods)) {
const shortcut = Gtk.accelerator_name(key, mods)
this._settings.set_strv(settingKey, [shortcut])
} else if (text === '') {
this._settings.set_strv(settingKey, [])
}
})

// Update entry when settings change
this._settings.connect(`changed::${settingKey}`, () => {
const bindings = this._settings.get_strv(settingKey)
entry.set_text(bindings.length > 0 ? bindings[0] : '')
})
}

setupKeybindingEntry('switch_to_next_window_entry', 'switch-to-next-window')
setupKeybindingEntry('switch_to_previous_window_entry', 'switch-to-previous-window')

// setup dialog for secondary menu options
this._builder
.get_object('secondarymenu_options_button')
Expand Down
31 changes: 31 additions & 0 deletions ui/SettingsAction.ui
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,37 @@
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup" id="action_window_switching_group">
<property name="title" translatable="yes">Window switching keyboard shortcuts</property>
<child>
<object class="AdwActionRow">
<property name="subtitle" translatable="yes">Switch to the next window in taskbar order</property>
<property name="title" translatable="yes">Next window</property>
<child>
<object class="GtkEntry" id="switch_to_next_window_entry">
<property name="placeholder-text" translatable="yes">e.g. &lt;Super&gt;Tab</property>
<property name="valign">center</property>
<property name="width-chars">18</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="subtitle" translatable="yes">Switch to the previous window in taskbar order</property>
<property name="title" translatable="yes">Previous window</property>
<child>
<object class="GtkEntry" id="switch_to_previous_window_entry">
<property name="placeholder-text" translatable="yes">e.g. &lt;Shift&gt;&lt;Super&gt;Tab</property>
<property name="valign">center</property>
<property name="width-chars">18</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup" id="action_appicons_group">
<property name="title" translatable="yes">Application icons context menu</property>
Expand Down