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;
 |