summaryrefslogtreecommitdiffstats
path: root/extensions/vertical-workspaces/windowSearchProvider.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2023-06-18 13:38:38 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2023-06-18 13:38:38 +0000
commita2afeba6545be9307f6505fd7a29375e89a9075e (patch)
treec598c70f26a350073352322c6d2d4da6952945fa /extensions/vertical-workspaces/windowSearchProvider.js
parentReleasing debian version 20230205-2. (diff)
downloadgnome-shell-extensions-extra-a2afeba6545be9307f6505fd7a29375e89a9075e.tar.xz
gnome-shell-extensions-extra-a2afeba6545be9307f6505fd7a29375e89a9075e.zip
Merging upstream version 20230618.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'extensions/vertical-workspaces/windowSearchProvider.js')
-rw-r--r--extensions/vertical-workspaces/windowSearchProvider.js358
1 files changed, 0 insertions, 358 deletions
diff --git a/extensions/vertical-workspaces/windowSearchProvider.js b/extensions/vertical-workspaces/windowSearchProvider.js
deleted file mode 100644
index 3256742..0000000
--- a/extensions/vertical-workspaces/windowSearchProvider.js
+++ /dev/null
@@ -1,358 +0,0 @@
-/**
- * Vertical Workspaces
- * windowSearchProvider.js
- *
- * @author GdH <G-dH@github.com>
- * @copyright 2022 -2023
- * @license GPL-3.0
- */
-
-'use strict';
-
-const { GLib, GObject, Gio, Gtk, Meta, St, Shell } = imports.gi;
-
-const Main = imports.ui.main;
-const ExtensionUtils = imports.misc.extensionUtils;
-const Me = ExtensionUtils.getCurrentExtension();
-const Settings = Me.imports.settings;
-const _ = Me.imports.settings._;
-
-const shellVersion = Settings.shellVersion;
-
-const ModifierType = imports.gi.Clutter.ModifierType;
-
-let windowSearchProvider;
-let _enableTimeoutId = 0;
-
-// prefix helps to eliminate results from other search providers
-// so it needs to be something less common
-// needs to be accessible from vw module
-var prefix = 'wq//';
-
-let opt;
-
-const Action = {
- NONE: 0,
- CLOSE: 1,
- CLOSE_ALL: 2,
- MOVE_TO_WS: 3,
- MOVE_ALL_TO_WS: 4
-}
-
-function init() {
-}
-
-function getOverviewSearchResult() {
- return Main.overview._overview.controls._searchController._searchResults;
-}
-
-function update(reset = false) {
- opt = Me.imports.settings.opt;
- if (!reset && opt.WINDOW_SEARCH_PROVIDER_ENABLED && !windowSearchProvider) {
- enable();
- } else if (reset || !opt.WINDOW_SEARCH_PROVIDER_ENABLED) {
- disable();
- opt = null;
- }
-}
-
-function enable() {
- // delay because Fedora had problem to register a new provider soon after Shell restarts
- _enableTimeoutId = GLib.timeout_add(
- GLib.PRIORITY_DEFAULT,
- 2000,
- () => {
- if (windowSearchProvider == null) {
- windowSearchProvider = new WindowSearchProvider(opt);
- getOverviewSearchResult()._registerProvider(
- windowSearchProvider
- );
- }
- _enableTimeoutId = 0;
- return GLib.SOURCE_REMOVE;
- }
- );
-}
-
-function disable() {
- if (windowSearchProvider) {
- getOverviewSearchResult()._unregisterProvider(
- windowSearchProvider
- );
- windowSearchProvider = null;
- }
- if (_enableTimeoutId) {
- GLib.source_remove(_enableTimeoutId);
- _enableTimeoutId = 0;
- }
-}
-
-function fuzzyMatch(term, text) {
- let pos = -1;
- const matches = [];
- // convert all accented chars to their basic form and to lower case
- const _text = text;//.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase();
- const _term = term.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase();
-
- // if term matches the substring exactly, gains the highest weight
- if (_text.includes(_term)) {
- return 0;
- }
-
- for (let i = 0; i < _term.length; i++) {
- let c = _term[i];
- let p;
- if (pos > 0)
- p = _term[i - 1];
- while (true) {
- pos += 1;
- if (pos >= _text.length) {
- return -1;
- }
- if (_text[pos] == c) {
- matches.push(pos);
- break;
- } else if (_text[pos] == p) {
- matches.pop();
- matches.push(pos);
- }
- }
- }
-
- // add all position to get a weight of the result
- // results closer to the beginning of the text and term characters closer to each other will gain more weight.
- return matches.reduce((r, p) => r + p) - matches.length * matches[0] + matches[0];
-}
-
-function strictMatch(term, text) {
- // remove diacritics and accents from letters
- let s = text.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase();
- let p = term.toLowerCase();
- let ps = p.split(/ +/);
-
- // allows to use multiple exact patterns separated by a space in arbitrary order
- for (let w of ps) { // escape regex control chars
- if (!s.match(w.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))) {
- return -1;
- }
- }
- return 0;
-}
-
-function makeResult(window, i) {
- const app = Shell.WindowTracker.get_default().get_window_app(window);
- const appName = app ? app.get_name() : 'Unknown';
- const windowTitle = window.get_title();
- const wsIndex = window.get_workspace().index();
-
- return {
- 'id': i,
- // convert all accented chars to their basic form and lower case for search
- 'name': `${wsIndex + 1}: ${windowTitle} ${appName}`.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase(),
- 'appName': appName,
- 'windowTitle': windowTitle,
- 'window': window
- }
-}
-
-const closeSelectedRegex = /^\/x!$/;
-const closeAllResultsRegex = /^\/xa!$/;
-const moveToWsRegex = /^\/m[0-9]+$/;
-const moveAllToWsRegex = /^\/ma[0-9]+$/;
-
-var WindowSearchProvider = class WindowSearchProvider {
- constructor(gOptions) {
- this._gOptions = gOptions;
- this.appInfo = Gio.AppInfo.create_from_commandline('true', 'Open Windows', null);
- this.appInfo.get_description = () => 'List of open windows';
- this.appInfo.get_name = () => 'Open Windows';
- this.appInfo.get_id = () => `${Me.metadata.uuid} ${this.title}`;
- this.appInfo.get_icon = () => Gio.icon_new_for_string('focus-windows-symbolic');
- this.appInfo.should_show = () => true;
- this.title = 'Window Search Provider',
- this.canLaunchSearch = true;
- this.isRemoteProvider = false;
-
- this.action = 0;
- }
-
- _getResultSet (terms) {
- // do not modify original terms
- let termsCopy = [...terms];
- // search for terms without prefix
- termsCopy[0] = termsCopy[0].replace(prefix, '');
-
- /*if (gOptions.get('searchWindowsCommands')) {
- this.action = 0;
- this.targetWs = 0;
-
- const lastTerm = terms[terms.length - 1];
- if (lastTerm.match(closeSelectedRegex)) {
- this.action = Action.CLOSE;
- } else if (lastTerm.match(closeAllResultsRegex)) {
- this.action = Action.CLOSE_ALL;
- } else if (lastTerm.match(moveToWsRegex)) {
- this.action = Action.MOVE_TO_WS;
- } else if (lastTerm.match(moveAllToWsRegex)) {
- this.action = Action.MOVE_ALL_TO_WS;
- }
- if (this.action) {
- terms.pop();
- if (this.action === Action.MOVE_TO_WS || this.action === Action.MOVE_ALL_TO_WS) {
- this.targetWs = parseInt(lastTerm.replace(/^[^0-9]+/, '')) - 1;
- }
- } else if (lastTerm.startsWith('/')) {
- terms.pop();
- }
- }*/
-
- const candidates = this.windows;
- const _terms = [].concat(termsCopy);
- let match;
-
- const term = _terms.join(' ');
- match = (s) => {
- return fuzzyMatch(term, s);
- }
-
- const results = [];
- let m;
- for (let key in candidates) {
- if (this._gOptions.get('searchFuzzy')) {
- m = fuzzyMatch(term, candidates[key].name);
- } else {
- m = strictMatch(term, candidates[key].name);
- }
- if (m !== -1) {
- results.push({ weight: m, id: key });
- }
- }
-
- results.sort((a, b) => a.weight > b.weight);
- const currentWs = global.workspace_manager.get_active_workspace_index();
- // prefer current workspace
- results.sort((a, b) => (this.windows[a.id].window.get_workspace().index() !== currentWs) && (this.windows[b.id].window.get_workspace().index() === currentWs));
- results.sort((a, b) => ((_terms != ' ') && (a.weight > 0 && b.weight === 0)));
-
- this.resultIds = results.map((item) => item.id);
- return this.resultIds;
- }
-
- getResultMetas (resultIds, callback = null) {
- const metas = resultIds.map((id) => this.getResultMeta(id));
- if (shellVersion >= 43) {
- return new Promise(resolve => resolve(metas));
- } else {
- callback(metas);
- }
- }
-
- getResultMeta (resultId) {
- const result = this.windows[resultId];
- const wsIndex = result.window.get_workspace().index();
- const app = Shell.WindowTracker.get_default().get_window_app(result.window);
- return {
- 'id': resultId,
- 'name': `${wsIndex + 1}: ${result.windowTitle}`,
- 'description': result.appName,
- 'createIcon': (size) => {
- return app
- ? app.create_icon_texture(size)
- : new St.Icon({ icon_name: 'icon-missing', icon_size: size });
- }
- }
- }
-
- launchSearch(terms, timeStamp) {
- }
-
- activateResult (resultId, terms, timeStamp) {
- const [,,state] = global.get_pointer();
-
- const isCtrlPressed = (state & ModifierType.CONTROL_MASK) != 0;
- const isShiftPressed = (state & ModifierType.SHIFT_MASK) != 0;
-
- this.action = 0;
- this.targetWs = 0;
-
- this.targetWs = global.workspaceManager.get_active_workspace().index() + 1;
- if (isShiftPressed && !isCtrlPressed) {
- this.action = Action.MOVE_TO_WS;
- } else if (isShiftPressed && isCtrlPressed) {
- this.action = Action.MOVE_ALL_TO_WS;
- }
-
- if (!this.action) {
- const result = this.windows[resultId];
- Main.activateWindow(result.window);
- return;
- }
-
- switch (this.action) {
- case Action.CLOSE:
- this._closeWindows([resultId]);
- break;
- case Action.CLOSE_ALL:
- this._closeWindows(this.resultIds);
- break;
- case Action.MOVE_TO_WS:
- this._moveWindowsToWs(resultId, [resultId]);
- break;
- case Action.MOVE_ALL_TO_WS:
- this._moveWindowsToWs(resultId, this.resultIds);
- break;
- }
- }
-
- _closeWindows(ids) {
- let time = global.get_current_time();
- for (let i = 0; i < ids.length; i++) {
- this.windows[ids[i]].window.delete(time + i);
- }
- Main.notify('Window Search Provider', `Closed ${ids.length} windows.`);
- }
-
- _moveWindowsToWs(selectedId, resultIds) {
- const workspace = global.workspaceManager.get_active_workspace();
-
- for (let i = 0; i < resultIds.length; i++) {
- this.windows[resultIds[i]].window.change_workspace(workspace);
- }
- const selectedWin = this.windows[selectedId].window;
- selectedWin.activate_with_workspace(global.get_current_time(), workspace);
- }
-
- getInitialResultSet (terms, callback, cancellable = null) {
- if (shellVersion >=43) {
- cancellable = callback;
- }
- let windows;
- this.windows = windows = {};
- global.display.get_tab_list(Meta.TabList.NORMAL, null).filter(w => w.get_workspace() !== null).map(
- (v, i) => windows[`${i}-${v.get_id()}`] = makeResult(v, `${i}-${v.get_id()}`)
- );
-
-
-
- if (shellVersion >= 43) {
- return new Promise(resolve => resolve(this._getResultSet(terms)));
- } else {
- callback(this._getResultSet(terms));
- }
- }
-
- filterResults (results, maxResults) {
- //return results.slice(0, maxResults);
- return results;
- }
-
- getSubsearchResultSet (previousResults, terms, callback, cancellable) {
- // if we return previous results, quick typers get non-actual results
- callback(this._getResultSet(terms));
- }
-
- createResultOjbect(resultMeta) {
- const app = Shell.WindowTracker.get_default().get_window_app(resultMeta.id);
- return new AppIcon(app);
- }
-}