Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gnome 45 support #8

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
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
25 changes: 0 additions & 25 deletions Makefile.am

This file was deleted.

23 changes: 12 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# GNOME Shell Extension: Super+Tab Launcher
Forked and updated for Gnome Shell 45+ from dsboger-zz's awesome original version :
https://github.com/dsboger/gnome-shell-extension-super-tab-launcher

Launch favorite apps from app switcher (i.e. Super+Tab or Alt+Tab) popup.
# GNOME Shell Extension: Alt+Tab Launcher

Git repository: https://github.com/dsboger/gnome-shell-extension-super-tab-launcher
Launch favorite apps from app switcher (i.e. Alt+Tab or Super+Tab) popup.

E.g.o: https://extensions.gnome.org/extension/1133/supertab-launcher/
Git repository: https://github.com/oxayotl/gnome-shell-extension-alt-tab-launcher

Have you ever tried to switch to an App, hit Super+Tab (or Alt+Tab) and just then

Have you ever tried to switch to an App, hit Alt+Tab (or Super+Tab) and just then
realize the App you sought after is not running? Then you had to cancel the popup,
bring the overview and launch the wanted App? This extension aims to streamline
the process by adding your (non-running) favorite Apps in the Super+Tab (or Alt+Tab)
Expand All @@ -15,18 +17,17 @@ launched!

## Notes

- Super+Tab Launcher was tested with GNOME Shell 3.22+
- Alt+Tab Launcher was tested with GNOME Shell 45
- It may (and probably will) interfere with other extensions that also modify
Super+Tab (or Alt+Tab) switcher. This scenario was not tested yet. If you find
an incompatibility that you would like to see fixed, please file a bug report!

## Installation

You may simply go to the e.g.o URL above and install the latest, reviewed release
of Super+Tab Launcher. It is also possible to install from the Git repository by
cloning (or downloading a release snapshot) and running the following commands
from the root folder:

A reviewed release of Alt+Tab Launcher should hopefully become available on
extensions.gnome.org shortly. In the meantime you can install from the Git
repository by cloning (or downloading a release snapshot) and running the
following commands from the root folder:

