summaryrefslogtreecommitdiffstats
path: root/extensions/45/vertical-workspaces/lib/search.js
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/45/vertical-workspaces/lib/search.js')
-rw-r--r--extensions/45/vertical-workspaces/lib/search.js405
1 files changed, 0 insertions, 405 deletions
diff --git a/extensions/45/vertical-workspaces/lib/search.js b/extensions/45/vertical-workspaces/lib/search.js
deleted file mode 100644
index fc15862..0000000
--- a/extensions/45/vertical-workspaces/lib/search.js
+++ /dev/null
@@ -1,405 +0,0 @@
-/**
- * V-Shell (Vertical Workspaces)
- * search.js
- *
- * @author GdH <G-dH@github.com>
- * @copyright 2022 - 2024
- * @license GPL-3.0
- *
- */
-
-'use strict';
-
-import GLib from 'gi://GLib';
-import Clutter from 'gi://Clutter';
-import St from 'gi://St';
-import Shell from 'gi://Shell';
-import GObject from 'gi://GObject';
-
-import * as Main from 'resource:///org/gnome/shell/ui/main.js';
-import * as Search from 'resource:///org/gnome/shell/ui/search.js';
-import * as AppDisplay from 'resource:///org/gnome/shell/ui/appDisplay.js';
-
-import * as SystemActions from 'resource:///org/gnome/shell/misc/systemActions.js';
-import { Highlighter } from 'resource:///org/gnome/shell/misc/util.js';
-
-let Me;
-// gettext
-let _;
-let opt;
-
-let SEARCH_MAX_WIDTH;
-
-export const SearchModule = class {
- constructor(me) {
- Me = me;
- opt = Me.opt;
- _ = Me.gettext;
-
- this._firstActivation = true;
- this.moduleEnabled = false;
- this._overrides = null;
- }
-
- cleanGlobals() {
- Me = null;
- opt = null;
- _ = null;
- }
-
- update(reset) {
- this.moduleEnabled = opt.get('searchModule');
- const conflict = false;
-
- reset = reset || !this.moduleEnabled || conflict;
-
- // don't touch the original code if module disabled
- if (reset && !this._firstActivation) {
- this._disableModule();
- } else if (!reset) {
- this._firstActivation = false;
- this._activateModule();
- }
- if (reset && this._firstActivation)
- console.debug(' SearchModule - Keeping untouched');
- }
-
- _activateModule() {
- this._updateSearchViewWidth();
-
- if (!this._overrides)
- this._overrides = new Me.Util.Overrides();
-
- this._overrides.addOverride('AppSearchProvider', AppDisplay.AppSearchProvider.prototype, AppSearchProvider);
- this._overrides.addOverride('SearchResult', Search.SearchResult.prototype, SearchResult);
- this._overrides.addOverride('SearchResultsView', Search.SearchResultsView.prototype, SearchResultsView);
- this._overrides.addOverride('ListSearchResults', Search.ListSearchResults.prototype, ListSearchResults);
- this._overrides.addOverride('ListSearchResult', Search.ListSearchResult.prototype, ListSearchResultOverride);
- this._overrides.addOverride('Highlighter', Highlighter.prototype, HighlighterOverride);
-
- // Don't expand the search view vertically and align it to the top
- // this is important in the static workspace mode when the search view bg is not transparent
- // also the "Searching..." and "No Results" notifications will be closer to the search entry, with the distance given by margin-top in the stylesheet
- Main.overview.searchController.y_align = Clutter.ActorAlign.START;
- // Increase the maxResults for app search so that it can show more results in case the user decreases the size of the result icon
- const appSearchDisplay = Main.overview.searchController._searchResults._providers.filter(p => p.id === 'applications')[0]?.display;
- if (appSearchDisplay)
- appSearchDisplay._maxResults = 12;
- console.debug(' SearchModule - Activated');
- }
-
- _disableModule() {
- const reset = true;
-
- const searchResults = Main.overview.searchController._searchResults;
- if (searchResults?._searchTimeoutId) {
- GLib.source_remove(searchResults._searchTimeoutId);
- searchResults._searchTimeoutId = 0;
- }
-
- this._updateSearchViewWidth(reset);
-
- if (this._overrides)
- this._overrides.removeAll();
- this._overrides = null;
-
- Main.overview.searchController.y_align = Clutter.ActorAlign.FILL;
-
- console.debug(' WorkspaceSwitcherPopupModule - Disabled');
- }
-
- _updateSearchViewWidth(reset = false) {
- const searchContent = Main.overview.searchController._searchResults._content;
- if (!SEARCH_MAX_WIDTH) { // just store original value;
- const themeNode = searchContent.get_theme_node();
- const width = themeNode.get_max_width();
- SEARCH_MAX_WIDTH = width;
- }
-
- if (reset) {
- searchContent.set_style('');
- } else {
- let width = Math.round(SEARCH_MAX_WIDTH * opt.SEARCH_VIEW_SCALE);
- searchContent.set_style(`max-width: ${width}px;`);
- }
- }
-};
-
-const ListSearchResults = {
- _getMaxDisplayedResults() {
- return opt.SEARCH_MAX_ROWS;
- },
-};
-
-// AppDisplay.AppSearchProvider
-const AppSearchProvider = {
- getInitialResultSet(terms, cancellable) {
- // Defer until the parental controls manager is initialized, so the
- // results can be filtered correctly.
- if (!this._parentalControlsManager.initialized) {
- return new Promise(resolve => {
- let initializedId = this._parentalControlsManager.connect('app-filter-changed', async () => {
- if (this._parentalControlsManager.initialized) {
- this._parentalControlsManager.disconnect(initializedId);
- resolve(await this.getInitialResultSet(terms, cancellable));
- }
- });
- });
- }
-
- const pattern = terms.join(' ');
-
- let appInfoList = Shell.AppSystem.get_default().get_installed();
-
- let weightList = {};
- appInfoList = appInfoList.filter(appInfo => {
- try {
- appInfo.get_id(); // catch invalid file encodings
- } catch (e) {
- return false;
- }
-
- let string = '';
- let name;
- let shouldShow = false;
- if (appInfo.get_display_name) {
- // show only launchers that should be visible in this DE
- shouldShow = appInfo.should_show() && this._parentalControlsManager.shouldShowApp(appInfo);
-
- if (shouldShow) {
- let id = appInfo.get_id().split('.');
- id = id[id.length - 2] || '';
- let baseName = appInfo.get_string('Name') || '';
- let dispName = appInfo.get_display_name() || '';
- let gName = appInfo.get_generic_name() || '';
- let description = appInfo.get_description() || '';
- let categories = appInfo.get_string('Categories')?.replace(/;/g, ' ') || '';
- let keywords = appInfo.get_string('Keywords')?.replace(/;/g, ' ') || '';
- name = `${dispName} ${id}`;
- string = `${dispName} ${gName} ${baseName} ${description} ${categories} ${keywords} ${id}`;
- }
- }
-
- let m = -1;
- if (shouldShow && opt.SEARCH_FUZZY) {
- m = Me.Util.fuzzyMatch(pattern, name);
- m = (m + Me.Util.strictMatch(pattern, string)) / 2;
- } else if (shouldShow) {
- m = Me.Util.strictMatch(pattern, string);
- }
-
- if (m !== -1)
- weightList[appInfo.get_id()] = m;
-
- return shouldShow && (m !== -1);
- });
-
- appInfoList.sort((a, b) => weightList[a.get_id()] > weightList[b.get_id()]);
-
- const usage = Shell.AppUsage.get_default();
- // sort apps by usage list
- appInfoList.sort((a, b) => usage.compare(a.get_id(), b.get_id()));
- // prefer apps where any word in their name starts with the pattern
- appInfoList.sort((a, b) => Me.Util.isMoreRelevant(a.get_display_name(), b.get_display_name(), pattern));
-
- let results = appInfoList.map(app => app.get_id());
-
- results = results.concat(this._systemActions.getMatchingActions(terms));
-
- return new Promise(resolve => resolve(results));
- },
-
- // App search result size
- createResultObject(resultMeta) {
- if (resultMeta.id.endsWith('.desktop')) {
- const icon = new AppDisplay.AppIcon(this._appSys.lookup_app(resultMeta['id']), {
- expandTitleOnHover: false,
- });
- icon.icon.setIconSize(opt.SEARCH_ICON_SIZE);
- return icon;
- } else {
- return new SystemActionIcon(this, resultMeta);
- // icon.icon._setSizeManually = true;
- // icon.icon.setIconSize(opt.SEARCH_ICON_SIZE);
- // return icon;
- }
- },
-};
-
-const SystemActionIcon = GObject.registerClass(
-class SystemActionIcon extends Search.GridSearchResult {
- _init(provider, metaInfo, resultsView) {
- super._init(provider, metaInfo, resultsView);
- this.icon._setSizeManually = true;
- this.icon.setIconSize(opt.SEARCH_ICON_SIZE);
- }
-
- activate() {
- SystemActions.getDefault().activateAction(this.metaInfo['id']);
- Main.overview.hide();
- }
-});
-
-const SearchResult = {
- activate() {
- this.provider.activateResult(this.metaInfo.id, this._resultsView.terms);
-
- if (this.metaInfo.clipboardText) {
- St.Clipboard.get_default().set_text(
- St.ClipboardType.CLIPBOARD, this.metaInfo.clipboardText);
- }
- // don't close overview if Shift key is pressed - Shift moves windows to the workspace
- if (!Me.Util.isShiftPressed())
- Main.overview.toggle();
- },
-};
-
-const SearchResultsView = {
- setTerms(terms) {
- // Check for the case of making a duplicate previous search before
- // setting state of the current search or cancelling the search.
- // This will prevent incorrect state being as a result of a duplicate
- // search while the previous search is still active.
- let searchString = terms.join(' ');
- let previousSearchString = this._terms.join(' ');
- if (searchString === previousSearchString)
- return;
-
- this._startingSearch = true;
-
- this._cancellable.cancel();
- this._cancellable.reset();
-
- if (terms.length === 0) {
- this._reset();
- return;
- }
-
- let isSubSearch = false;
- if (this._terms.length > 0)
- isSubSearch = searchString.indexOf(previousSearchString) === 0;
-
- this._terms = terms;
- this._isSubSearch = isSubSearch;
- this._updateSearchProgress();
-
- if (!this._searchTimeoutId)
- this._searchTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, opt.SEARCH_DELAY, this._onSearchTimeout.bind(this));
-
- this._highlighter = new Highlighter(this._terms);
-
- this.emit('terms-changed');
- },
-
- _doSearch() {
- this._startingSearch = false;
-
- let previousResults = this._results;
- this._results = {};
-
- const term0 = this._terms[0];
- const onlySupportedProviders = term0.startsWith(Me.WSP_PREFIX) || term0.startsWith(Me.ESP_PREFIX) || term0.startsWith(Me.RFSP_PREFIX);
-
- this._providers.forEach(provider => {
- const supportedProvider = ['open-windows', 'extensions', 'recent-files'].includes(provider.id);
- if (!onlySupportedProviders || (onlySupportedProviders && supportedProvider)) {
- let previousProviderResults = previousResults[provider.id];
- this._doProviderSearch(provider, previousProviderResults);
- } else {
- // hide unwanted providers, they will show() automatically when needed
- provider.display.visible = false;
- }
- });
-
- this._updateSearchProgress();
- this._clearSearchTimeout();
- },
-
- _updateSearchProgress() {
- let haveResults = this._providers.some(provider => {
- let display = provider.display;
- return display.getFirstResult() !== null;
- });
-
- this._scrollView.visible = haveResults;
- this._statusBin.visible = !haveResults;
-
- if (!haveResults) {
- if (this.searchInProgress)
- this._statusText.set_text(_('Searching…'));
- else
- this._statusText.set_text(_('No results.'));
- }
- },
-};
-
-// Add highlighting of the "name" part of the result for all providers
-const ListSearchResultOverride = {
- _highlightTerms() {
- let markup = this._resultsView.highlightTerms(this.metaInfo['name']);
- this.label_actor.clutter_text.set_markup(markup);
- markup = this._resultsView.highlightTerms(this.metaInfo['description'].split('\n')[0]);
- this._descriptionLabel.clutter_text.set_markup(markup);
- },
-};
-
-const HighlighterOverride = {
- /**
- * @param {?string[]} terms - list of terms to highlight
- */
- /* constructor(terms) {
- if (!terms)
- return;
-
- const escapedTerms = terms
- .map(term => Shell.util_regex_escape(term))
- .filter(term => term.length > 0);
-
- if (escapedTerms.length === 0)
- return;
-
- this._highlightRegex = new RegExp(
- `(${escapedTerms.join('|')})`, 'gi');
- },*/
-
- /**
- * Highlight all occurences of the terms defined for this
- * highlighter in the provided text using markup.
- *
- * @param {string} text - text to highlight the defined terms in
- * @returns {string}
- */
- highlight(text, options) {
- if (!this._highlightRegex)
- return GLib.markup_escape_text(text, -1);
-
- // force use local settings if the class is overridden by another extension (WSP, ESP)
- const o = options || opt;
- let escaped = [];
- let lastMatchEnd = 0;
- let match;
- let style = ['', ''];
- if (o.HIGHLIGHT_DEFAULT)
- style = ['<b>', '</b>'];
- // The default highlighting by the bold style causes text to be "randomly" ellipsized in cases where it's not necessary
- // and also blurry
- // Underscore doesn't affect label size and all looks better
- else if (o.HIGHLIGHT_UNDERLINE)
- style = ['<u>', '</u>'];
-
- while ((match = this._highlightRegex.exec(text))) {
- if (match.index > lastMatchEnd) {
- let unmatched = GLib.markup_escape_text(
- text.slice(lastMatchEnd, match.index), -1);
- escaped.push(unmatched);
- }
- let matched = GLib.markup_escape_text(match[0], -1);
- escaped.push(`${style[0]}${matched}${style[1]}`);
- lastMatchEnd = match.index + match[0].length;
- }
- let unmatched = GLib.markup_escape_text(
- text.slice(lastMatchEnd), -1);
- escaped.push(unmatched);
- return escaped.join('');
- },
-};