Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Once clicked, button triggers from anywhere on the widget #1022

Open
3 tasks done
altacountbabi opened this issue Feb 3, 2024 · 5 comments
Open
3 tasks done
Labels
bug Something isn't working

Comments

@altacountbabi
Copy link

altacountbabi commented Feb 3, 2024

Checklist before submitting an issue

  • I have searched through the existing closed and open issues for eww and made sure this is not a duplicate
  • I have specifically verified that this bug is not a common user error
  • I am providing as much relevant information as I am able to in this bug report (Minimal config to reproduce the issue for example, if applicable)

Description of the bug

Whenever I click on a button it opens fine but then I can click anywhere on the window and it will activate the button. This only seems to happen when wlogout with the layer shell protocol is the button action. I have tested with notify-send and it seems to work fine

Reproducing the issue

eww.yuck

(
    defwindow bar
    :monitor 0
    :geometry (
        geometry
        :x "0%"
        :y "0%"
        :width "100%"
        :height "40px"
        :anchor "top center"
    )
    :exclusive true
    (
        centerbox
        :orientation "h"
        "workspaces"
        "00:00"
        (
            box
            :class "sidestuff"
            :orientation "h"
            :space-evenly false
            :halign "end"
            (
                button
                :class ""
                :timeout "9999h"
                :onclick "wlogout -p layer-shell"
                ""
            )
        )
    )
)

style.scss

* {
    all: unset;
    font-weight: 600;
}

.bar {
    background-color: #000000;
    padding: 10px;
}

.sidestuff {
    margin-right: 10px;
}

Expected behaviour

The button only activating when clicked on it

Additional context

reproducing this bug requires wlogout installed
using eww version 0.4.0 65d622c

bug.mp4
@altacountbabi altacountbabi added the bug Something isn't working label Feb 3, 2024
@JohnOberhauser
Copy link

I'm having a similar issue. When my bar gets into this state, I no longer see hover highlighting on my other buttons, and it seems like only the one button can be interacted with.

@Rayzeq
Copy link
Contributor

Rayzeq commented Feb 10, 2024

It's just a theory, but here's what I think is happening:

  1. When a GTK button detects a button press event, it grabs the pointer. This behavior is detailed in the GDK documentation here:
    Note that if the event mask of a GdkWindow has selected both button press and button release events, or touch begin and touch end, then a press event will cause an automatic grab until the button is released, equivalent to a grab on the window with owner_events set to TRUE. This is done because most applications expect to receive paired press and release events.
  2. Wayland (or only Hyprland, I don't know) has some weird behavior with grabs, which can lead to them being disregarded. However, GTK retains its own grab mechanism, which redirects all events received by the main window (your bar) to the button.
  3. wlogout opens before the button release event is received by your bar, and intercepts it. Because it hasn't received a button release event, your power button won't ungrab the pointer.
  4. This means that at this stage, all events received by your bar are sent to your power button.

Whether my theory is correct or not, I've done some tests and I've noticed that this bug indeed only triggers if you release your mouse button after wlogout has opened. So to avoid triggering the issue, you need to release your mouse button before wlogout opens, either by adding a delay before wlogout opens, or by clicking faster.

Note that releasing your mouse button before wlogout opens will also fix your bar if it's in this bugged state.

@Rayzeq
Copy link
Contributor

Rayzeq commented Feb 10, 2024

A way to solve the issue properly would be to replace your button with:

(
    eventbox
    :class ""
    :timeout "9999h"
    :onbuttonrelease "wlogout -p layer-shell"
    ""
)

Unfortunately, eww currently doesn't have a onbuttonrelease event.

You may also note that you don't need to put a really high timeout, you can do:

(
    button
    :class ""
    :onclick "wlogout -p layer-shell &"
    ""
)

@j0ng4b
Copy link

j0ng4b commented Feb 24, 2024

It's just a theory, but here's what I think is happening:

1. When a GTK button detects a button press event, it grabs the pointer. This behavior is detailed in the GDK documentation [here](https://docs.gtk.org/gdk3/method.Seat.grab.html):
   `Note that if the event mask of a GdkWindow has selected both button press and button release events, or touch begin and touch end, then a press event will cause an automatic grab until the button is released, equivalent to a grab on the window with owner_events set to TRUE. This is done because most applications expect to receive paired press and release events.`

2. Wayland (or only Hyprland, I don't know) has some weird behavior with grabs, which can lead to them being disregarded. However, GTK retains its own grab mechanism, which redirects all events received by the main window (your bar) to the button.

3. `wlogout` opens before the button release event is received by your bar, and intercepts it. Because it hasn't received a button release event, your power button won't ungrab the pointer.

4. This means that at this stage, all events received by your bar are sent to your power button.

Whether my theory is correct or not, I've done some tests and I've noticed that this bug indeed only triggers if you release your mouse button after wlogout has opened. So to avoid triggering the issue, you need to release your mouse button before wlogout opens, either by adding a delay before wlogout opens, or by clicking faster.

Note that releasing your mouse button before wlogout opens will also fix your bar if it's in this bugged state.

This seems to be true, the same happens with rofi wayland fork that uses layer shell protocol, when I added a sleep before open rofi everything work fine but without the sleep when click on any place that is an eww widget the rofi is (re)opened independent of the widget onclick event action.

I'm using Hyprland too.

@MarvinRuesenberg
Copy link

MarvinRuesenberg commented Apr 18, 2024

I am/was experiencing the same behavior with eventboxes and buttons.

Since the issue seems to be related to the connect_button_press event, i got a very dirty workaround by using the connect_button_release_event instead.

As i am not really familiar with the whole ecosystem of gtk, signal handling, nor rust really - I dont know whether this is just a lucky guess or will break other stuff down the road. I am assuming however that the button press event is not released by default and therefore tied to the widget until the pointer/focus gets taken by a different one. Maybe there is a way to release it inside of the function?

I changed the lines for the eventboxes to the following in: eww/crates/eww/src/widgets/widget_definitions.rs - line 852++:

gtk_widget.add_events(gdk::EventMask::BUTTON_RELEASE_MASK);
            connect_signal_handler!(gtk_widget, gtk_widget.connect_button_release_event(move |_, evt| {
                match evt.button() {
                    1 => run_command(timeout, &onclick, &[] as &[&str]),
                    2 => run_command(timeout, &onmiddleclick, &[] as &[&str]),
                    3 => run_command(timeout, &onrightclick, &[] as &[&str]),
                    _ => {},
                }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants