1
0
Fork 0
gnome-shell-extensions-extra/extensions/vertical-workspaces/lib/search.js

207 lines
7 KiB
JavaScript
Raw Normal View History

/**
* V-Shell (Vertical Workspaces)
* search.js
*
* @author GdH <G-dH@github.com>
* @copyright 2022 - 2023
* @license GPL-3.0
*
*/
'use strict';
const { Shell, Gio, St, Clutter } = imports.gi;
const Main = imports.ui.main;
const AppDisplay = imports.ui.appDisplay;
const Search = imports.ui.search;
const Me = imports.misc.extensionUtils.getCurrentExtension();
const _Util = Me.imports.lib.util;
const _ = Me.imports.lib.settings._;
const shellVersion = _Util.shellVersion;
let opt;
let _overrides;
let _firstRun = true;
let SEARCH_MAX_WIDTH;
function update(reset = false) {
opt = Me.imports.lib.settings.opt;
const moduleEnabled = opt.get('searchModule', true);
reset = reset || !moduleEnabled;
// don't even touch this module if disabled
if (_firstRun && reset)
return;
_firstRun = false;
if (_overrides)
_overrides.removeAll();
_updateSearchViewWidth(reset);
if (reset) {
Main.overview._overview._controls.layoutManager._searchController.y_align = Clutter.ActorAlign.FILL;
opt = null;
_overrides = null;
return;
}
_overrides = new _Util.Overrides();
_overrides.addOverride('AppSearchProvider', AppDisplay.AppSearchProvider.prototype, AppSearchProvider);
_overrides.addOverride('SearchResult', Search.SearchResult.prototype, SearchResult);
_overrides.addOverride('SearchResultsView', Search.SearchResultsView.prototype, SearchResultsView);
// 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._overview._controls.layoutManager._searchController.y_align = Clutter.ActorAlign.START;
}
function _updateSearchViewWidth(reset = false) {
const searchContent = Main.overview._overview._controls.layoutManager._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;`);
}
}
// AppDisplay.AppSearchProvider
const AppSearchProvider = {
getInitialResultSet(terms, callback, _cancellable) {
// Defer until the parental controls manager is initialized, so the
// results can be filtered correctly.
if (!this._parentalControlsManager.initialized) {
let initializedId = this._parentalControlsManager.connect('app-filter-changed', () => {
if (this._parentalControlsManager.initialized) {
this._parentalControlsManager.disconnect(initializedId);
this.getInitialResultSet(terms, callback, _cancellable);
}
});
return;
}
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 dispName = appInfo.get_display_name() || '';
let gName = appInfo.get_generic_name() || '';
let description = appInfo.get_description() || '';
let categories = appInfo.get_string('Categories') || '';
let keywords = appInfo.get_string('Keywords') || '';
name = dispName;
string = `${dispName} ${gName} ${description} ${categories} ${keywords}`;
}
}
let m = -1;
if (shouldShow && opt.SEARCH_FUZZY) {
m = _Util.fuzzyMatch(pattern, name);
m = (m + _Util.strictMatch(pattern, string)) / 2;
} else if (shouldShow) {
m = _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) => _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));
if (shellVersion < 43)
callback(results);
else
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 {
const icon = new AppDisplay.SystemActionIcon(this, resultMeta);
icon.icon._setSizeManually = true;
icon.icon.setIconSize(opt.SEARCH_ICON_SIZE);
return icon;
}
},
};
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 (!_Util.isShiftPressed())
Main.overview.toggle();
},
};
const SearchResultsView = {
_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.'));
}
},
};