summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-01-20 15:18:43 +1100
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-01-20 15:18:43 +1100
commit17223a00fcd3f8b505c7e9cf52c814cc301f5b3b (patch)
treed8b1d2c5b1d69c97879b4356c443429bbdba282b
parentsession screen (diff)
downloadcaelestia-shell-17223a00fcd3f8b505c7e9cf52c814cc301f5b3b.tar.gz
caelestia-shell-17223a00fcd3f8b505c7e9cf52c814cc301f5b3b.tar.bz2
caelestia-shell-17223a00fcd3f8b505c7e9cf52c814cc301f5b3b.zip
launcher: context menu for items
-rw-r--r--src/modules/launcher.tsx82
1 files changed, 68 insertions, 14 deletions
diff --git a/src/modules/launcher.tsx b/src/modules/launcher.tsx
index 67d0ee9..0e72224 100644
--- a/src/modules/launcher.tsx
+++ b/src/modules/launcher.tsx
@@ -8,7 +8,7 @@ import { Apps } from "../services/apps";
import Math, { type HistoryItem } from "../services/math";
import { getAppCategoryIcon } from "../utils/icons";
import { launch } from "../utils/system";
-import { setupCustomTooltip } from "../utils/widgets";
+import { MenuItem, setupCustomTooltip } from "../utils/widgets";
import PopupWindow from "../widgets/popupwindow";
type Mode = "apps" | "files" | "math";
@@ -73,18 +73,40 @@ const PinnedApp = (names: string[]) => {
}
}
- if (!app) console.error(`Launcher - Unable to find app for "${names.join(", ")}"`);
+ if (!app) {
+ console.error(`Launcher - Unable to find app for "${names.join(", ")}"`);
+ return null;
+ }
+
+ const menu = new Gtk.Menu();
+ menu.append(new MenuItem({ label: "Launch", onActivate: () => launchAndClose(widget, astalApp!) }));
+
+ if (app.list_actions().length > 0) menu.append(new Gtk.SeparatorMenuItem({ visible: true }));
+ app.list_actions().forEach(action => {
+ menu.append(
+ new MenuItem({
+ label: app.get_action_name(action),
+ onActivate: () => {
+ close(widget); // Pass result cause menu is its own toplevel
+ app.launch_action(action, null);
+ },
+ })
+ );
+ });
- return app ? (
+ const widget = (
<button
className="pinned-app result"
cursor="pointer"
onClicked={self => launchAndClose(self, astalApp!)}
+ onClick={(_, event) => event.button === Astal.MouseButton.SECONDARY && menu.popup_at_pointer(null)}
setup={self => setupCustomTooltip(self, app.get_display_name())}
+ onDestroy={() => menu.destroy()}
>
<icon gicon={app.get_icon()!} />
</button>
- ) : null;
+ );
+ return widget;
};
const PinnedApps = () => <box homogeneous>{config.pins.map(PinnedApp)}</box>;
@@ -112,14 +134,24 @@ const Result = ({
label,
sublabel,
onClicked,
+ onSecondaryClick,
+ onDestroy,
}: {
icon?: string;
materialIcon?: string;
label: string;
sublabel?: string;
onClicked: (self: Widget.Button) => void;
+ onSecondaryClick?: (self: Widget.Button) => void;
+ onDestroy?: () => void;
}) => (
- <button className="result" cursor="pointer" onClicked={onClicked}>
+ <button
+ className="result"
+ cursor="pointer"
+ onClicked={onClicked}
+ onClick={(self, event) => event.button === Astal.MouseButton.SECONDARY && onSecondaryClick?.(self)}
+ onDestroy={onDestroy}
+ >
<box>
{icon && Astal.Icon.lookup_icon(icon) ? (
<icon valign={Gtk.Align.START} className="icon" icon={icon} />
@@ -158,15 +190,37 @@ const SubcommandResult = ({
/>
);
-const AppResult = ({ app }: { app: AstalApps.Application }) => (
- <Result
- icon={app.iconName}
- materialIcon={getAppCategoryIcon(app)}
- label={app.name}
- sublabel={app.description}
- onClicked={self => launchAndClose(self, app)}
- />
-);
+const AppResult = ({ app }: { app: AstalApps.Application }) => {
+ const menu = new Gtk.Menu();
+ menu.append(new MenuItem({ label: "Launch", onActivate: () => launchAndClose(result, app) }));
+
+ const appInfo = app.app as Gio.DesktopAppInfo;
+ if (appInfo.list_actions().length > 0) menu.append(new Gtk.SeparatorMenuItem({ visible: true }));
+ appInfo.list_actions().forEach(action => {
+ menu.append(
+ new MenuItem({
+ label: appInfo.get_action_name(action),
+ onActivate: () => {
+ close(result); // Pass result cause menu is its own toplevel
+ appInfo.launch_action(action, null);
+ },
+ })
+ );
+ });
+
+ const result = (
+ <Result
+ icon={app.iconName}
+ materialIcon={getAppCategoryIcon(app)}
+ label={app.name}
+ sublabel={app.description}
+ onClicked={self => launchAndClose(self, app)}
+ onSecondaryClick={() => menu.popup_at_pointer(null)}
+ onDestroy={() => menu.destroy()}
+ />
+ );
+ return result;
+};
const MathResult = ({ math, isHistory, entry }: { math: HistoryItem; isHistory?: boolean; entry: Widget.Entry }) => (
<Result