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

Fix handling skip taskbar on LTS and latest #1069

Merged
merged 3 commits into from
Jul 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions schemas/org.gnome.shell.extensions.pop-shell.gschema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
<summary>Show title bars on windows with server-side decorations</summary>
</key>

<key type="b" name="show-skip-taskbar">
<default>true</default>
<summary>Handle minimized to tray windows</summary>
</key>

<!-- Tiling Options -->
<key type="u" name="column-size">
<default>64</default>
Expand Down
55 changes: 52 additions & 3 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ interface Error {

type Result<T> = Ok<T> | Error;

export const DEFAULT_RULES: Array<FloatRule> = [
export const DEFAULT_FLOAT_RULES: Array<FloatRule> = [
{ class: "Floating Window Exceptions"},
{ class: "Authy Desktop", },
{ class: "Enpass", title: "Enpass Assistant" },
{ class: "Zotero", title: "Quick Format Citation" },
{ class: "Com.github.donadigo.eddy", },
{ class: "Conky", },
{ class: "Guake", },
{ class: "Com.github.amezin.ddterm", },
{ class: "gnome-screenshot", },
{ class: "jetbrains-toolbox", },
{ class: "jetbrains-webstorm", title: "License Activation" },
Expand All @@ -45,6 +47,22 @@ export const DEFAULT_RULES: Array<FloatRule> = [
{ class: "Gnome-initial-setup" },
];

export interface WindowRule {
class?: string;
title?: string;
disabled?: boolean;
}

/**
* These windows will skip showing in Overview, Thumbnails or SwitcherList
* And any rule here should be added on the DEFAULT_RULES above
*/
export const SKIPTASKBAR_EXCEPTIONS: Array<WindowRule> = [
{ class: "Conky", },
{ class: "Guake", },
{ class: "Com.github.amezin.ddterm", },
];

export interface FloatRule {
class?: string;
title?: string;
Expand All @@ -62,6 +80,12 @@ export class Config {
/** List of windows that should float, regardless of their WM hints */
float: Array<FloatRule> = [];

/**
* List of Windows with skip taskbar true but still hidden in Overview,
* Switchers, Workspace Thumbnails
*/
skiptaskbarhidden: Array<WindowRule> = [];

/** Logs window details on focus of window */
log_on_focus: boolean = false;

Expand Down Expand Up @@ -92,7 +116,7 @@ export class Config {
}

window_shall_float(wclass: string, title: string): boolean {
for (const rule of this.float.concat(DEFAULT_RULES)) {
for (const rule of this.float.concat(DEFAULT_FLOAT_RULES)) {
if (rule.class) {
if (!new RegExp(rule.class, 'i').test(wclass)) {
continue
Expand All @@ -111,6 +135,31 @@ export class Config {
return false;
}

skiptaskbar_shall_hide(meta_window: any) {
let wmclass = meta_window.get_wm_class();
let wmtitle = meta_window.get_title();

if (!meta_window.is_skip_taskbar()) return false;

for (const rule of this.skiptaskbarhidden.concat(SKIPTASKBAR_EXCEPTIONS)) {
if (rule.class) {
if (!new RegExp(rule.class, 'i').test(wmclass)) {
continue
}
}

if (rule.title) {
if (!new RegExp(rule.title, 'i').test(wmtitle)) {
continue
}
}

return rule.disabled ? false : true;
}

return false;
}

reload() {
const conf = Config.from_config();

Expand Down Expand Up @@ -141,7 +190,7 @@ export class Config {

toggle_system_exception(wmclass: string | undefined, wmtitle: string | undefined, disabled: boolean) {
if (disabled) {
for (const value of DEFAULT_RULES) {
for (const value of DEFAULT_FLOAT_RULES) {
if (value.class === wmclass && value.title === wmtitle) {
value.disabled = disabled;
this.float.push(value);
Expand Down
153 changes: 127 additions & 26 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1745,6 +1745,13 @@ export class Ext extends Ecs.System<ExtEvent> {
case 'smart-gaps':
this.on_smart_gap();
this.show_border_on_focused();
break;
case 'show-skip-taskbar':
if (this.settings.show_skiptaskbar()) {
_show_skip_taskbar_windows(this);
} else {
_hide_skip_taskbar_windows();
}
}
});

Expand Down Expand Up @@ -2404,10 +2411,6 @@ export class Ext extends Ecs.System<ExtEvent> {

let ext: Ext | null = null;
let indicator: Indicator | null = null;
let default_isoverviewwindow_ws: any;
let default_isoverviewwindow_ws_thumbnail: any;
let default_init_appswitcher: any;
let default_getwindowlist_windowswitcher: any;

// @ts-ignore
function init() {
Expand All @@ -2418,8 +2421,6 @@ function init() {
function enable() {
log.info("enable");

_show_skip_taskbar_windows();

if (!ext) {
ext = new Ext();

Expand All @@ -2428,6 +2429,12 @@ function enable() {
});
}

if (ext.settings.show_skiptaskbar()) {
_show_skip_taskbar_windows(ext);
} else {
_hide_skip_taskbar_windows();
}

if (ext.was_locked) {
ext.was_locked = false;
return;
Expand Down Expand Up @@ -2455,8 +2462,6 @@ function enable() {
function disable() {
log.info("disable");

_hide_skip_taskbar_windows();

if (ext) {
if (sessionMode.isLocked) {
ext.was_locked = true;
Expand All @@ -2479,6 +2484,8 @@ function disable() {
ext.auto_tiler.destroy(ext);
ext.auto_tiler = null;
}

_hide_skip_taskbar_windows();
}

if (indicator) {
Expand Down Expand Up @@ -2536,20 +2543,75 @@ function* iter_workspaces(manager: any): IterableIterator<[number, any]> {
}
}

let default_isoverviewwindow_ws: any;
let default_isoverviewwindow_ws_thumbnail: any;
let default_init_appswitcher: any;
let default_getwindowlist_windowswitcher: any;
let default_getcaption_windowpreview: any;
let default_getcaption_workspace: any;

/**
* Decorates the default gnome-shell workspace/overview handling
* of skip_task_bar. And have those window types included in pop-shell.
* Should only be called on extension#enable()
*
* NOTE to future maintainer:
* Skip taskbar has been left out by upstream for a reason. And the
* Shell.WindowTracker seems to skip handling skip taskbar windows, so they are
* null or undefined. GNOME 40+ and lower version checking should be done to
* constantly support having them within pop-shell.
*
* Known skip taskbars ddterm, conky, guake, minimized to tray apps, etc.
*
* While minimize to tray are the target for this feature,
* skip taskbars that float/and avail workspace all
* need to added to config.ts as default floating
*
*/
function _show_skip_taskbar_windows() {
// Handle the overview
default_isoverviewwindow_ws = Workspace.prototype._isOverviewWindow;
Workspace.prototype._isOverviewWindow = function(window: any) {
// wm_class Gjs needs to be skipped to prevent the ghost window in
// workspace and overview
return (window.skip_taskbar && window.get_wm_class() !== "Gjs") ||
default_isoverviewwindow_ws(window);
};
function _show_skip_taskbar_windows(ext: Ext) {
let cfg = ext.conf;
if (!GNOME_VERSION?.startsWith("40.")) {
// TODO GNOME 40 added a call to windowtracker and app var is not checked if null
// in WindowPreview._init(). Then new WindowPreview() is being called on
// _addWindowClone() of workspace.js.
// So it has to be skipped being overriden for now.

// Handle the overview
default_isoverviewwindow_ws = Workspace.prototype._isOverviewWindow;
Workspace.prototype._isOverviewWindow = function(window: any) {
// wm_class Gjs needs to be skipped to prevent the ghost window in
// workspace and overview
let show_skiptb = !cfg.skiptaskbar_shall_hide(window);
return (show_skiptb && window.skip_taskbar && window.get_wm_class() !== "Gjs") ||
default_isoverviewwindow_ws(window);
};
}

// Handle _getCaption errors
if (GNOME_VERSION?.startsWith("3.36")) {
// imports.ui.windowPreview is not in 3.36,
// _getCaption() is still in workspace.js
default_getcaption_workspace = Workspace.prototype._getCaption;
Workspace.prototype._getCaption = function() {
if (this.metaWindow.title)
return this.metaWindow.title;

let tracker = Shell.WindowTracker.get_default();
let app = tracker.get_window_app(this.metaWindow);
return app? app.get_name() : "";
}
} else {
const { WindowPreview } = imports.ui.windowPreview;
default_getcaption_windowpreview = WindowPreview.prototype._getCaption;
WindowPreview.prototype._getCaption = function() {
if (this.metaWindow.title)
return this.metaWindow.title;

let tracker = Shell.WindowTracker.get_default();
let app = tracker.get_window_app(this.metaWindow);
return app? app.get_name() : "";
};
}

// Handle the workspace thumbnail
default_isoverviewwindow_ws_thumbnail =
Expand All @@ -2558,7 +2620,8 @@ function _show_skip_taskbar_windows() {
let meta_win = win.get_meta_window();
// wm_class Gjs needs to be skipped to prevent the ghost window in
// workspace and overview
return (meta_win.skip_taskbar && meta_win.get_wm_class() !== "Gjs") ||
let show_skiptb = !cfg.skiptaskbar_shall_hide(meta_win);
return (show_skiptb && meta_win.skip_taskbar && meta_win.get_wm_class() !== "Gjs") ||
default_isoverviewwindow_ws_thumbnail(win);
};

Expand Down Expand Up @@ -2596,7 +2659,10 @@ function _show_skip_taskbar_windows() {
});

for (let i = 0; i < allRunningSkipTaskbarApps.length; i++) {
let appIcon = new AppIcon(windowTracker.get_window_app(allRunningSkipTaskbarApps[i]));
let meta_win = allRunningSkipTaskbarApps[i];
let show_skiptb = !cfg.skiptaskbar_shall_hide(meta_win);
if (meta_win.is_skip_taskbar() && !show_skiptb) continue;
let appIcon = new AppIcon(windowTracker.get_window_app(meta_win));
appIcon.cachedWindows = allWindows.filter(
w => windowTracker.get_window_app(w) === appIcon.app);
if (appIcon.cachedWindows.length > 0)
Expand All @@ -2623,20 +2689,55 @@ function _show_skip_taskbar_windows() {
let windows = global.display.get_tab_list(Meta.TabList.NORMAL_ALL,
workspace);
return windows.map(w => {
return w.is_attached_dialog() ? w.get_transient_for() : w;
}).filter((w, i, a) => w != null && a.indexOf(w) == i);
let show_skiptb = !cfg.skiptaskbar_shall_hide(w);
let meta_window = w.is_attached_dialog() ? w.get_transient_for() : w;
if (meta_window) {
if (!meta_window.is_skip_taskbar() ||
meta_window.is_skip_taskbar() && show_skiptb) {
return meta_window;
}
}
return null;
}).filter((w, i, a) => w != null && a.indexOf(w) == i);
}
}

/**
* This is the cleanup/restore of the decorator for skip_taskbar when pop-shell
* is disabled.
* Should only be called on extension#disable()
*
* Default functions should be checked if they exist,
* especially when skip taskbar setting was left on during an update
*
*/
function _hide_skip_taskbar_windows() {
Workspace.prototype._isOverviewWindow = default_isoverviewwindow_ws;
WorkspaceThumbnail.prototype._isOverviewWindow =
default_isoverviewwindow_ws_thumbnail;
AppSwitcher.prototype._init = default_init_appswitcher;
WindowSwitcherPopup.prototype._getWindowList = default_getwindowlist_windowswitcher;
if (!GNOME_VERSION?.startsWith("40.")) {
if (default_isoverviewwindow_ws)
Workspace.prototype._isOverviewWindow = default_isoverviewwindow_ws;
}

if (GNOME_VERSION?.startsWith("3.36")) {
if (default_getcaption_workspace)
Workspace.prototype._getCaption = default_getcaption_workspace;
} else {
if (default_getcaption_windowpreview) {
const { WindowPreview } = imports.ui.windowPreview;
WindowPreview.prototype._getCaption =
default_getcaption_windowpreview;
}
}

if (default_isoverviewwindow_ws_thumbnail) {
WorkspaceThumbnail.prototype._isOverviewWindow =
default_isoverviewwindow_ws_thumbnail;
}

if (default_init_appswitcher)
AppSwitcher.prototype._init = default_init_appswitcher;

if (default_getwindowlist_windowswitcher) {
WindowSwitcherPopup.prototype._getWindowList =
default_getwindowlist_windowswitcher;
}
}
15 changes: 11 additions & 4 deletions src/plugin_shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,13 @@ const SELECTIONS: Array<Selection> = [
{
id: 4,
name: "Toggle Window Tiling",
description: "Tiled windows are arranged side by side on the screen"
}

description: "Tiled windows are arranged side by side on the screen",
},
{
id: 5,
name: "Toggle Minimized to Tray Windows (Experimental)",
description: "Handle windows with minimized to tray or skip taskbar option",
},
]

export class ShellBuiltin extends plugins.Builtin {
Expand Down Expand Up @@ -64,8 +68,11 @@ export class ShellBuiltin extends plugins.Builtin {
case 4:
ext.toggle_tiling()
break
case 5:
ext.settings.set_show_skiptaskbar(!ext.settings.show_skiptaskbar());
break
}

return { event: "noop" }
}
}
}