mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
Launcher: refactor, renaming plugins to providers to avoid confusion with the plugin system.
This commit is contained in:
@@ -6,7 +6,7 @@ import Quickshell.Widgets
|
||||
import "../../../Helpers/AdvancedMath.js" as AdvancedMath
|
||||
import "../../../Helpers/FuzzySort.js" as Fuzzysort
|
||||
|
||||
import "Plugins"
|
||||
import "Providers"
|
||||
import qs.Commons
|
||||
import qs.Modules.MainScreen
|
||||
import qs.Services.Keyboard
|
||||
@@ -50,8 +50,8 @@ SmartPanel {
|
||||
property string searchText: ""
|
||||
property int selectedIndex: 0
|
||||
property var results: []
|
||||
property var plugins: []
|
||||
property var activePlugin: null
|
||||
property var providers: []
|
||||
property var activeProvider: null
|
||||
property bool resultsReady: false
|
||||
property bool ignoreMouseHover: Settings.data.appLauncher.ignoreMouseInput
|
||||
|
||||
@@ -62,7 +62,7 @@ SmartPanel {
|
||||
if (searchText.startsWith(">clip") || searchText.startsWith(">calc")) {
|
||||
return false;
|
||||
}
|
||||
if (activePlugin === emojiPlugin && emojiPlugin.isBrowsingMode) {
|
||||
if (activeProvider === emojiProvider && emojiProvider.isBrowsingMode) {
|
||||
return true;
|
||||
}
|
||||
return Settings.data.appLauncher.viewMode === "grid";
|
||||
@@ -84,31 +84,31 @@ SmartPanel {
|
||||
// They are instead being forwared from the search field NTextInput below.
|
||||
function onTabPressed() {
|
||||
// In emoji browsing mode, Tab navigates between categories
|
||||
if (activePlugin === emojiPlugin && emojiPlugin.isBrowsingMode) {
|
||||
var currentIndex = emojiPlugin.categories.indexOf(emojiPlugin.selectedCategory);
|
||||
var nextIndex = (currentIndex + 1) % emojiPlugin.categories.length;
|
||||
emojiPlugin.selectCategory(emojiPlugin.categories[nextIndex]);
|
||||
} else if ((activePlugin === null || activePlugin === appsPlugin) && appsPlugin.isBrowsingMode && !root.searchText.startsWith(">") && Settings.data.appLauncher.showCategories) {
|
||||
if (activeProvider === emojiProvider && emojiProvider.isBrowsingMode) {
|
||||
var currentIndex = emojiProvider.categories.indexOf(emojiProvider.selectedCategory);
|
||||
var nextIndex = (currentIndex + 1) % emojiProvider.categories.length;
|
||||
emojiProvider.selectCategory(emojiProvider.categories[nextIndex]);
|
||||
} else if ((activeProvider === null || activeProvider === appsProvider) && appsProvider.isBrowsingMode && !root.searchText.startsWith(">") && Settings.data.appLauncher.showCategories) {
|
||||
// In apps browsing mode (no search), Tab navigates between categories
|
||||
var availableCategories = appsPlugin.availableCategories || ["all"];
|
||||
var currentIndex = availableCategories.indexOf(appsPlugin.selectedCategory);
|
||||
var availableCategories = appsProvider.availableCategories || ["all"];
|
||||
var currentIndex = availableCategories.indexOf(appsProvider.selectedCategory);
|
||||
var nextIndex = (currentIndex + 1) % availableCategories.length;
|
||||
appsPlugin.selectCategory(availableCategories[nextIndex]);
|
||||
appsProvider.selectCategory(availableCategories[nextIndex]);
|
||||
} else {
|
||||
selectNextWrapped();
|
||||
}
|
||||
}
|
||||
|
||||
function onBackTabPressed() {
|
||||
if (activePlugin === emojiPlugin && emojiPlugin.isBrowsingMode) {
|
||||
var currentIndex = emojiPlugin.categories.indexOf(emojiPlugin.selectedCategory);
|
||||
var previousIndex = ((currentIndex - 1) % emojiPlugin.categories.length + emojiPlugin.categories.length) % emojiPlugin.categories.length;
|
||||
emojiPlugin.selectCategory(emojiPlugin.categories[previousIndex]);
|
||||
} else if ((activePlugin === null || activePlugin === appsPlugin) && appsPlugin.isBrowsingMode && !root.searchText.startsWith(">") && Settings.data.appLauncher.showCategories) {
|
||||
var availableCategories = appsPlugin.availableCategories || ["all"];
|
||||
var currentIndex = availableCategories.indexOf(appsPlugin.selectedCategory);
|
||||
if (activeProvider === emojiProvider && emojiProvider.isBrowsingMode) {
|
||||
var currentIndex = emojiProvider.categories.indexOf(emojiProvider.selectedCategory);
|
||||
var previousIndex = ((currentIndex - 1) % emojiProvider.categories.length + emojiProvider.categories.length) % emojiProvider.categories.length;
|
||||
emojiProvider.selectCategory(emojiProvider.categories[previousIndex]);
|
||||
} else if ((activeProvider === null || activeProvider === appsProvider) && appsProvider.isBrowsingMode && !root.searchText.startsWith(">") && Settings.data.appLauncher.showCategories) {
|
||||
var availableCategories = appsProvider.availableCategories || ["all"];
|
||||
var currentIndex = availableCategories.indexOf(appsProvider.selectedCategory);
|
||||
var previousIndex = ((currentIndex - 1) % availableCategories.length + availableCategories.length) % availableCategories.length;
|
||||
appsPlugin.selectCategory(availableCategories[previousIndex]);
|
||||
appsProvider.selectCategory(availableCategories[previousIndex]);
|
||||
} else {
|
||||
selectPreviousWrapped();
|
||||
}
|
||||
@@ -188,24 +188,24 @@ SmartPanel {
|
||||
// Delete clipboard entry if one is selected
|
||||
if (selectedIndex >= 0 && results && results[selectedIndex] && results[selectedIndex].clipboardId) {
|
||||
const clipboardId = results[selectedIndex].clipboardId;
|
||||
clipPlugin.gotResults = false;
|
||||
clipPlugin.isWaitingForData = true;
|
||||
clipPlugin.lastSearchText = root.searchText;
|
||||
clipProvider.gotResults = false;
|
||||
clipProvider.isWaitingForData = true;
|
||||
clipProvider.lastSearchText = root.searchText;
|
||||
ClipboardService.deleteById(String(clipboardId));
|
||||
}
|
||||
}
|
||||
|
||||
// Public API for plugins
|
||||
// Public API for providers
|
||||
function setSearchText(text) {
|
||||
searchText = text;
|
||||
}
|
||||
|
||||
// Plugin registration
|
||||
function registerPlugin(plugin) {
|
||||
plugins.push(plugin);
|
||||
plugin.launcher = root;
|
||||
if (plugin.init)
|
||||
plugin.init();
|
||||
// Provider registration
|
||||
function registerProvider(provider) {
|
||||
providers.push(provider);
|
||||
provider.launcher = root;
|
||||
if (provider.init)
|
||||
provider.init();
|
||||
}
|
||||
|
||||
// Caclualtor handling
|
||||
@@ -261,26 +261,26 @@ SmartPanel {
|
||||
// Search handling
|
||||
function updateResults() {
|
||||
results = [];
|
||||
activePlugin = null;
|
||||
activeProvider = null;
|
||||
|
||||
// Check for command mode
|
||||
if (searchText.startsWith(">")) {
|
||||
// Find plugin that handles this command
|
||||
for (let plugin of plugins) {
|
||||
if (plugin.handleCommand && plugin.handleCommand(searchText)) {
|
||||
activePlugin = plugin;
|
||||
results = plugin.getResults(searchText);
|
||||
// Find provider that handles this command
|
||||
for (let provider of providers) {
|
||||
if (provider.handleCommand && provider.handleCommand(searchText)) {
|
||||
activeProvider = provider;
|
||||
results = provider.getResults(searchText);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Show available commands if just ">" or filter commands if partial match
|
||||
if (!activePlugin) {
|
||||
// Collect all commands from all plugins
|
||||
if (!activeProvider) {
|
||||
// Collect all commands from all providers
|
||||
let allCommands = [];
|
||||
for (let plugin of plugins) {
|
||||
if (plugin.commands) {
|
||||
allCommands = allCommands.concat(plugin.commands());
|
||||
for (let provider of providers) {
|
||||
if (provider.commands) {
|
||||
allCommands = allCommands.concat(provider.commands());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,11 +312,11 @@ SmartPanel {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Regular search - let plugins contribute results
|
||||
for (let plugin of plugins) {
|
||||
if (plugin.handleSearch) {
|
||||
const pluginResults = plugin.getResults(searchText);
|
||||
results = results.concat(pluginResults);
|
||||
// Regular search - let providers contribute results
|
||||
for (let provider of providers) {
|
||||
if (provider.handleSearch) {
|
||||
const providerResults = provider.getResults(searchText);
|
||||
results = results.concat(providerResults);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,12 +337,12 @@ SmartPanel {
|
||||
resultsReady = false;
|
||||
ignoreMouseHover = true;
|
||||
|
||||
// Notify plugins and update results
|
||||
// Use Qt.callLater to ensure plugins are registered (Component.onCompleted runs first)
|
||||
// Notify providers and update results
|
||||
// Use Qt.callLater to ensure providers are registered (Component.onCompleted runs first)
|
||||
Qt.callLater(() => {
|
||||
for (let plugin of plugins) {
|
||||
if (plugin.onOpened)
|
||||
plugin.onOpened();
|
||||
for (let provider of providers) {
|
||||
if (provider.onOpened)
|
||||
provider.onOpened();
|
||||
}
|
||||
updateResults();
|
||||
resultsReady = true;
|
||||
@@ -354,53 +354,53 @@ SmartPanel {
|
||||
searchText = "";
|
||||
ignoreMouseHover = true;
|
||||
|
||||
// Notify plugins
|
||||
for (let plugin of plugins) {
|
||||
if (plugin.onClosed)
|
||||
plugin.onClosed();
|
||||
// Notify providers
|
||||
for (let provider of providers) {
|
||||
if (provider.onClosed)
|
||||
provider.onClosed();
|
||||
}
|
||||
}
|
||||
|
||||
// Plugin components - declared inline so imports work correctly
|
||||
ApplicationsPlugin {
|
||||
id: appsPlugin
|
||||
// Provider components - declared inline so imports work correctly
|
||||
ApplicationsProvider {
|
||||
id: appsProvider
|
||||
Component.onCompleted: {
|
||||
registerPlugin(this);
|
||||
Logger.d("Launcher", "Registered: ApplicationsPlugin");
|
||||
registerProvider(this);
|
||||
Logger.d("Launcher", "Registered: ApplicationsProvider");
|
||||
}
|
||||
}
|
||||
|
||||
CalculatorPlugin {
|
||||
id: calcPlugin
|
||||
CalculatorProvider {
|
||||
id: calcProvider
|
||||
Component.onCompleted: {
|
||||
registerPlugin(this);
|
||||
Logger.d("Launcher", "Registered: CalculatorPlugin");
|
||||
registerProvider(this);
|
||||
Logger.d("Launcher", "Registered: CalculatorProvider");
|
||||
}
|
||||
}
|
||||
|
||||
ClipboardPlugin {
|
||||
id: clipPlugin
|
||||
ClipboardProvider {
|
||||
id: clipProvider
|
||||
Component.onCompleted: {
|
||||
if (Settings.data.appLauncher.enableClipboardHistory) {
|
||||
registerPlugin(this);
|
||||
Logger.d("Launcher", "Registered: ClipboardPlugin");
|
||||
registerProvider(this);
|
||||
Logger.d("Launcher", "Registered: ClipboardProvider");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CommandPlugin {
|
||||
id: cmdPlugin
|
||||
CommandProvider {
|
||||
id: cmdProvider
|
||||
Component.onCompleted: {
|
||||
registerPlugin(this);
|
||||
Logger.d("Launcher", "Registered: CommandPlugin");
|
||||
registerProvider(this);
|
||||
Logger.d("Launcher", "Registered: CommandProvider");
|
||||
}
|
||||
}
|
||||
|
||||
EmojiPlugin {
|
||||
id: emojiPlugin
|
||||
EmojiProvider {
|
||||
id: emojiProvider
|
||||
Component.onCompleted: {
|
||||
registerPlugin(this);
|
||||
Logger.d("Launcher", "Registered: EmojiPlugin");
|
||||
registerProvider(this);
|
||||
Logger.d("Launcher", "Registered: EmojiProvider");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -728,7 +728,7 @@ SmartPanel {
|
||||
}
|
||||
|
||||
NIconButton {
|
||||
visible: root.activePlugin === null || root.activePlugin === appsPlugin
|
||||
visible: root.activeProvider === null || root.activeProvider === appsProvider
|
||||
icon: Settings.data.appLauncher.viewMode === "grid" ? "layout-list" : "layout-grid"
|
||||
tooltipText: Settings.data.appLauncher.viewMode === "grid" ? I18n.tr("tooltips.list-view") : I18n.tr("tooltips.grid-view")
|
||||
Layout.preferredWidth: searchInput.height
|
||||
@@ -742,41 +742,41 @@ SmartPanel {
|
||||
// Emoji category tabs (shown when in browsing mode)
|
||||
NTabBar {
|
||||
id: emojiCategoryTabs
|
||||
visible: root.activePlugin === emojiPlugin && emojiPlugin.isBrowsingMode
|
||||
visible: root.activeProvider === emojiProvider && emojiProvider.isBrowsingMode
|
||||
Layout.fillWidth: true
|
||||
margins: Style.marginM
|
||||
property int computedCurrentIndex: {
|
||||
if (visible && emojiPlugin.categories) {
|
||||
return emojiPlugin.categories.indexOf(emojiPlugin.selectedCategory);
|
||||
if (visible && emojiProvider.categories) {
|
||||
return emojiProvider.categories.indexOf(emojiProvider.selectedCategory);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
currentIndex: computedCurrentIndex
|
||||
|
||||
Repeater {
|
||||
model: emojiPlugin.categories
|
||||
model: emojiProvider.categories
|
||||
NIconTabButton {
|
||||
required property string modelData
|
||||
required property int index
|
||||
icon: emojiPlugin.categoryIcons[modelData] || "star"
|
||||
tooltipText: emojiPlugin.getCategoryName ? emojiPlugin.getCategoryName(modelData) : modelData
|
||||
icon: emojiProvider.categoryIcons[modelData] || "star"
|
||||
tooltipText: emojiProvider.getCategoryName ? emojiProvider.getCategoryName(modelData) : modelData
|
||||
tabIndex: index
|
||||
checked: emojiCategoryTabs.currentIndex === index
|
||||
onClicked: {
|
||||
emojiPlugin.selectCategory(modelData);
|
||||
emojiProvider.selectCategory(modelData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: emojiPlugin
|
||||
target: emojiProvider
|
||||
enabled: emojiCategoryTabs.visible
|
||||
function onSelectedCategoryChanged() {
|
||||
// Force update of currentIndex when selectedCategory changes
|
||||
Qt.callLater(() => {
|
||||
if (emojiCategoryTabs.visible && emojiPlugin.categories) {
|
||||
const newIndex = emojiPlugin.categories.indexOf(emojiPlugin.selectedCategory);
|
||||
if (emojiCategoryTabs.visible && emojiProvider.categories) {
|
||||
const newIndex = emojiProvider.categories.indexOf(emojiProvider.selectedCategory);
|
||||
if (newIndex >= 0 && emojiCategoryTabs.currentIndex !== newIndex) {
|
||||
emojiCategoryTabs.currentIndex = newIndex;
|
||||
}
|
||||
@@ -788,41 +788,41 @@ SmartPanel {
|
||||
// App category tabs (shown when browsing apps without search)
|
||||
NTabBar {
|
||||
id: appCategoryTabs
|
||||
visible: (root.activePlugin === null || root.activePlugin === appsPlugin) && appsPlugin.isBrowsingMode && !root.searchText.startsWith(">") && Settings.data.appLauncher.showCategories
|
||||
visible: (root.activeProvider === null || root.activeProvider === appsProvider) && appsProvider.isBrowsingMode && !root.searchText.startsWith(">") && Settings.data.appLauncher.showCategories
|
||||
Layout.fillWidth: true
|
||||
margins: Style.marginM
|
||||
property int computedCurrentIndex: {
|
||||
if (visible && appsPlugin.availableCategories) {
|
||||
return appsPlugin.availableCategories.indexOf(appsPlugin.selectedCategory);
|
||||
if (visible && appsProvider.availableCategories) {
|
||||
return appsProvider.availableCategories.indexOf(appsProvider.selectedCategory);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
currentIndex: computedCurrentIndex
|
||||
|
||||
Repeater {
|
||||
model: appsPlugin.availableCategories || []
|
||||
model: appsProvider.availableCategories || []
|
||||
NIconTabButton {
|
||||
required property string modelData
|
||||
required property int index
|
||||
icon: appsPlugin.categoryIcons[modelData] || "apps"
|
||||
tooltipText: appsPlugin.getCategoryName ? appsPlugin.getCategoryName(modelData) : modelData
|
||||
icon: appsProvider.categoryIcons[modelData] || "apps"
|
||||
tooltipText: appsProvider.getCategoryName ? appsProvider.getCategoryName(modelData) : modelData
|
||||
tabIndex: index
|
||||
checked: appCategoryTabs.currentIndex === index
|
||||
onClicked: {
|
||||
appsPlugin.selectCategory(modelData);
|
||||
appsProvider.selectCategory(modelData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: appsPlugin
|
||||
target: appsProvider
|
||||
enabled: appCategoryTabs.visible
|
||||
function onSelectedCategoryChanged() {
|
||||
// Force update of currentIndex when selectedCategory changes
|
||||
Qt.callLater(() => {
|
||||
if (appCategoryTabs.visible && appsPlugin.availableCategories) {
|
||||
const newIndex = appsPlugin.availableCategories.indexOf(appsPlugin.selectedCategory);
|
||||
if (appCategoryTabs.visible && appsProvider.availableCategories) {
|
||||
const newIndex = appsProvider.availableCategories.indexOf(appsProvider.selectedCategory);
|
||||
if (newIndex >= 0 && appCategoryTabs.currentIndex !== newIndex) {
|
||||
appCategoryTabs.currentIndex = newIndex;
|
||||
}
|
||||
@@ -1109,14 +1109,14 @@ SmartPanel {
|
||||
NIconButton {
|
||||
visible: !!modelData.clipboardId && entry.isSelected
|
||||
icon: "trash"
|
||||
tooltipText: I18n.tr("plugins.clipboard-delete")
|
||||
tooltipText: I18n.tr("launcher.providers.clipboard-delete")
|
||||
z: 1
|
||||
onClicked: {
|
||||
if (modelData.clipboardId) {
|
||||
// Set plugin state before deletion so refresh works
|
||||
clipPlugin.gotResults = false;
|
||||
clipPlugin.isWaitingForData = true;
|
||||
clipPlugin.lastSearchText = root.searchText;
|
||||
// Set provider state before deletion so refresh works
|
||||
clipProvider.gotResults = false;
|
||||
clipProvider.isWaitingForData = true;
|
||||
clipProvider.lastSearchText = root.searchText;
|
||||
// Delete the item - deleteById now uses Process and will refresh automatically
|
||||
ClipboardService.deleteById(String(modelData.clipboardId));
|
||||
}
|
||||
@@ -1162,7 +1162,7 @@ SmartPanel {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
cellWidth: {
|
||||
if (root.activePlugin === emojiPlugin && emojiPlugin.isBrowsingMode) {
|
||||
if (root.activeProvider === emojiProvider && emojiProvider.isBrowsingMode) {
|
||||
return parent.width / root.targetGridColumns;
|
||||
}
|
||||
// Make cells fit exactly like the tab bar
|
||||
@@ -1170,7 +1170,7 @@ SmartPanel {
|
||||
return parent.width / root.targetGridColumns;
|
||||
}
|
||||
cellHeight: {
|
||||
if (root.activePlugin === emojiPlugin && emojiPlugin.isBrowsingMode) {
|
||||
if (root.activeProvider === emojiProvider && emojiProvider.isBrowsingMode) {
|
||||
return (parent.width / root.targetGridColumns) * 1.2;
|
||||
}
|
||||
// Cell height scales automatically as parent.width scales with uiScaleRatio
|
||||
@@ -1195,7 +1195,7 @@ SmartPanel {
|
||||
function updateGridColumns() {
|
||||
// Update gridColumns based on actual GridView width
|
||||
// This ensures navigation works correctly regardless of panel size
|
||||
if (root.activePlugin === emojiPlugin && emojiPlugin.isBrowsingMode) {
|
||||
if (root.activeProvider === emojiProvider && emojiProvider.isBrowsingMode) {
|
||||
// Always 5 columns for emoji browsing mode
|
||||
root.gridColumns = 5;
|
||||
} else {
|
||||
@@ -1220,9 +1220,9 @@ SmartPanel {
|
||||
|
||||
// Update gridColumns when entering/exiting emoji browsing mode
|
||||
Connections {
|
||||
target: emojiPlugin
|
||||
target: emojiProvider
|
||||
function onIsBrowsingModeChanged() {
|
||||
if (emojiPlugin.isBrowsingMode) {
|
||||
if (emojiProvider.isBrowsingMode) {
|
||||
root.gridColumns = 5;
|
||||
}
|
||||
}
|
||||
@@ -1302,14 +1302,14 @@ SmartPanel {
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: (root.activePlugin === emojiPlugin && emojiPlugin.isBrowsingMode) ? 4 : Style.marginM
|
||||
anchors.bottomMargin: (root.activePlugin === emojiPlugin && emojiPlugin.isBrowsingMode) ? Style.marginL : Style.marginM
|
||||
anchors.margins: (root.activeProvider === emojiProvider && emojiProvider.isBrowsingMode) ? 4 : Style.marginM
|
||||
anchors.bottomMargin: (root.activeProvider === emojiProvider && emojiProvider.isBrowsingMode) ? Style.marginL : Style.marginM
|
||||
spacing: Style.marginS
|
||||
|
||||
// Icon badge or Image preview or Emoji
|
||||
Rectangle {
|
||||
Layout.preferredWidth: {
|
||||
if (root.activePlugin === emojiPlugin && emojiPlugin.isBrowsingMode && modelData.emojiChar) {
|
||||
if (root.activeProvider === emojiProvider && emojiProvider.isBrowsingMode && modelData.emojiChar) {
|
||||
return gridEntry.width - 8;
|
||||
}
|
||||
// Scale badge relative to cell size for proper scaling on all resolutions
|
||||
@@ -1317,7 +1317,7 @@ SmartPanel {
|
||||
return Math.round(gridEntry.width * 0.6);
|
||||
}
|
||||
Layout.preferredHeight: {
|
||||
if (root.activePlugin === emojiPlugin && emojiPlugin.isBrowsingMode && modelData.emojiChar) {
|
||||
if (root.activeProvider === emojiProvider && emojiProvider.isBrowsingMode && modelData.emojiChar) {
|
||||
return gridEntry.width - 8;
|
||||
}
|
||||
// Scale badge relative to cell size for proper scaling on all resolutions
|
||||
@@ -1406,7 +1406,7 @@ SmartPanel {
|
||||
text: modelData.emojiChar ? modelData.emojiChar : modelData.name.charAt(0).toUpperCase()
|
||||
pointSize: {
|
||||
if (modelData.emojiChar) {
|
||||
if (root.activePlugin === emojiPlugin && emojiPlugin.isBrowsingMode) {
|
||||
if (root.activeProvider === emojiProvider && emojiProvider.isBrowsingMode) {
|
||||
// Scale with cell width but cap at reasonable maximum
|
||||
const cellBasedSize = gridEntry.width * 0.4;
|
||||
const maxSize = Style.fontSizeXXXL * Style.uiScaleRatio;
|
||||
@@ -1429,7 +1429,7 @@ SmartPanel {
|
||||
NText {
|
||||
text: modelData.name || "Unknown"
|
||||
pointSize: {
|
||||
if (root.activePlugin === emojiPlugin && emojiPlugin.isBrowsingMode && modelData.emojiChar) {
|
||||
if (root.activeProvider === emojiProvider && emojiProvider.isBrowsingMode && modelData.emojiChar) {
|
||||
return Style.fontSizeS * Style.uiScaleRatio;
|
||||
}
|
||||
// Scale font size relative to cell width for low res, but cap at maximum
|
||||
@@ -1443,8 +1443,8 @@ SmartPanel {
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: gridEntry.width - 8
|
||||
Layout.leftMargin: (root.activePlugin === emojiPlugin && emojiPlugin.isBrowsingMode && modelData.emojiChar) ? Style.marginS : 0
|
||||
Layout.rightMargin: (root.activePlugin === emojiPlugin && emojiPlugin.isBrowsingMode && modelData.emojiChar) ? Style.marginS : 0
|
||||
Layout.leftMargin: (root.activeProvider === emojiProvider && emojiProvider.isBrowsingMode && modelData.emojiChar) ? Style.marginS : 0
|
||||
Layout.rightMargin: (root.activeProvider === emojiProvider && emojiProvider.isBrowsingMode && modelData.emojiChar) ? Style.marginS : 0
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.NoWrap
|
||||
maximumLineCount: 1
|
||||
@@ -1472,14 +1472,14 @@ SmartPanel {
|
||||
NIconButton {
|
||||
visible: !!modelData.clipboardId && gridEntry.isSelected
|
||||
icon: "trash"
|
||||
tooltipText: I18n.tr("plugins.clipboard-delete")
|
||||
tooltipText: I18n.tr("launcher.providers.clipboard-delete")
|
||||
z: 11
|
||||
onClicked: {
|
||||
if (modelData.clipboardId) {
|
||||
// Set plugin state before deletion so refresh works
|
||||
clipPlugin.gotResults = false;
|
||||
clipPlugin.isWaitingForData = true;
|
||||
clipPlugin.lastSearchText = root.searchText;
|
||||
// Set provider state before deletion so refresh works
|
||||
clipProvider.gotResults = false;
|
||||
clipProvider.isWaitingForData = true;
|
||||
clipProvider.lastSearchText = root.searchText;
|
||||
// Delete the item - deleteById now uses Process and will refresh automatically
|
||||
ClipboardService.deleteById(String(modelData.clipboardId));
|
||||
}
|
||||
@@ -1521,12 +1521,12 @@ SmartPanel {
|
||||
if (results.length === 0) {
|
||||
if (searchText) {
|
||||
return "No results";
|
||||
} else if (activePlugin === emojiPlugin && emojiPlugin.isBrowsingMode && emojiPlugin.selectedCategory === "recent") {
|
||||
} else if (activeProvider === emojiProvider && emojiProvider.isBrowsingMode && emojiProvider.selectedCategory === "recent") {
|
||||
return "No recently used emoji";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
var prefix = activePlugin && activePlugin.name ? activePlugin.name + ": " : "";
|
||||
var prefix = activeProvider && activeProvider.name ? activeProvider.name + ": " : "";
|
||||
return prefix + results.length + " result" + (results.length !== 1 ? 's' : '');
|
||||
}
|
||||
pointSize: Style.fontSizeXS
|
||||
|
||||
+9
-9
@@ -8,7 +8,7 @@ Item {
|
||||
id: root
|
||||
|
||||
property var launcher: null
|
||||
property string name: I18n.tr("plugins.applications")
|
||||
property string name: I18n.tr("launcher.providers.applications")
|
||||
property bool handleSearch: true
|
||||
property var entries: []
|
||||
|
||||
@@ -332,7 +332,7 @@ Item {
|
||||
|
||||
function loadApplications() {
|
||||
if (typeof DesktopEntries === 'undefined') {
|
||||
Logger.w("ApplicationsPlugin", "DesktopEntries service not available");
|
||||
Logger.w("ApplicationsProvider", "DesktopEntries service not available");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -352,7 +352,7 @@ Item {
|
||||
|
||||
// If exec is different, it's a legitimate different entry - keep it
|
||||
if (previousExec !== execCmd) {
|
||||
Logger.d("ApplicationsPlugin", `Keeping variant of ${appId}: ${execCmd} (differs from ${previousExec})`);
|
||||
Logger.d("ApplicationsProvider", `Keeping variant of ${appId}: ${execCmd} (differs from ${previousExec})`);
|
||||
// Add with modified ID to make it unique
|
||||
app.id = `${appId}_${execCmd}`;
|
||||
seen.set(app.id, execCmd);
|
||||
@@ -360,7 +360,7 @@ Item {
|
||||
}
|
||||
|
||||
// Same appId AND same exec = true duplicate, skip it
|
||||
Logger.d("ApplicationsPlugin", `Skipping duplicate: ${appId}`);
|
||||
Logger.d("ApplicationsProvider", `Skipping duplicate: ${appId}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -371,7 +371,7 @@ Item {
|
||||
return app;
|
||||
});
|
||||
|
||||
Logger.d("ApplicationsPlugin", `Loaded ${entries.length} applications`);
|
||||
Logger.d("ApplicationsProvider", `Loaded ${entries.length} applications`);
|
||||
updateAvailableCategories();
|
||||
}
|
||||
|
||||
@@ -542,7 +542,7 @@ Item {
|
||||
|
||||
// Defer execution to next event loop iteration to ensure panel is fully closed
|
||||
Qt.callLater(() => {
|
||||
Logger.d("ApplicationsPlugin", `Launching: ${app.name}`);
|
||||
Logger.d("ApplicationsProvider", `Launching: ${app.name}`);
|
||||
// Record usage and persist asynchronously
|
||||
if (Settings.data.appLauncher.sortByMostUsed) {
|
||||
recordUsage(app);
|
||||
@@ -561,7 +561,7 @@ Item {
|
||||
Quickshell.execDetached(command);
|
||||
}
|
||||
} else if (Settings.data.appLauncher.useApp2Unit && app.id) {
|
||||
Logger.d("ApplicationsPlugin", `Using app2unit for: ${app.id}`);
|
||||
Logger.d("ApplicationsProvider", `Using app2unit for: ${app.id}`);
|
||||
if (app.runInTerminal)
|
||||
Quickshell.execDetached(["app2unit", "--", app.id + ".desktop"]);
|
||||
else
|
||||
@@ -570,7 +570,7 @@ Item {
|
||||
// Fallback logic when app2unit is not used
|
||||
if (app.runInTerminal) {
|
||||
// If app.execute() fails for terminal apps, we handle it manually.
|
||||
Logger.d("ApplicationsPlugin", "Executing terminal app manually: " + app.name);
|
||||
Logger.d("ApplicationsProvider", "Executing terminal app manually: " + app.name);
|
||||
const terminal = Settings.data.appLauncher.terminalCommand.split(" ");
|
||||
const command = terminal.concat(app.command);
|
||||
Quickshell.execDetached(command);
|
||||
@@ -579,7 +579,7 @@ Item {
|
||||
} else if (app.execute) {
|
||||
app.execute();
|
||||
} else {
|
||||
Logger.w("ApplicationsPlugin", `Could not launch: ${app.name}. No valid launch method.`);
|
||||
Logger.w("ApplicationsProvider", `Could not launch: ${app.name}. No valid launch method.`);
|
||||
}
|
||||
}
|
||||
});
|
||||
+5
-5
@@ -6,7 +6,7 @@ import qs.Commons
|
||||
// TODO: Remove this plugin in 2-3 bussiness days
|
||||
Item {
|
||||
property var launcher: null
|
||||
property string name: I18n.tr("plugins.calculator")
|
||||
property string name: I18n.tr("launcher.providers.calculator")
|
||||
property string iconMode: Settings.data.appLauncher.iconMode
|
||||
|
||||
function handleCommand(query) {
|
||||
@@ -18,7 +18,7 @@ Item {
|
||||
return [
|
||||
{
|
||||
"name": ">calc",
|
||||
"description": I18n.tr("plugins.calculator-deprecated"),
|
||||
"description": I18n.tr("launcher.providers.calculator-deprecated"),
|
||||
"icon": "alert-triangle",
|
||||
"isTablerIcon": true,
|
||||
"isImage": false,
|
||||
@@ -43,8 +43,8 @@ Item {
|
||||
if (!expression) {
|
||||
return [
|
||||
{
|
||||
"name": I18n.tr("plugins.calculator-name"),
|
||||
"description": I18n.tr("plugins.calculator-deprecated"),
|
||||
"name": I18n.tr("launcher.providers.calculator-name"),
|
||||
"description": I18n.tr("launcher.providers.calculator-deprecated"),
|
||||
"icon": "alert-triangle",
|
||||
"isTablerIcon": true,
|
||||
"isImage": false,
|
||||
@@ -72,7 +72,7 @@ Item {
|
||||
} catch (error) {
|
||||
return [
|
||||
{
|
||||
"name": I18n.tr("plugins.calculator-error"),
|
||||
"name": I18n.tr("launcher.providers.calculator-error"),
|
||||
"description": error.message || "Invalid expression",
|
||||
"icon": iconMode === "tabler" ? "circle-x" : "dialog-error",
|
||||
"isTablerIcon": true,
|
||||
+16
-16
@@ -6,12 +6,12 @@ import qs.Services.Keyboard
|
||||
Item {
|
||||
id: root
|
||||
|
||||
// Plugin metadata
|
||||
property string name: I18n.tr("plugins.clipboard")
|
||||
// Provider metadata
|
||||
property string name: I18n.tr("launcher.providers.clipboard")
|
||||
property var launcher: null
|
||||
property string iconMode: Settings.data.appLauncher.iconMode
|
||||
|
||||
// Plugin capabilities
|
||||
// Provider capabilities
|
||||
property bool handleSearch: false // Don't handle regular search
|
||||
|
||||
// Internal state
|
||||
@@ -39,9 +39,9 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize plugin
|
||||
// Initialize provider
|
||||
function init() {
|
||||
Logger.i("ClipboardPlugin", "Initialized");
|
||||
Logger.i("ClipboardProvider", "Initialized");
|
||||
// Pre-load clipboard data if service is active
|
||||
if (ClipboardService.active) {
|
||||
ClipboardService.list(100);
|
||||
@@ -60,7 +60,7 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
// Check if this plugin handles the command
|
||||
// Check if this provider handles the command
|
||||
function handleCommand(searchText) {
|
||||
return searchText.startsWith(">clip");
|
||||
}
|
||||
@@ -70,7 +70,7 @@ Item {
|
||||
return [
|
||||
{
|
||||
"name": ">clip",
|
||||
"description": I18n.tr("plugins.clipboard-search-description"),
|
||||
"description": I18n.tr("launcher.providers.clipboard-search-description"),
|
||||
"icon": iconMode === "tabler" ? "clipboard" : "text-x-generic",
|
||||
"isTablerIcon": true,
|
||||
"isImage": false,
|
||||
@@ -80,7 +80,7 @@ Item {
|
||||
},
|
||||
{
|
||||
"name": ">clip clear",
|
||||
"description": I18n.tr("plugins.clipboard-clear-description"),
|
||||
"description": I18n.tr("launcher.providers.clipboard-clear-description"),
|
||||
"icon": iconMode === "tabler" ? "trash" : "user-trash",
|
||||
"isTablerIcon": true,
|
||||
"isImage": false,
|
||||
@@ -106,8 +106,8 @@ Item {
|
||||
if (!ClipboardService.active) {
|
||||
return [
|
||||
{
|
||||
"name": I18n.tr("plugins.clipboard-history-disabled"),
|
||||
"description": I18n.tr("plugins.clipboard-history-disabled-description"),
|
||||
"name": I18n.tr("launcher.providers.clipboard-history-disabled"),
|
||||
"description": I18n.tr("launcher.providers.clipboard-history-disabled-description"),
|
||||
"icon": iconMode === "tabler" ? "refresh" : "view-refresh",
|
||||
"isTablerIcon": true,
|
||||
"isImage": false,
|
||||
@@ -120,8 +120,8 @@ Item {
|
||||
if (query === "clear") {
|
||||
return [
|
||||
{
|
||||
"name": I18n.tr("plugins.clipboard-clear-history"),
|
||||
"description": I18n.tr("plugins.clipboard-clear-description-full"),
|
||||
"name": I18n.tr("launcher.providers.clipboard-clear-history"),
|
||||
"description": I18n.tr("launcher.providers.clipboard-clear-description-full"),
|
||||
"icon": iconMode === "tabler" ? "trash" : "delete_sweep",
|
||||
"isTablerIcon": true,
|
||||
"isImage": false,
|
||||
@@ -137,8 +137,8 @@ Item {
|
||||
if (ClipboardService.loading || isWaitingForData) {
|
||||
return [
|
||||
{
|
||||
"name": I18n.tr("plugins.clipboard-loading"),
|
||||
"description": I18n.tr("plugins.clipboard-loading-description"),
|
||||
"name": I18n.tr("launcher.providers.clipboard-loading"),
|
||||
"description": I18n.tr("launcher.providers.clipboard-loading-description"),
|
||||
"icon": iconMode === "tabler" ? "refresh" : "view-refresh",
|
||||
"isTablerIcon": true,
|
||||
"isImage": false,
|
||||
@@ -156,8 +156,8 @@ Item {
|
||||
ClipboardService.list(100);
|
||||
return [
|
||||
{
|
||||
"name": I18n.tr("plugins.clipboard-loading"),
|
||||
"description": I18n.tr("plugins.clipboard-loading-description"),
|
||||
"name": I18n.tr("launcher.providers.clipboard-loading"),
|
||||
"description": I18n.tr("launcher.providers.clipboard-loading-description"),
|
||||
"icon": iconMode === "tabler" ? "refresh" : "view-refresh",
|
||||
"isTablerIcon": true,
|
||||
"isImage": false,
|
||||
+4
-4
@@ -4,7 +4,7 @@ import qs.Commons
|
||||
|
||||
Item {
|
||||
property var launcher: null
|
||||
property string name: I18n.tr("plugins.command")
|
||||
property string name: I18n.tr("launcher.providers.command")
|
||||
property string iconMode: Settings.data.appLauncher.iconMode
|
||||
|
||||
function handleCommand(query) {
|
||||
@@ -15,7 +15,7 @@ Item {
|
||||
return [
|
||||
{
|
||||
"name": ">cmd",
|
||||
"description": I18n.tr("plugins.command-description"),
|
||||
"description": I18n.tr("launcher.providers.command-description"),
|
||||
"icon": iconMode === "tabler" ? "terminal" : "utilities-terminal",
|
||||
"isTablerIcon": true,
|
||||
"isImage": false,
|
||||
@@ -33,8 +33,8 @@ Item {
|
||||
let expression = query.substring(4).trim();
|
||||
return [
|
||||
{
|
||||
"name": I18n.tr("plugins.command-name"),
|
||||
"description": I18n.tr("plugins.command-description"),
|
||||
"name": I18n.tr("launcher.providers.command-name"),
|
||||
"description": I18n.tr("launcher.providers.command-description"),
|
||||
"icon": iconMode === "tabler" ? "terminal" : "utilities-terminal",
|
||||
"isTablerIcon": true,
|
||||
"isImage": false,
|
||||
+8
-8
@@ -6,8 +6,8 @@ import qs.Services.Keyboard
|
||||
Item {
|
||||
id: root
|
||||
|
||||
// Plugin metadata
|
||||
property string name: I18n.tr("plugins.emoji")
|
||||
// Provider metadata
|
||||
property string name: I18n.tr("launcher.providers.emoji")
|
||||
property var launcher: null
|
||||
property string iconMode: Settings.data.appLauncher.iconMode
|
||||
property bool handleSearch: false
|
||||
@@ -56,9 +56,9 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize plugin
|
||||
// Initialize provider
|
||||
function init() {
|
||||
Logger.i("EmojiPlugin", "Initialized");
|
||||
Logger.d("EmojiProvider", "Initialized");
|
||||
}
|
||||
|
||||
function selectCategory(category) {
|
||||
@@ -73,7 +73,7 @@ Item {
|
||||
selectedCategory = "recent";
|
||||
}
|
||||
|
||||
// Check if this plugin handles the command
|
||||
// Check if this provider handles the command
|
||||
function handleCommand(searchText) {
|
||||
return searchText.startsWith(">emoji");
|
||||
}
|
||||
@@ -83,7 +83,7 @@ Item {
|
||||
return [
|
||||
{
|
||||
"name": ">emoji",
|
||||
"description": I18n.tr("plugins.emoji-search-description"),
|
||||
"description": I18n.tr("launcher.providers.emoji-search-description"),
|
||||
"icon": iconMode === "tabler" ? "mood-smile" : "face-smile",
|
||||
"isTablerIcon": true,
|
||||
"isImage": false,
|
||||
@@ -103,8 +103,8 @@ Item {
|
||||
if (!EmojiService.loaded) {
|
||||
return [
|
||||
{
|
||||
"name": I18n.tr("plugins.emoji-loading"),
|
||||
"description": I18n.tr("plugins.emoji-loading-description"),
|
||||
"name": I18n.tr("launcher.providers.emoji-loading"),
|
||||
"description": I18n.tr("launcher.providers.emoji-loading-description"),
|
||||
"icon": iconMode === "tabler" ? "refresh" : "view-refresh",
|
||||
"isTablerIcon": true,
|
||||
"isImage": false,
|
||||
Reference in New Issue
Block a user