```
./autogen.sh
Expand Down
3 changes: 0 additions & 3 deletions autogen.sh

This file was deleted.

14 changes: 0 additions & 14 deletions configure.ac

This file was deleted.

2 changes: 0 additions & 2 deletions src/Makefile.am

This file was deleted.

161 changes: 40 additions & 121 deletions src/extension.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* GNOME Shell Extension: Super+Tab Launcher
* GNOME Shell Extension: Alt+Tab Launcher
* Copyright (C) 2023 Jean-Alexandre Anglès d'Auriac
* Copyright (C) 2018 Davi da Silva Böger
*
* This program is free software: you can redistribute it and/or modify
Expand All @@ -16,10 +17,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

const SwitcherPopup = imports.ui.switcherPopup;
const AltTab = imports.ui.altTab;
const AppFavorites = imports.ui.appFavorites;
const Shell = imports.gi.Shell;
import {Extension} from 'resource:///org/gnome/shell/extensions/extension.js';

import * as SwitcherPopup from 'resource:///org/gnome/shell/ui/switcherPopup.js';
import * as AltTab from 'resource:///org/gnome/shell/ui/altTab.js';
import * as AppFavorites from 'resource:///org/gnome/shell/ui/appFavorites.js';
import Shell from 'gi://Shell';

function openNewAppWindow(app) {
if (app.get_n_windows() == 0) {
Expand All @@ -36,110 +39,42 @@ function openNewAppWindow(app) {

function addLauncherForApp(app, switcher) {
let appIcon = new AltTab.AppIcon(app);
if (appIcon.actor) { // compatibility with <= 3.30.1
appIcon.actor.add_style_class_name('super-tab-launcher');
appIcon.actor.opacity = 128; // cannot set opacity through CSS?
} else {
appIcon.add_style_class_name('super-tab-launcher');
appIcon.opacity = 128; // cannot set opacity through CSS?
}
appIcon.cachedWindows = ["Hi, I'm a window!"]; // hack to hide the arrow
switcher._addIcon(appIcon); // TODO add in the right position
appIcon.add_style_class_name('super-tab-launcher');
appIcon.opacity = 128; // cannot set opacity through CSS?
appIcon.cachedWindows = ["Hi, I'm a window!"]; // hack because switcher._addIcon expects a window
switcher._addIcon(appIcon);
appIcon.cachedWindows = [];
// do not remove icon when non-running app stops running...
appIcon.app.disconnect(appIcon._stateChangedId);
// ... but remove when it starts running
appIcon._stateChangedId = appIcon.app.connect('notify::state', app => {
if (app.state == Shell.AppState.RUNNING) {
switcher._removeIcon(app);
}
});
appIcon.actuallyJustLauncher = true;
return appIcon;
}


let AppSwitcher_init_orig;
let AppSwitcher_removeIcon_orig;
let AppSwitcherPopup_init_orig;
let AppSwitcherPopup_initialSelection_orig;
let AppSwitcherPopup_select_orig;
let AppSwitcherPopup_finish_orig;

const AppSwitcher_init_mod = function(apps, altTabPopup) {
AppSwitcher_init_orig.apply(this, [apps, altTabPopup]);
// addedApps may differ from apps if 'current-workspace-only' is set
let addedApps = this.icons.map(function(i) { return i.app; });
const AppSwitcherPopup_init_mod = function() {
AppSwitcherPopup_init_orig.apply(this, []);
let favorites = AppFavorites.getAppFavorites().getFavorites();
let addedApps = this._switcherList.icons.map(function(i) { return i.app; });
for (let i in favorites) {
let favoriteApp = favorites[i];
if (addedApps.indexOf(favoriteApp) < 0) {
addLauncherForApp(favoriteApp, this);
addLauncherForApp(favoriteApp, this._switcherList);
}
}
}

const AppSwitcher_removeIcon_mod = function(app) {
AppSwitcher_removeIcon_orig.apply(this, [app]);
// we may be removing a launcher, so check if app is runnning
if (app.state != Shell.AppState.RUNNING) {
let favorites = AppFavorites.getAppFavorites().getFavorites();
let favIndex = favorites.indexOf(app);
if (favIndex >= 0) {
let appIcon = addLauncherForApp(app, this);
appIcon.set_size(this._iconSize);
}
}
}

const AppSwitcherPopup_init_mod = function() {
AppSwitcherPopup_init_orig.apply(this, []);
if (this._switcherList == undefined) {
// we know there are no running apps, as we have no _switcherList
this._switcherList = new AltTab.AppSwitcher([], this);
this._items = this._switcherList.icons;
}
}

const AppSwitcherPopup_initialSelection_mod = function(backward, binding) {
if (binding == 'switch-applications') {
// favorites are always added after running apps, so if first icon has no windows,
// there are no running apps
if (this._items[0].cachedWindows.length == 0) {
this._select(0);
return;
}

if (this._items.length > 1 && this._items[1].cachedWindows.length == 0) {
let firstAppHasFocus = false;
for (let window of this._items[0].app.get_windows()) {
if (window.has_focus()) {
firstAppHasFocus = true;
break;
}
}
if (!firstAppHasFocus) {
this._select(0);
return;
}
}
}
AppSwitcherPopup_initialSelection_orig.apply(this, [backward, binding]);
}

const AppSwitcherPopup_select_mod = function(app, window, forceAppFocus) {
let appIcon = this._items[app];
if (appIcon.cachedWindows.length == 0) {
if (appIcon.actuallyJustLauncher) {
// force not to show window thumbnails if app has no windows
window = null;
forceAppFocus = true;
}
AppSwitcherPopup_select_orig.apply(this, [app, window, forceAppFocus]);
}


const AppSwitcherPopup_finish_mod = function(timestamp) {
let appIcon = this._items[this._selectedIndex];
if (appIcon.cachedWindows.length == 0) {
// if app has no windows, launch it
if (appIcon.actuallyJustLauncher) {
// we do not activate() to respect 'current-workspace-only' setting
openNewAppWindow(appIcon.app);
SwitcherPopup.SwitcherPopup.prototype._finish.apply(this, [timestamp]);
Expand All @@ -148,46 +83,30 @@ const AppSwitcherPopup_finish_mod = function(timestamp) {
}
}

function init(metadata) {
}

function enable() {
AppSwitcher_init_orig = AltTab.AppSwitcher.prototype._init;
AltTab.AppSwitcher.prototype._init = AppSwitcher_init_mod;

AppSwitcher_removeIcon_orig = AltTab.AppSwitcher.prototype._removeIcon;
AltTab.AppSwitcher.prototype._removeIcon = AppSwitcher_removeIcon_mod;

AppSwitcherPopup_init_orig = AltTab.AppSwitcherPopup.prototype._init;
AltTab.AppSwitcherPopup.prototype._init = AppSwitcherPopup_init_mod;

AppSwitcherPopup_initialSelection_orig = AltTab.AppSwitcherPopup.prototype._initialSelection;
AltTab.AppSwitcherPopup.prototype._initialSelection = AppSwitcherPopup_initialSelection_mod;

AppSwitcherPopup_select_orig = AltTab.AppSwitcherPopup.prototype._select;
AltTab.AppSwitcherPopup.prototype._select = AppSwitcherPopup_select_mod;

AppSwitcherPopup_finish_orig = AltTab.AppSwitcherPopup.prototype._finish;
AltTab.AppSwitcherPopup.prototype._finish = AppSwitcherPopup_finish_mod;
}
let AppSwitcherPopup_init_orig;
let AppSwitcherPopup_select_orig;
let AppSwitcherPopup_finish_orig;

function disable() {
AltTab.AppSwitcher.prototype._init = AppSwitcher_init_orig;
AppSwitcher_init_orig = null;
export default class PlainExampleExtension extends Extension {
enable() {
AppSwitcherPopup_init_orig = AltTab.AppSwitcherPopup.prototype._init;
AltTab.AppSwitcherPopup.prototype._init = AppSwitcherPopup_init_mod;

AltTab.AppSwitcher.prototype._removeIcon = AppSwitcher_removeIcon_orig;
AppSwitcher_removeIcon_orig = null;
AppSwitcherPopup_select_orig = AltTab.AppSwitcherPopup.prototype._select;
AltTab.AppSwitcherPopup.prototype._select = AppSwitcherPopup_select_mod;

AltTab.AppSwitcherPopup.prototype._init = AppSwitcherPopup_init_orig;
AppSwitcherPopup_init_orig = null;
AppSwitcherPopup_finish_orig = AltTab.AppSwitcherPopup.prototype._finish;
AltTab.AppSwitcherPopup.prototype._finish = AppSwitcherPopup_finish_mod;
}

AltTab.AppSwitcherPopup.prototype._initialSelection = AppSwitcherPopup_initialSelection_orig;
AppSwitcherPopup_initialSelection_orig = null;
disable() {
AltTab.AppSwitcherPopup.prototype._init = AppSwitcherPopup_init_orig;
AppSwitcherPopup_init_orig = null;

AltTab.AppSwitcherPopup.prototype._select = AppSwitcherPopup_select_orig;
AppSwitcherPopup_select_orig = null;
AltTab.AppSwitcherPopup.prototype._select = AppSwitcherPopup_select_orig;
AppSwitcherPopup_select_orig = null;

AltTab.AppSwitcherPopup.prototype._finish = AppSwitcherPopup_finish_orig;
AppSwitcherPopup_finish_orig = null;
AltTab.AppSwitcherPopup.prototype._finish = AppSwitcherPopup_finish_orig;
AppSwitcherPopup_finish_orig = null;
}
}

14 changes: 8 additions & 6 deletions src/metadata.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
{
"shell-version": ["3.22", "3.24", "3.26", "3.28", "3.30"],
"uuid": "[email protected]",
"name": "Super+Tab Launcher",
"description": "Launch favorite apps from Super+Tab (and Alt+Tab) popup",
"url": "https://github.com/dsboger/gnome-shell-extension-super-tab-launcher",
"version": 8
"name": "Alt+Tab Launcher",
"description": "Launch favorite apps from Alt+Tab (and Super+Tab) popup",
"uuid": "[email protected]",
"url": "https://github.com/oxayotl/gnome-shell-extension-alt-tab-launcher",
"shell-version": [
"45", "46", "47"
],
"version": 4
}