diff --git a/build.sh b/build.sh index 9ac9cfb..114e70a 100755 --- a/build.sh +++ b/build.sh @@ -12,4 +12,4 @@ zip -r ../windowgestures@extension.amarullz.com.zip ./* ## Recompile schemas glib-compile-schemas schemas/ -cd .. \ No newline at end of file +cd .. diff --git a/src/extension.js b/src/extension.js index 224df97..a137370 100644 --- a/src/extension.js +++ b/src/extension.js @@ -126,6 +126,10 @@ class Manager { clearTimeout(this._actionWidgets.tilerHider); this._actionWidgets.tilerHider = null; } + if (this._actionWidgets.resetApplist) { + clearTimeout(this._actionWidgets.resetApplist); + this._actionWidgets.resetApplist = null; + } } // Cleanup Extension @@ -600,6 +604,113 @@ class Manager { }).filter((w, i, a) => !w.skip_taskbar && a.indexOf(w) === i); } + // Get Window Tab List with Fixed Order + _getWindowTabListFixed() { + let wm = global.workspace_manager; + let workspace = wm.get_active_workspace(); + let windows = global.display.get_tab_list( + Meta.TabList.NORMAL_ALL, workspace + ); + + // Filter and map windows + let filteredWindows = windows.map(w => { + return w.is_attached_dialog() ? w.get_transient_for() : w; + }).filter((w, i, a) => !w.skip_taskbar && a.indexOf(w) === i); + + // Sort by process creation time (oldest first) + filteredWindows.sort((a, b) => { + let timeA = this._getProcessCreationTime(a.get_pid()); + let timeB = this._getProcessCreationTime(b.get_pid()); + return timeA - timeB; + }); + + return filteredWindows; + } + + // Get Application List + _getApplicationList() { + let wm = global.workspace_manager; + let workspace = wm.get_active_workspace(); + let windows = global.display.get_tab_list( + Meta.TabList.NORMAL_ALL, workspace + ); + + // Group windows by application + let appMap = new Map(); + windows.forEach(w => { + let window = w.is_attached_dialog() ? w.get_transient_for() : w; + if (!window || window.skip_taskbar) return; + + let app = this._winmanWinApp(window); + if (!app) return; + + if (!appMap.has(app)) { + appMap.set(app, []); + } + appMap.get(app).push(window); + }); + + // Convert to array of applications with their windows + // Sort by most recently used (active window first) + let activeWindow = global.display.get_focus_window(); + let apps = Array.from(appMap.entries()).map(([app, windows]) => ({ + app: app, + windows: windows, + activeWindow: windows[0] // First window as representative + })); + + // Put active application first + if (activeWindow) { + let activeApp = this._winmanWinApp(activeWindow); + if (activeApp) { + let activeIndex = apps.findIndex(a => a.app === activeApp); + if (activeIndex > 0) { + let activeAppData = apps.splice(activeIndex, 1)[0]; + apps.unshift(activeAppData); + } + } + } + + return apps; + } + + // Get Application List with Fixed Order + _getApplicationListFixed() { + let wm = global.workspace_manager; + let workspace = wm.get_active_workspace(); + let windows = global.display.get_tab_list( + Meta.TabList.NORMAL_ALL, workspace + ); + + // Group windows by application + let appMap = new Map(); + windows.forEach(w => { + let window = w.is_attached_dialog() ? w.get_transient_for() : w; + if (!window || window.skip_taskbar) return; + + let app = this._winmanWinApp(window); + if (!app) return; + + if (!appMap.has(app)) { + appMap.set(app, []); + } + appMap.get(app).push(window); + }); + + // Convert to array of applications with their windows + let apps = Array.from(appMap.entries()).map(([app, windows]) => ({ + app: app, + windows: windows, + activeWindow: windows[0], // First window as representative + processTime: this._getProcessCreationTime(windows[0].get_pid()) // Use process creation time for sorting + })); + + // Sort by process creation time (oldest first) + apps.sort((a, b) => a.processTime - b.processTime); + + return apps; + } + // Hide Preview _hidePreview() { global.window_manager.emit("hide-tile-preview"); @@ -1635,6 +1746,8 @@ class Manager { case 9: cfg_name = "pinch3-out"; break; case 10: cfg_name = "pinch4-in"; break; case 11: cfg_name = "pinch4-out"; break; + case 24: return 24; // Next application - direct return + case 25: return 25; // Previous application - direct return default: if (type >= 50 && type <= 53) { // Max & Snap @@ -1889,18 +2002,21 @@ class Manager { } } - else if ((id == 4) || (id == 5)) { + else if ((id == 4) || (id == 5) || (id == 24) || (id == 25)) { // - // NEXT & PREVIOUS WINDOW SWITCHING + // NEXT & PREVIOUS WINDOW/APPLICATION SWITCHING // if (this._isOnOverview()) { return; // Ignore on overview } - let prv = (id == 5); + let prv = (id == 5 || id == 25); let wid = prv ? "switchwin_prev" : "switchwin_next"; let ui = this._actionWidgets[wid]; + // Check if this should be application switching + let isAppSwitching = (id == 24 || id == 25); + // Init indicator if (!ui) { ui = -1; @@ -1912,14 +2028,26 @@ class Manager { clearTimeout(this._actionWidgets.resetWinlist); this._actionWidgets.resetWinlist = 0; } - // Get cached window list - if (this._actionWidgets.cacheWinTabList) { - wins = this._actionWidgets.cacheWinTabList?.wins; - listActor = this._actionWidgets.cacheWinTabList?.actor; + // Get cached window/app list + if (isAppSwitching) { + if (this._actionWidgets.cacheAppTabList) { + wins = this._actionWidgets.cacheAppTabList?.apps; + listActor = this._actionWidgets.cacheAppTabList?.actor; + } + } else { + if (this._actionWidgets.cacheWinTabList) { + wins = this._actionWidgets.cacheWinTabList?.wins; + listActor = this._actionWidgets.cacheWinTabList?.actor; + } } if (!wins) { // No last cached - wins = this._getWindowTabList(); + let useFixedOrder = this._settings.get_boolean('fixed-window-order'); + if (isAppSwitching) { + wins = useFixedOrder ? this._getApplicationListFixed() : this._getApplicationList(); + } else { + wins = useFixedOrder ? this._getWindowTabListFixed() : this._getWindowTabList(); + } if (wins.length > 1) { // Create UI let gsize = Main.layoutManager.uiGroup.get_size(); @@ -1943,7 +2071,7 @@ class Manager { pivY = 1; } listActor = this._createUi( - "wgs-winswitch", lX, lY, lW, lH + isAppSwitching ? "wgs-appswitch" : "wgs-winswitch", lX, lY, lW, lH ); listActor.set_pivot_point(0.5, pivY); listActor.opacity = 0; @@ -1951,22 +2079,42 @@ class Manager { listActor.scale_y = 0.5; listActor._data = []; for (var i = 0; i < wins.length; i++) { - let win = wins[i]; - let app = this._winmanWinApp(win); - let ico = app.create_icon_texture(32); - ico.add_style_class_name("wgs-winswitch-ico"); - // remove_style_class_name + let item = wins[i]; + let ico, app, win; + + if (isAppSwitching) { + // Application switching + app = item.app; + win = item.activeWindow; + ico = app.create_icon_texture(32); + ico.add_style_class_name("wgs-appswitch-ico"); + } else { + // Window switching + win = item; + app = this._winmanWinApp(win); + ico = app.create_icon_texture(32); + ico.add_style_class_name("wgs-winswitch-ico"); + } + listActor.add_child(ico); ico.set_size(32, 32); ico.set_position((pad * 2) + (48 * i), pad); ico.set_pivot_point(0.5, 0.5); - listActor._data.push( - { + + if (isAppSwitching) { + listActor._data.push({ + app: app, + windows: item.windows, + activeWindow: win, + ico: ico + }); + } else { + listActor._data.push({ app: app, win: win, ico: ico - } - ) + }); + } } listActor.viewShow({ opacity: 255, @@ -1975,41 +2123,138 @@ class Manager { }, 200); // Reorder for next (below 1s) calls - this._actionWidgets.cacheWinTabList = { - sel: 0, - first: wins[0], - wins: wins, - actor: listActor - }; + let useFixedOrder = this._settings.get_boolean('fixed-window-order'); + let currentIndex = 0; + + if (useFixedOrder) { + // Find current active window/app in the sorted list + let activeWindow = global.display.get_focus_window(); + if (activeWindow) { + if (isAppSwitching) { + let activeApp = this._winmanWinApp(activeWindow); + currentIndex = wins.findIndex(item => item.app === activeApp); + } else { + currentIndex = wins.findIndex(win => win === activeWindow); + } + } + // If not found, use 0 as default + if (currentIndex === -1) { + currentIndex = 0; + } + } + + if (isAppSwitching) { + this._actionWidgets.cacheAppTabList = { + sel: 0, + first: wins[0], + apps: wins, + actor: listActor, + useFixedOrder: useFixedOrder, + currentIndex: currentIndex + }; + } else { + this._actionWidgets.cacheWinTabList = { + sel: 0, + first: wins[0], + wins: wins, + actor: listActor, + useFixedOrder: useFixedOrder, + currentIndex: currentIndex + }; + } } else { - this._actionWidgets.cacheWinTabList = null; + if (isAppSwitching) { + this._actionWidgets.cacheAppTabList = null; + } else { + this._actionWidgets.cacheWinTabList = null; + } } } if (wins.length > 1) { - ui = { from: wins[0] }; - if (prv) { - ui.into = wins[wins.length - 1]; - ui.nsel = -1; + let useFixedOrder = this._settings.get_boolean('fixed-window-order'); + let cache = isAppSwitching ? this._actionWidgets.cacheAppTabList : this._actionWidgets.cacheWinTabList; + + if (useFixedOrder && cache && cache.useFixedOrder) { + // Use fixed order with index + let currentIndex = cache.currentIndex; + let nextIndex; + + if (prv) { + nextIndex = (currentIndex - 1 + wins.length) % wins.length; + } else { + nextIndex = (currentIndex + 1) % wins.length; + } + + ui = { + from: wins[currentIndex], + into: wins[nextIndex], + nsel: prv ? -1 : 1, + lstate: 0, + currentIndex: currentIndex, + nextIndex: nextIndex + }; + } else { + // Use original logic - find current active window/app + let activeWindow = global.display.get_focus_window(); + let fromIndex = 0; + + if (activeWindow) { + if (isAppSwitching) { + let activeApp = this._winmanWinApp(activeWindow); + fromIndex = wins.findIndex(item => item.app === activeApp); + } else { + fromIndex = wins.findIndex(win => win === activeWindow); + } + } + + if (fromIndex === -1) { + fromIndex = 0; + } + + let toIndex; + if (prv) { + toIndex = (fromIndex - 1 + wins.length) % wins.length; + } else { + toIndex = (fromIndex + 1) % wins.length; + } + + ui = { + from: wins[fromIndex], + into: wins[toIndex], + nsel: prv ? -1 : 1, + lstate: 0 + }; } - else { - ui.into = wins[1]; - ui.nsel = 1; + + if (isAppSwitching) { + ui.from_actor = ui.from.activeWindow.get_compositor_private(); + ui.into_actor = ui.into.activeWindow.get_compositor_private(); + } else { + ui.from_actor = ui.from.get_compositor_private(); + ui.into_actor = ui.into.get_compositor_private(); } - ui.lstate = 0; - ui.from_actor = ui.from.get_compositor_private(); - ui.into_actor = ui.into.get_compositor_private(); ui.from_actor.set_pivot_point(0.5, 1); ui.into_actor.set_pivot_point(0.5, 1); // Set selected target for (var i = 0; i < listActor._data.length; i++) { let d = listActor._data[i]; - if (d.win == ui.from) { + let fromMatch, intoMatch; + + if (isAppSwitching) { + fromMatch = (d.app == ui.from.app); + intoMatch = (d.app == ui.into.app); + } else { + fromMatch = (d.win == ui.from); + intoMatch = (d.win == ui.into); + } + + if (fromMatch) { d.ico.add_style_class_name("selected"); ui.from_ico = d.ico; } - else if (d.win == ui.into) { + else if (intoMatch) { d.ico.remove_style_class_name("selected"); ui.into_ico = d.ico; } @@ -2021,18 +2266,32 @@ class Manager { this._actionWidgets[wid] = ui; } if (ui && ui != -1) { + let useStableSwitching = this._settings.get_boolean('stable-window-switching'); + if (!state) { try { - ui.from_actor.opacity = 255 - Math.round(80 * progress); - ui.from_actor.scale_y = - ui.from_actor.scale_x = 1.0 - (0.05 * progress); - ui.into_actor.scale_y = - ui.into_actor.scale_x = 1.0 + (0.05 * progress); + if (ui.from_actor && !ui.from_actor.is_destroyed && ui.from_actor.is_destroyed !== undefined) { + ui.from_actor.opacity = 255 - Math.round(80 * progress); + ui.from_actor.scale_y = + ui.from_actor.scale_x = 1.0 - (0.05 * progress); + } + if (ui.into_actor && !ui.into_actor.is_destroyed && ui.into_actor.is_destroyed !== undefined) { + ui.into_actor.scale_y = + ui.into_actor.scale_x = 1.0 + (0.05 * progress); + } } catch (e) { } - if (progress > 0.8) { + + // Determine when to switch based on stable mode + let shouldSwitch = useStableSwitching ? (progress > 0.1) : (progress > 0.8); + + if (shouldSwitch) { if (!ui.lstate) { try { - ui.into.raise(); + if (isAppSwitching && ui.into && ui.into.activeWindow) { + ui.into.activeWindow.raise(); + } else if (ui.into) { + ui.into.raise(); + } } catch (e) { } ui.lstate = 1; ui.from_ico?.remove_style_class_name("selected"); @@ -2041,7 +2300,11 @@ class Manager { } else if (ui.lstate) { try { - ui.from.raise(); + if (isAppSwitching && ui.from && ui.from.activeWindow) { + ui.from.activeWindow.raise(); + } else if (ui.from) { + ui.from.raise(); + } } catch (e) { } ui.lstate = 0; ui.from_ico?.add_style_class_name("selected"); @@ -2049,87 +2312,187 @@ class Manager { } } else { - if ((progress > 0.8) || ui.lstate) { + // In stable mode, always complete the switch when gesture ends + let shouldComplete = useStableSwitching ? true : ((progress > 0.8) || ui.lstate); + + if (shouldComplete) { try { try { - this._actionWidgets - .cacheWinTabList.first.activate( - Meta.CURRENT_TIME - ); + if (isAppSwitching && this._actionWidgets.cacheAppTabList && + this._actionWidgets.cacheAppTabList.first && + this._actionWidgets.cacheAppTabList.first.activeWindow) { + this._actionWidgets + .cacheAppTabList.first.activeWindow.activate( + Meta.CURRENT_TIME + ); + } else if (this._actionWidgets.cacheWinTabList && + this._actionWidgets.cacheWinTabList.first) { + this._actionWidgets + .cacheWinTabList.first.activate( + Meta.CURRENT_TIME + ); + } } catch (e) { } try { - ui.from.raise(); + if (isAppSwitching && ui.from && ui.from.activeWindow) { + ui.from.activeWindow.raise(); + } else if (ui.from) { + ui.from.raise(); + } } catch (e) { } - ui.into.activate( - Meta.CURRENT_TIME - ); + if (isAppSwitching && ui.into && ui.into.activeWindow) { + ui.into.activeWindow.activate( + Meta.CURRENT_TIME + ); + } else if (ui.into) { + ui.into.activate( + Meta.CURRENT_TIME + ); + } } catch (e) { } - if (prv) { - this._actionWidgets.cacheWinTabList.wins.unshift( - this._actionWidgets.cacheWinTabList.wins.pop() - ); - } - else { - this._actionWidgets.cacheWinTabList.wins.push( - this._actionWidgets.cacheWinTabList.wins.shift() - ); + let cache = isAppSwitching ? this._actionWidgets.cacheAppTabList : this._actionWidgets.cacheWinTabList; + if (cache && cache.useFixedOrder && ui.nextIndex !== undefined) { + // Update index for fixed order mode + cache.currentIndex = ui.nextIndex; + } else if (cache) { + // Use original reordering logic + if (prv) { + if (isAppSwitching && cache.apps && cache.apps.length > 0) { + cache.apps.unshift(cache.apps.pop()); + } else if (cache.wins && cache.wins.length > 0) { + cache.wins.unshift(cache.wins.pop()); + } + } + else { + if (isAppSwitching && cache.apps && cache.apps.length > 0) { + cache.apps.push(cache.apps.shift()); + } else if (cache.wins && cache.wins.length > 0) { + cache.wins.push(cache.wins.shift()); + } + } } ui.from_ico?.remove_style_class_name("selected"); ui.into_ico?.add_style_class_name("selected"); } else { + // In stable mode, if we haven't switched yet, force a switch + if (useStableSwitching && !ui.lstate) { + try { + if (isAppSwitching && ui.into && ui.into.activeWindow) { + ui.into.activeWindow.activate(Meta.CURRENT_TIME); + } else if (ui.into) { + ui.into.activate(Meta.CURRENT_TIME); + } + } catch (e) { } + + // Update cache for next switch + let cache = isAppSwitching ? this._actionWidgets.cacheAppTabList : this._actionWidgets.cacheWinTabList; + if (cache && cache.useFixedOrder && ui.nextIndex !== undefined) { + cache.currentIndex = ui.nextIndex; + } else if (cache) { + if (prv) { + if (isAppSwitching && cache.apps && cache.apps.length > 0) { + cache.apps.unshift(cache.apps.pop()); + } else if (cache.wins && cache.wins.length > 0) { + cache.wins.unshift(cache.wins.pop()); + } + } else { + if (isAppSwitching && cache.apps && cache.apps.length > 0) { + cache.apps.push(cache.apps.shift()); + } else if (cache.wins && cache.wins.length > 0) { + cache.wins.push(cache.wins.shift()); + } + } + } + } ui.from_ico?.add_style_class_name("selected"); ui.into_ico?.remove_style_class_name("selected"); } ui.nclose = 0; // Ease Restore try { - ui.from_actor.ease({ - duration: Math.round(200 * progress), - mode: Clutter.AnimationMode.EASE_OUT_QUAD, - opacity: 255, - scale_x: 1, - scale_y: 1, - onStopped: () => { - ui.from_actor.set_pivot_point(0, 0); - ui.from_actor = null; - ui.from = null; - if (++ui.nclose == 2) { - ui = null; + if (ui.from_actor && !ui.from_actor.is_destroyed && ui.from_actor.is_destroyed !== undefined) { + ui.from_actor.ease({ + duration: Math.round(200 * progress), + mode: Clutter.AnimationMode.EASE_OUT_QUAD, + opacity: 255, + scale_x: 1, + scale_y: 1, + onStopped: () => { + if (ui.from_actor && !ui.from_actor.is_destroyed) { + ui.from_actor.set_pivot_point(0, 0); + } + ui.from_actor = null; + ui.from = null; + if (++ui.nclose == 2) { + ui = null; + } } + }); + } else { + ui.from_actor = null; + ui.from = null; + if (++ui.nclose == 2) { + ui = null; } - }); + } } catch (e) { } try { - ui.into_actor.ease({ - duration: Math.round(200 * progress), - mode: Clutter.AnimationMode.EASE_OUT_QUAD, - opacity: 255, - scale_x: 1, - scale_y: 1, - onStopped: () => { - ui.into_actor.set_pivot_point(0, 0); - ui.into_actor = null; - ui.into = null; - if (++ui.nclose == 2) { - ui = null; + if (ui.into_actor && !ui.into_actor.is_destroyed && ui.into_actor.is_destroyed !== undefined) { + ui.into_actor.ease({ + duration: Math.round(200 * progress), + mode: Clutter.AnimationMode.EASE_OUT_QUAD, + opacity: 255, + scale_x: 1, + scale_y: 1, + onStopped: () => { + if (ui.into_actor && !ui.into_actor.is_destroyed) { + ui.into_actor.set_pivot_point(0, 0); + } + ui.into_actor = null; + ui.into = null; + if (++ui.nclose == 2) { + ui = null; + } } + }); + } else { + ui.into_actor = null; + ui.into = null; + if (++ui.nclose == 2) { + ui = null; } - }); + } } catch (e) { } this._actionWidgets[wid] = null; // Clear cache after timeout let me = this; - this._actionWidgets.resetWinlist = setTimeout( - function () { - me._actionWidgets - .cacheWinTabList.actor.aniRelease(); - me._actionWidgets.cacheWinTabList = null; - clearTimeout(me._actionWidgets.resetWinlist); - me._actionWidgets.resetWinlist = 0; - }, 500 - ); + if (isAppSwitching) { + this._actionWidgets.resetApplist = setTimeout( + function () { + if (me._actionWidgets.cacheAppTabList && + me._actionWidgets.cacheAppTabList.actor) { + me._actionWidgets.cacheAppTabList.actor.aniRelease(); + } + me._actionWidgets.cacheAppTabList = null; + clearTimeout(me._actionWidgets.resetApplist); + me._actionWidgets.resetApplist = 0; + }, 500 + ); + } else { + this._actionWidgets.resetWinlist = setTimeout( + function () { + if (me._actionWidgets.cacheWinTabList && + me._actionWidgets.cacheWinTabList.actor) { + me._actionWidgets.cacheWinTabList.actor.aniRelease(); + } + me._actionWidgets.cacheWinTabList = null; + clearTimeout(me._actionWidgets.resetWinlist); + me._actionWidgets.resetWinlist = 0; + }, 500 + ); + } } } else if (state) { this._actionWidgets[wid] = ui = null; @@ -2665,6 +3028,56 @@ class Manager { // End Of Actions // } + + // Update fixed order index when window list changes + _updateFixedOrderIndex(cache, currentWindow, isAppSwitching) { + if (!cache || !cache.useFixedOrder) return; + + let wins = isAppSwitching ? cache.apps : cache.wins; + if (!wins || wins.length === 0) return; + + // Find current window in the list + let newIndex = 0; + if (currentWindow) { + if (isAppSwitching) { + let currentApp = this._winmanWinApp(currentWindow); + newIndex = wins.findIndex(item => item.app === currentApp); + } else { + newIndex = wins.findIndex(win => win === currentWindow); + } + } + + // If not found, use 0 as default + if (newIndex === -1) { + newIndex = 0; + } + + cache.currentIndex = newIndex; + } + + // Get process creation time by PID + _getProcessCreationTime(pid) { + try { + // Try to read from /proc/{pid}/stat + let statFile = Gio.File.new_for_path(`/proc/${pid}/stat`); + if (statFile.query_exists(null)) { + let [success, contents] = statFile.load_contents(null); + if (success) { + let decoder = new TextDecoder(); + let statText = decoder.decode(contents); + let statData = statText.split(' '); + // The 22nd field (index 21) contains the start time in jiffies + let startTime = parseInt(statData[21]); + return startTime; + } + } + } catch (e) { + // If we can't read the stat file, fall back to window ID + } + + // Fallback: return a large number to put unknown processes at the end + return Number.MAX_SAFE_INTEGER; + } } // Export Extension diff --git a/src/metadata.json b/src/metadata.json index 7144742..c3ca308 100644 --- a/src/metadata.json +++ b/src/metadata.json @@ -12,4 +12,4 @@ "url": "https://github.com/amarullz/windowgestures", "uuid": "windowgestures@extension.amarullz.com", "version": 7 -} \ No newline at end of file +} diff --git a/src/prefs.js b/src/prefs.js index 8e70259..6d119f0 100644 --- a/src/prefs.js +++ b/src/prefs.js @@ -26,7 +26,7 @@ import { PACKAGE_VERSION } from 'resource:///org/gnome/Shell/Extensions/js/misc/ export default class extends ExtensionPreferences { fillPreferencesWindow(window) { const GNOME_VER = parseFloat(PACKAGE_VERSION); - const SUPPORT_PINCH = (GNOME_VER < 46)||(GNOME_VER>=48.2); + const SUPPORT_PINCH = (GNOME_VER < 46) || (GNOME_VER >= 48.2); const WEBSITE_LINK = "https://amarullz.com/"; const PAYPAL_LINK = "https://paypal.me/amarullz"; const GNU_SOFTWARE = '' + @@ -90,6 +90,16 @@ export default class extends ExtensionPreferences { "Enable move window snap", "" ); + this._createSwitch( + fn, "fixed-window-order", + "Use fixed window order for switching", + "When enabled, window switching will follow a fixed order based on window creation time instead of cycling between two windows" + ); + this._createSwitch( + fn, "stable-window-switching", + "Use stable window switching", + "When enabled, window switching will be more stable and always switch exactly one window regardless of gesture distance" + ); // Actions const action_list = [ @@ -122,6 +132,9 @@ export default class extends ExtensionPreferences { "Notification", // 22 "Run (Alt+F2)", // 23 + "Next application", // 24 + "Previous application", // 25 + ]; const act1 = new Adw.PreferencesGroup({ diff --git a/src/schemas/org.gnome.shell.extensions.windowgestures.gschema.xml b/src/schemas/org.gnome.shell.extensions.windowgestures.gschema.xml index fbb1f7e..71e88b6 100644 --- a/src/schemas/org.gnome.shell.extensions.windowgestures.gschema.xml +++ b/src/schemas/org.gnome.shell.extensions.windowgestures.gschema.xml @@ -40,6 +40,14 @@ true Enable Pinch + + false + Use fixed window order for switching + + + false + Use stable window switching + diff --git a/src/stylesheet.css b/src/stylesheet.css index 95409aa..a3af532 100644 --- a/src/stylesheet.css +++ b/src/stylesheet.css @@ -36,6 +36,24 @@ background-color: rgba(120, 120, 120, 0.6); } +/* Application Switching Indicator */ +.wgs-appswitch { + text-align: center; + border-radius: 48px; +} + +.wgs-appswitch .wgs-appswitch-ico { + padding: 5px; + border-radius: 5px; + background-color: rgba(120, 120, 120, 0); + transition-property: background-color; + transition-duration: 0.3s; +} + +.wgs-appswitch .wgs-appswitch-ico.selected { + background-color: rgba(120, 120, 120, 0.6); +} + /* Key Indicator */ .wgs-indicator-keys { width: 128px; @@ -69,6 +87,7 @@ /* Light Mode */ .wgs-winswitch, +.wgs-appswitch, .wgs-indicator-keys, .wgs-indicator-backforward { background-color: rgba(230, 230, 230, 0.8); @@ -84,6 +103,7 @@ /* Dark Mode */ .wgs-dark.wgs-winswitch, +.wgs-dark.wgs-appswitch, .wgs-dark.wgs-indicator-keys, .wgs-dark.wgs-indicator-backforward { background-color: rgba(40, 40, 40, 0.8);