88 lines
3.0 KiB
TypeScript
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;
|