💥 fix(runner): wrong scrolling positions, focus escaping to the listbox

This commit is contained in:
retrozinndev
2025-08-10 00:35:17 -03:00
parent fd58ebd5b3
commit 052854a407
+19 -19
View File
@@ -225,14 +225,12 @@ function selectNextItem(listbox: Gtk.ListBox) {
return; return;
const viewport = listbox.parent as Gtk.Viewport; const viewport = listbox.parent as Gtk.Viewport;
const vadjustment = viewport.vadjustment; const vadjustment = (viewport.parent as Gtk.ScrolledWindow).get_vadjustment();
const [, , nextRowY] = nextRow.translate_coordinates(viewport, const nextRowVAllocation = (nextRow.get_allocation().y + nextRow.get_allocation().height);
nextRow.get_allocation().x, nextRow.get_allocation().y);
listbox.select_row(nextRow as Gtk.ListBoxRow); listbox.select_row(nextRow as Gtk.ListBoxRow);
if(vadjustment.value < nextRowY) if(nextRowVAllocation > viewport.get_allocation().height)
vadjustment.set_value(nextRowY - vadjustment.value); vadjustment.set_value(nextRow.get_allocation().y - viewport.get_allocation().height + nextRow.get_allocation().height);}
}
export function openRunner(props: RunnerProps, placeholders?: Array<Result>): Astal.Window { export function openRunner(props: RunnerProps, placeholders?: Array<Result>): Astal.Window {
props.width ??= 780; props.width ??= 780;
@@ -245,16 +243,16 @@ export function openRunner(props: RunnerProps, placeholders?: Array<Result>): As
<PopupWindow namespace={"runner"} monitor={mon} widthRequest={props.width} <PopupWindow namespace={"runner"} monitor={mon} widthRequest={props.width}
heightRequest={props.height} exclusivity={Astal.Exclusivity.IGNORE} halign={Gtk.Align.CENTER} heightRequest={props.height} exclusivity={Astal.Exclusivity.IGNORE} halign={Gtk.Align.CENTER}
marginTop={(AstalHyprland.get_default().get_monitor(mon)?.height / 2) - (props.height! / 2)} marginTop={(AstalHyprland.get_default().get_monitor(mon)?.height / 2) - (props.height! / 2)}
valign={Gtk.Align.START} $={() => { valign={Gtk.Align.START} hexpand orientation={Gtk.Orientation.VERTICAL}
$={() => {
plugins.forEach(plugin => plugins.forEach(plugin =>
plugin.init?.()); plugin.init?.());
props.initialText && props.initialText &&
Runner.setEntryText(props.initialText); Runner.setEntryText(props.initialText);
}} actionKeyPressed={(self, keyval) => { }} actionKeyPressed={(self, keyval) => {
const listbox = ((getPopupWindowContainer(self).get_first_child()! const listbox = ((getPopupWindowContainer(self).get_last_child() as Gtk.ScrolledWindow)
.get_last_child()! as Gtk.ScrolledWindow).get_child()! as Gtk.Viewport) .get_child() as Gtk.Viewport).get_child() as Gtk.ListBox;
.get_child()! as Gtk.ListBox;
switch(keyval) { switch(keyval) {
case Gdk.KEY_F5: case Gdk.KEY_F5:
@@ -279,8 +277,10 @@ export function openRunner(props: RunnerProps, placeholders?: Array<Result>): As
return; return;
} }
!gtkEntry?.hasFocus && if(!gtkEntry?.hasFocus) {
gtkEntry?.grab_focus(); gtkEntry?.grab_focus();
listbox.grab_focus();
}
}} actionClosed={() => { }} actionClosed={() => {
[...plugins.values()].forEach(plugin => plugin?.onClose?.()); [...plugins.values()].forEach(plugin => plugin?.onClose?.());
root.dispose(); root.dispose();
@@ -288,30 +288,31 @@ export function openRunner(props: RunnerProps, placeholders?: Array<Result>): As
instance = null; instance = null;
gtkEntry = null; gtkEntry = null;
}}> }}>
<Gtk.Box class={`runner main`} orientation={Gtk.Orientation.VERTICAL} hexpand
valign={Gtk.Align.START}>
<Gtk.SearchEntry class={"search"} placeholderText={props.entryPlaceHolder ?? ""} <Gtk.SearchEntry class={"search"} placeholderText={props.entryPlaceHolder ?? ""}
$={(self) => gtkEntry = self} searchDelay={0} onSearchChanged={(self) => { $={(self) => gtkEntry = self} searchDelay={0} onSearchChanged={(self) => {
const listbox = self.get_next_sibling()?.get_first_child()?.get_first_child() as Gtk.ListBox; const listbox = ((self.get_next_sibling()! as Gtk.ScrolledWindow)
.get_child() as Gtk.Viewport).get_child() as Gtk.ListBox;
updateResultsList(listbox, self.text, placeholders); updateResultsList(listbox, self.text, placeholders);
listbox.get_row_at_index(0) && listbox.get_row_at_index(0) &&
listbox.select_row(listbox.get_row_at_index(0)); listbox.select_row(listbox.get_row_at_index(0));
}} onActivate={(self) => { }} onActivate={(self) => {
const listbox = self.parent.get_last_child()?.get_first_child()?.get_first_child() as Gtk.ListBox; const listbox = ((self.get_next_sibling() as Gtk.ScrolledWindow)
.get_child() as Gtk.Viewport).get_child() as Gtk.ListBox;
const resultWidget = listbox.get_selected_row()?.get_child(); const resultWidget = listbox.get_selected_row()?.get_child();
if(resultWidget instanceof ResultWidget) { if(resultWidget instanceof ResultWidget && !clickTimeout) {
clickTimeout = timeout(250, () => clickTimeout = undefined);
resultWidget.actionClick(); resultWidget.actionClick();
resultWidget.closeOnClick && resultWidget.closeOnClick &&
Runner.close(); Runner.close();
} }
}} onStopSearch={() => Runner.close()} // close Runner on Escape }} onStopSearch={() => Runner.close()} // close Runner on Escape
/> />
<Gtk.ScrolledWindow class={"results-scrollable"} vscrollbarPolicy={Gtk.PolicyType.AUTOMATIC} <Gtk.ScrolledWindow class={"results-scrollable"} vscrollbarPolicy={Gtk.PolicyType.AUTOMATIC}
hscrollbarPolicy={Gtk.PolicyType.NEVER} hexpand vexpand propagateNaturalHeight visible={false} hscrollbarPolicy={Gtk.PolicyType.NEVER} hexpand vexpand propagateNaturalHeight visible={false}
maxContentHeight={props.height}> maxContentHeight={props.height} focusable={false}>
<Gtk.ListBox hexpand activateOnSingleClick selectionMode={Gtk.SelectionMode.SINGLE} <Gtk.ListBox hexpand activateOnSingleClick selectionMode={Gtk.SelectionMode.SINGLE}
onRowActivated={(_, row) => { onRowActivated={(_, row) => {
@@ -326,7 +327,6 @@ export function openRunner(props: RunnerProps, placeholders?: Array<Result>): As
}} }}
/> />
</Gtk.ScrolledWindow> </Gtk.ScrolledWindow>
</Gtk.Box>
</PopupWindow> as Astal.Window </PopupWindow> as Astal.Window
)(); )();