88 lines
3.0 KiB
TypeScript

import { Variable } from "astal";
import { App, Astal, Gdk, Gtk, hook } from "astal/gtk4";
import AstalApps from "gi://AstalApps";
import AppList from "./modules/Apps";
const prefixes = ['='];
function hide() {
App.get_window("launcher")!.hide();
}
const Launcher = () => {
const apps = new AstalApps.Apps();
const width = Variable(1000);
const height = Variable(1000);
const text = Variable("");
const visible = Variable(false);
const onEnter = () => {
// TODO handle custom stuff
apps.fuzzy_query(text.get())?.[0].launch();
hide();
};
return <window
name="launcher"
visible={visible()}
anchor={Astal.WindowAnchor.TOP | Astal.WindowAnchor.BOTTOM}
exclusivity={Astal.Exclusivity.EXCLUSIVE}
keymode={Astal.Keymode.ON_DEMAND}
application={App}
onShow={(self) => {
width.set(self.get_current_monitor().geometry.width);
height.set(self.get_current_monitor().geometry.height);
}}
onKeyPressed={(self, keyval) => {
if (keyval === Gdk.KEY_Escape) self.hide();
}}
child={
<box
vertical
cssClasses={["app-launcher-wrapper"]}
widthRequest={width()}
heightRequest={height()}
valign={Gtk.Align.CENTER}
>
<button onClicked={hide} visible={false} />
<box
vertical
cssClasses={["app-launcher"]}
valign={Gtk.Align.CENTER}
halign={Gtk.Align.CENTER}
widthRequest={500}
>
<button onClicked={hide} visible={false}></button>
<box cssClasses={["search"]}>
<image iconName={"system-search-symbolic"}></image>
<entry
placeholderText={"Search..."}
text={text.get()}
setup={self => {
hook(self, App, 'window-toggled', (_, win) => {
if (win.name == 'launcher') {
self.set_text('');
self.grab_focus();
}
})
}}
onNotifyText={self => text.set(self.text)}
primaryIconSensitive
onActivate={onEnter}
hexpand></entry>
</box>
<AppList
hide={hide}
query={text}
visible={text(v => {
return !prefixes.includes(v.slice(0, 1));
})}
></AppList>
</box>
</box>
}
>
</window>
}
export default Launcher;