launcher: context menu for items
This commit is contained in:
parent
611f2c766f
commit
17223a00fc
1 changed files with 68 additions and 14 deletions
|
|
@ -8,7 +8,7 @@ import { Apps } from "../services/apps";
|
||||||
import Math, { type HistoryItem } from "../services/math";
|
import Math, { type HistoryItem } from "../services/math";
|
||||||
import { getAppCategoryIcon } from "../utils/icons";
|
import { getAppCategoryIcon } from "../utils/icons";
|
||||||
import { launch } from "../utils/system";
|
import { launch } from "../utils/system";
|
||||||
import { setupCustomTooltip } from "../utils/widgets";
|
import { MenuItem, setupCustomTooltip } from "../utils/widgets";
|
||||||
import PopupWindow from "../widgets/popupwindow";
|
import PopupWindow from "../widgets/popupwindow";
|
||||||
|
|
||||||
type Mode = "apps" | "files" | "math";
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
return app ? (
|
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);
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const widget = (
|
||||||
<button
|
<button
|
||||||
className="pinned-app result"
|
className="pinned-app result"
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
onClicked={self => launchAndClose(self, astalApp!)}
|
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())}
|
setup={self => setupCustomTooltip(self, app.get_display_name())}
|
||||||
|
onDestroy={() => menu.destroy()}
|
||||||
>
|
>
|
||||||
<icon gicon={app.get_icon()!} />
|
<icon gicon={app.get_icon()!} />
|
||||||
</button>
|
</button>
|
||||||
) : null;
|
);
|
||||||
|
return widget;
|
||||||
};
|
};
|
||||||
|
|
||||||
const PinnedApps = () => <box homogeneous>{config.pins.map(PinnedApp)}</box>;
|
const PinnedApps = () => <box homogeneous>{config.pins.map(PinnedApp)}</box>;
|
||||||
|
|
@ -112,14 +134,24 @@ const Result = ({
|
||||||
label,
|
label,
|
||||||
sublabel,
|
sublabel,
|
||||||
onClicked,
|
onClicked,
|
||||||
|
onSecondaryClick,
|
||||||
|
onDestroy,
|
||||||
}: {
|
}: {
|
||||||
icon?: string;
|
icon?: string;
|
||||||
materialIcon?: string;
|
materialIcon?: string;
|
||||||
label: string;
|
label: string;
|
||||||
sublabel?: string;
|
sublabel?: string;
|
||||||
onClicked: (self: Widget.Button) => void;
|
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>
|
<box>
|
||||||
{icon && Astal.Icon.lookup_icon(icon) ? (
|
{icon && Astal.Icon.lookup_icon(icon) ? (
|
||||||
<icon valign={Gtk.Align.START} className="icon" icon={icon} />
|
<icon valign={Gtk.Align.START} className="icon" icon={icon} />
|
||||||
|
|
@ -158,15 +190,37 @@ const SubcommandResult = ({
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
const AppResult = ({ app }: { app: AstalApps.Application }) => (
|
const AppResult = ({ app }: { app: AstalApps.Application }) => {
|
||||||
<Result
|
const menu = new Gtk.Menu();
|
||||||
icon={app.iconName}
|
menu.append(new MenuItem({ label: "Launch", onActivate: () => launchAndClose(result, app) }));
|
||||||
materialIcon={getAppCategoryIcon(app)}
|
|
||||||
label={app.name}
|
const appInfo = app.app as Gio.DesktopAppInfo;
|
||||||
sublabel={app.description}
|
if (appInfo.list_actions().length > 0) menu.append(new Gtk.SeparatorMenuItem({ visible: true }));
|
||||||
onClicked={self => launchAndClose(self, app)}
|
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 }) => (
|
const MathResult = ({ math, isHistory, entry }: { math: HistoryItem; isHistory?: boolean; entry: Widget.Entry }) => (
|
||||||
<Result
|
<Result
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue