Aylur / ags

A customizable and extensible shell
GNU General Public License v3.0
1.73k stars 94 forks source link

[Feature] Allow a way to get the position of button clicked + assign those coords to a window. #452

Closed Jas-SinghFSU closed 1 week ago

Jas-SinghFSU commented 2 weeks ago

Currently, in order to spawn a window where a button is clicked - in a scenario where we want a custom popover(not built-in) - we have to first fetch a cursor position via external methods (hyprctl cursorpos) and then do monitor resolution calculations to set margins to mimic location.

It would be nice to simply get the location of the Widget.Button that was clicked so we can assign a window right under that button. And this would require us to have a way of passing X,Y coordinates to a Widget.Window.

Jas-SinghFSU commented 2 weeks ago

There is a Gtk.MenuButton that can spawn a menu or popover but both of those elements are extremely limiting and I would like to make my own "popover" when a button is clicked. Essentially it's just a Widget.Window(+children) spawning under the buttons location.

kotontrion commented 2 weeks ago

you can already do this:

Widget.Button({
    on_primary_click_release: (self, event) => {
        print(event.get_coords()) //coordinates of click relative to button
        print(event.get_root_coords()) //coordinates of click relative to window
        const alloc = self.get_allocation()
        print(alloc.x, alloc.y, alloc.width, alloc.height) //position of button relative to parent
        const [_, x, y] = self.translate_coordinates(self.get_toplevel(), 0, 0);
        print(x, y) //position of button relative to window
    },
})
Jas-SinghFSU commented 2 weeks ago

Oh wow, that's neat. I was trying to find the method to send these coordinates to a Widget.Window. That is the last part because I'm handling that with margins now. Do you know what method that is, to pass the coordinates to position a window?

kotontrion commented 2 weeks ago

In Wayland there is no way to position a window yourself. For regular windows you have to use compositor commands to move them( eg something like hyprctl windowmove windowName x y (idk, didn't look the command up)). For layer shell windows(Widget.Window) the only way is to use window margins. Here is an idea I didn't test, but might give you an idea:

function openWindowAtPosition(name, x, y){
  const window = App.getWindow(name)
  //maybe calculate better x/y coords to make sure the window does not clip out of the monitor.
  window.marginLeft = x
  window.marginTop = y
  App.openWindow(name)
}