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

Xwayland apps on wayland #5101

Open
2 tasks done
Gurjaka opened this issue Nov 26, 2024 · 54 comments · Fixed by #5102
Open
2 tasks done

Xwayland apps on wayland #5101

Gurjaka opened this issue Nov 26, 2024 · 54 comments · Fixed by #5102

Comments

@Gurjaka
Copy link
Contributor

Gurjaka commented Nov 26, 2024

Issue description

image
First I discovered this issue when turning on Steam, later discovered that none Xwayland app works, even after running in terminal I get no output about error. This is all I got:

steam                                                                               
steam.sh[9848]: Running Steam on nixos 25.05 64-bit
steam.sh[9848]: STEAM_RUNTIME is enabled automatically
setup.sh[9896]: Steam runtime environment up-to-date!
steam.sh[9848]: Steam client's requirements are satisfied
CProcessEnvironmentManager is ready, 6 preallocated environment variables.
[2024-11-26 21:52:42] Startup - updater built Nov 12 2024 17:09:08
[2024-11-26 21:52:42] Startup - Steam Client launched with: '/home/gurami/.local/share/Steam/ubuntu12_32/steam' '-srt-logger-opened'
11/26 21:52:42 minidumps folder is set to /tmp/dumps
11/26 21:52:42 Init: Installing breakpad exception handler for appid(steam)/version(1731433018)/tid(9958)
src/steamexe/updateui_xwin.cpp (341) : Could not open connection to X
src/steamexe/updateui_xwin.cpp (341) : Could not open connection to X
11/26 21:52:42 Init: Installing breakpad exception handler for appid(steam)/version(1731433018)/tid(9958)
Error: Check your DISPLAY environment variable and make sure that you have enabled X.
If you are running remotely, make sure that you have a remote connection which will allow an X connection.

For more information visit https://support.steampowered.com/kb_article.php?ref=4050-WOJB-0608
Using host zenity for message
assert_20241126215242_4.dmp[9963]: Uploading dump (out-of-process)
/tmp/dumps/assert_20241126215242_4.dmp
src/steamexe/main.cpp (1328) : failed to initialize update status ui, or create initial window
src/steamexe/main.cpp (1328) : failed to initialize update status ui, or create initial window
11/26 21:52:42 Init: Installing breakpad exception handler for appid(steam)/version(1731433018)/tid(9958)
assert_20241126215242_7.dmp[9967]: Uploading dump (out-of-process)
/tmp/dumps/assert_20241126215242_7.dmp
~ 
❯ assert_20241126215242_7.dmp[9967]: Finished uploading minidump (out-of-process): success = yes
assert_20241126215242_7.dmp[9967]: response: CrashID=bp-d24466c0-21b4-45ce-a0d9-3cf602241126
assert_20241126215242_7.dmp[9967]: file ''/tmp/dumps/assert_20241126215242_7.dmp'', upload yes: ''CrashID=bp-d24466c0-21b4-45ce-a0d9-3cf602241126''
assert_20241126215242_4.dmp[9963]: Finished uploading minidump (out-of-process): success = yes
assert_20241126215242_4.dmp[9963]: response: CrashID=bp-38149775-6e7b-4400-a972-a50db2241126
assert_20241126215242_4.dmp[9963]: file ''/tmp/dumps/assert_20241126215242_4.dmp'', upload yes: ''CrashID=bp-38149775-6e7b-4400-a972-a50db2241126''

Version

0.29.0+1dacffb.flake

Backend

Wayland (experimental)

Config

import os
import subprocess
import socket
from libqtile import hook, qtile
from libqtile import bar, layout, qtile, widget
from libqtile.config import Click, Drag, Group, ScratchPad, DropDown, Key, Match, Screen
from libqtile.lazy import lazy
# from libqtile.utils import guess_terminal
from qtile_extras import widget
from libqtile.backend.wayland import InputConfig
from qtile_extras.widget.decorations import BorderDecoration
from libqtile.config import Key, KeyChord
from theme import colors

# Set backend
if qtile.core.name == "wayland":
    os.environ["XDG_SESSION_DESKTOP"] = "qtile:wlroots"
    os.environ["XDG_CURRENT_DESKTOP"] = "qtile:wlroots"

# Startup
@hook.subscribe.startup_once
def autostart():
    home = os.path.expanduser('~/Dotfiles/nixos/modules/qtile/autostart.sh')
    subprocess.Popen([home])

# OnReload
def onreload():
    reload = os.path.expanduser('~/Dotfiles/nixos/modules/qtile/reload.sh')
    subprocess.Popen([reload])

onreload()

# Variables

mod = "mod4"
host = socket.gethostname()
terminal = "kitty" 
browser = "firefox"
launcher = "rofi -show drun"
fileManager = "thunar"
editor = "code"
ntCenter = "swaync-client -t -sw"

keys = [
    # A list of available commands that can be bound to keys can be found
    # at https://docs.qtile.org/en/latest/manual/config/lazy.html
    # Switch between windows
    Key([mod], "h", lazy.layout.left(), desc="Move focus to left"),
    Key([mod], "l", lazy.layout.right(), desc="Move focus to right"),
    Key([mod], "j", lazy.layout.down(), desc="Move focus down"),
    Key([mod], "k", lazy.layout.up(), desc="Move focus up"),
    Key([mod], "space", lazy.layout.next(), desc="Move window focus to other window"),
    # Move windows between left/right columns or move up/down in current stack.
    # Moving out of range in Columns layout will create new column.
    Key([mod, "shift"], "h", lazy.layout.shuffle_left(), desc="Move window to the left"),
    Key([mod, "shift"], "l", lazy.layout.shuffle_right(), desc="Move window to the right"),
    Key([mod, "shift"], "j", lazy.layout.shuffle_down(), desc="Move window down"),
    Key([mod, "shift"], "k", lazy.layout.shuffle_up(), desc="Move window up"),

    # Grow windows. If current window is on the edge of screen and direction
    # will be to screen edge - window would shrink.
    Key([mod, "control"], "j", lazy.layout.shrink(), desc="Shrink window"),
    Key([mod, "control"], "k", lazy.layout.grow(), desc="Grow window"),
    Key([mod], "n", lazy.layout.normalize(), desc="Reset all window sizes"),
    # Toggle between split and unsplit sides of stack.
    # Split = all windows displayed
    # Unsplit = 1 window displayed, like Max layout, but still with
    # multiple stack panes
    Key([mod, "shift"], "Return", lazy.layout.toggle_split(), desc="Toggle between split and unsplit sides of stack"),
    Key([mod], "Return", lazy.spawn(terminal), desc="Launch terminal"),
    # Toggle between different layouts as defined below
    Key([mod], "z", lazy.next_layout(), desc="Toggle between layouts"),
    Key([mod, "Shift"], "q", lazy.window.kill(), desc="Kill focused window"),
    Key([mod], "f", lazy.window.toggle_fullscreen(), desc="Toggle fullscreen on the focused window"),
    Key([mod], "t", lazy.window.toggle_floating(), desc="Toggle floating on the focused window"),
    Key([mod, "control"], "r", lazy.reload_config(), desc="Reload the config"),
    Key([mod, "control"], "q", lazy.shutdown(), desc="Shutdown Qtile"),
    Key([mod], "d", lazy.spawn(launcher), desc="Exec app launcher"),
    Key([mod], "e", lazy.spawn(fileManager), desc="Exec File manager"),
    Key([mod], "b", lazy.spawn(browser), desc="Exec browser"),
    Key([mod], "c", lazy.spawn(editor), desc="Exec editor"),
    Key([mod], "Tab", lazy.spawn(ntCenter), desc="Exec notification center"),
    Key([mod, "Shift"], "s", lazy.spawn('grim -g "$(slurp -d)" - | wl-copy', shell=True)),
    Key(["Shift"], "Tab", lazy.widget["keyboardlayout"].next_keyboard()),
    Key([], "XF86AudioRaiseVolume", lazy.spawn("wpctl set-volume -l 1.4 @DEFAULT_AUDIO_SINK@ 5%+")),
    Key([], "XF86AudioLowerVolume", lazy.spawn("wpctl set-volume -l 1.4 @DEFAULT_AUDIO_SINK@ 5%-")),
    Key([], "XF86AudioMute", lazy.spawn("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle")),
    Key([], "XF86MonBrightnessDown", lazy.spawn("brightnessctl set 5%-")),
    Key([], "XF86MonBrightnessUp", lazy.spawn("brightnessctl set +5%")),
    Key([], "XF86AudioPlay", lazy.spawn('playerctl --player=spotify,%any play-pause')),
    Key([], "XF86AudioPrev", lazy.spawn('playerctl --player=spotify,%any previous')),
    Key([], "XF86AudioNext", lazy.spawn('playerctl --player=spotify,%any next')),

    KeyChord([mod], "i", [
        Key([mod], "i", lazy.ungrab_all_chords())],
        mode=True,
        name='Vm Mode',
    ),
]

# Add key bindings to switch VTs in Wayland.
# We can't check qtile.core.name in default config as it is loaded before qtile is started
# We therefore defer the check until the key binding is run by using .when(func=...)
for vt in range(1, 8):
    keys.append(
        Key(
            ["control", "mod1"],
            f"f{vt}",
            lazy.core.change_vt(vt).when(func=lambda: qtile.core.name == "wayland"),
            desc=f"Switch to VT{vt}",
        )
    )


# groups = [Group(i) for i in "123456789"]
groups = [
    ScratchPad("p", [
        DropDown("Music", "spotify", opacity=1, height=0.5, on_focus_lost_hide=False),
        DropDown("Term", terminal, opacity=1, height=0.5, on_focus_lost_hide=False),
    ]),
    Group("1", label=" "),
    Group("2", label="󰈹 ", matches=[Match(wm_class="Navigator"), Match(wm_class="vivaldi-stable")], spawn=browser),
    Group("3", label=" "),
    Group("4", label=" ", matches=[Match(wm_class="obsidian")]),
    Group("5", label=" "),
    Group("6", label="󰑈 "),
    Group("7", label=" "),
    Group("8", label="󰧮 "),
    Group("9", label=" ", matches=[Match(wm_class="vesktop")], spawn="vesktop"),
    Group("0", label="󰮂 ", matches=[Match(wm_class="steam")]),
]

for i in groups:
    keys.extend(
        [
            # mod1 + group number = switch to group
            Key(
                [mod],
                i.name,
                lazy.group[i.name].toscreen(),
                desc="Switch to group {}".format(i.name),
            ),
            # mod1 + shift + group number = switch to & move focused window to group
            Key(
                [mod, "shift"],
                i.name,
                lazy.window.togroup(i.name, switch_group=True),
                desc="Switch to & move focused window to group {}".format(i.name),
            ),
            Key([mod], "s", lazy.group['p'].dropdown_toggle('Music')),
            Key([mod], "a", lazy.group['p'].dropdown_toggle('Term')),


            # Or, use below if you prefer not to switch to that group.
            # # mod1 + shift + group number = move focused window to group
            # Key([mod, "shift"], i.name, lazy.window.togroup(i.name),
            #     desc="move focused window to group {}".format(i.name)),
        ]
    )

if colors["theme"] == "Everforest":
    layout_theme = {
        "border_focus": "#A7C080",
        "border_normal": "#48584E",
        "border_width": 2,
        "margin": 5,
    }
elif colors["theme"] == "Nord":
    layout_theme = {
    "border_focus": "#5E81AC",
    "border_normal": "#4C566A",
    "border_width": 2,
    "margin": 5,
    }

layouts = [
    # layout.Columns(**layout_theme),
    #layout.Max(),
    # Try more layouts by unleashing below layouts.
    # layout.Stack(num_stacks=2),
    # layout.Bsp(),
    # layout.Matrix(),
    layout.MonadTall(**layout_theme),
    # layout.MonadWide(),
    # layout.RatioTile(),
    # layout.Tile(),
    # layout.TreeTab(),
    # layout.VerticalTile(),
    # layout.Zoomy(),
]

widget_defaults = dict(
    font="Fira Code Nerd Font Medium",
    fontsize=14,
    padding=3,
)
extension_defaults = widget_defaults.copy()

widget_list = [
    widget.TextBox(
        fmt = " ",
        padding = None,
        fontsize = 20,
        foreground = colors["base12"],
        mouse_callbacks = {"Button1": lambda: qtile.spawn(f"{browser} github.com/gurjaka")},
    ),

    widget.Clock(
        foreground = colors["base14"],
        format=" %a,%b,%d -  %H:%M",
        decorations = [
            BorderDecoration(
                border_width = [0,0,2,0],
                colour = colors["base14"],
                padding_x = 3,
                padding_y = None,
            ),
        ],
    ),

    widget.Spacer(
        length = 2,
    ),

    widget.GroupBox(
        fontsize = 20,
        active = colors["base09"],
        inactive = colors["base03"],
        block_highlight_text_color = "#FFFFFF",
        highlight_method = "line",
        highlight_color = colors["base01"],
        this_current_screen_border = colors["base09"],
        urgent_alert_method = "line",
        urgent_border = colors["base11"],
        disable_drag = True,
        decorations = [
            BorderDecoration(
                border_width = [0,0,2,0],
                colour = colors["base03"],
                padding_x = 3,
                padding_y = None,
            ),
        ],
    ),

    widget.Spacer(
        length = 2,
    ),

    widget.TextBox(
        foreground = colors["base05"],
        text = '|',
        padding = 2,
    ),

    widget.CurrentLayoutIcon(
        foreground = colors["base05"],
        padding = 4,
        scale = 0.6
    ),

    widget.CurrentLayout(
        foreground = colors["base05"],
        padding = 5,
    ),

    widget.TextBox(
        foreground = colors["base05"],
        text = '|',
        padding = 2,
    ),

    widget.WindowName(
        foreground = colors["base13"],
        #format = "{}",
        decorations = [
            BorderDecoration(
                border_width = [0,0,2,0],
                colour = colors["base13"],
                padding_x = 3,
                padding_y = None,
            ),
        ],
    ),

    widget.Spacer(
        length = 2,
    ),

    widget.Chord(
        chords_colors={
            "launch": (colors["base01"], colors["base12"]),
        },
        foreground = colors["base12"],
        name_transform=lambda name: name.upper(),
        decorations = [
            BorderDecoration(
                border_width = [0,0,2,0],
                colour = colors["base12"],
                padding_x = None,
                padding_y = None,
            ),
        ],
    ),

    widget.Spacer(
        length = 2,
    ),

    # NB Systray is incompatible with Wayland, consider using StatusNotifier instead
    # widget.StatusNotifier(),
    widget.StatusNotifier(
        background = colors["base02"],
        padding = 5,
        decorations = [
            BorderDecoration(
                border_width = [0,0,2,0],
                colour = colors["base11"],
                padding_x = None,
                padding_y = None,
            ),
        ],
    ),

    widget.Spacer(
        length = 2,
    ),

    widget.Battery(
        foreground = colors["base14"],
        charge_char = "󰂄",
        discharge_char = "󰁿",
        empty_char = "󰂎",
        format = '{char} {percent:2.0%} {hour:d}:{min:02d}',
        decorations=[
            BorderDecoration(
                border_width = [0, 0, 2, 0],
                colour = colors["base14"],
                padding_x = 3,
                padding_y = None,
            ),
        ],
    ),

    widget.Spacer(
        length = 2,
    ),


    widget.GenPollText(
        update_interval = 300,
        func = lambda: subprocess.check_output("printf $(uname -r)", shell=True, text=True),
        foreground = colors["base12"],
        fmt = ' {}',
        decorations=[
            BorderDecoration(
                border_width = [0, 0, 2, 0],
                colour = colors["base12"],
                padding_x = 3,
                padding_y = None,
            ),
        ],
    ),

    widget.Spacer(
        length = 2,
    ),

    widget.CPU(
        foreground = colors["base09"],
        format = '󰍹 Cpu:{load_percent}%',
        mouse_callbacks = {"Button1": lambda: qtile.spawn(f"{terminal} btop")},
        decorations = [
            BorderDecoration(
                border_width = [0,0,2,0],
                colour = colors["base09"],
                padding_x = 3,
                padding_y = None,
            ),
        ],
    ),

    widget.Spacer(
        length = 2,
    ),

    widget.DF(
        update_interval = 60,
        foreground = colors["base14"],
        mouse_callbacks = {'Button1': lambda: qtile.spawn(f"{terminal} df")},
        partition = '/',
        #format = '[{p}] {uf}{m} ({r:.0f}%)',
        format = '🖴 Disk:{uf}{m}',
        visible_on_warn = False,
        decorations=[
            BorderDecoration(
                border_width = [0, 0, 2, 0],
                colour = colors["base14"],
                padding_x = 3,
                padding_y = None,
            )
        ],
    ),

    widget.Spacer(
        length = 2,
    ),

    widget.Memory(
        foreground = colors["base15"],
        format = ' Mem:{NotAvailable:.0f}{mm}',
        mouse_callbacks = {"Button1": lambda: qtile.spawn(f"{terminal} btop")},
        decorations = [
            BorderDecoration(
                border_width = [0,0,2,0],
                colour = colors["base15"],
                padding_x = 3,
                padding_y = None,
            ),
        ],
    ),

    widget.Spacer(
        length = 2,
    ),

    widget.PulseVolume(
        foreground = colors["base13"],
        fmt = " :{}",
        decorations = [
            BorderDecoration(
                border_width = [0,0,2,0],
                colour = colors["base13"],
                padding_x = 3,
                padding_y = None,
            ),
        ],
    ),

    widget.Spacer(
        length = 2,
    ),

    widget.KeyboardLayout(
        foreground = colors["base08"],
        configured_keyboards = ["us dvorak", "ge"],
        display_map = {"us dvorak": "US", "ge": "GE"},
        option = "caps:escape",
        fmt = " Kbd:{}",
        decorations = [
            BorderDecoration(
                border_width = [0,0,2,0],
                colour = colors["base08"],
                padding_x = 3,
                padding_y = None,
            ),
        ],
    ),

    widget.Spacer(
        length = 2,
    ),
]

if host != "laptop":
    del widget_list[15]

screens = [
    Screen(
        wallpaper = f"~/Dotfiles/wallpapers/{colors["theme"]}/main.jpg",
        wallpaper_mode = "fill",
        top=bar.Bar(
            widget_list,
            24,
            background = colors["base00"],
        ),
    ),
]

# Drag floating layouts.
mouse = [
    Drag([mod], "Button1", lazy.window.set_position_floating(), start=lazy.window.get_position()),
    Drag([mod], "Button3", lazy.window.set_size_floating(), start=lazy.window.get_size()),
    Click([mod], "Button2", lazy.window.bring_to_front()),
]

dgroups_key_binder = None
dgroups_app_rules = []  # type: list
follow_mouse_focus = True
bring_front_click = True
floats_kept_above = True
cursor_warp = False
floating_layout = layout.Floating(
    **layout_theme,
    float_rules=[
        # Run the utility of `xprop` to see the wm class and name of an X client.
        *layout.Floating.default_float_rules,
        Match(wm_class="confirmreset"),  # gitk
        Match(wm_class="makebranch"),  # gitk
        Match(wm_class="maketag"),  # gitk
        Match(wm_class="ssh-askpass"),  # ssh-askpass
        Match(title="branchdialog"),  # gitk
        Match(title="pinentry"),  # GPG key password entry
    ]
)

auto_fullscreen = True
focus_on_window_activation = "smart"
reconfigure_screens = True

# If things like steam games want to auto-minimize themselves when losing
# focus, should we respect this or not?
auto_minimize = True

# When using the Wayland backend, this can be used to configure input devices.
wl_input_rules = {
    "type:pointer": InputConfig(
        accel_profile = "flat",
    ),
    # "type:keyboard": InputConfig(
    #     # kb_layout = "us, ge",
    #     # kb_options = "grp:alt_shift_toggle, caps:escape",
    # ),
}

wl_xcursor_theme = "Breeze_Light"
wl_xcursor_size = 24

# XXX: Gasp! We're lying here. In fact, nobody really uses or cares about this
# string besides java UI toolkits; you can see several discussions on the
# mailing lists, GitHub issues, and other WM documentation that suggest setting
# this string if your java app doesn't work correctly. We may as well just lie
# and say that we're a working one by default.
#
# We choose LG3D to maximize irony: it is a 3D non-reparenting WM written in
# java that happens to be on java's whitelist.
wmname = "QTILE"

Logs

qtile.log

Required

  • I have searched past issues to see if this bug has already been reported, and it hasn't been.
  • I understand that people give their precious time for free, and thus I've done my very best to make this problem as easy as possible to investigate.
@elParaguayo
Copy link
Member

@tych0 I think this is caused by removing the double fork.

I get the following error waitpid for Xwayland fork failed: No child processes which, from a 2 second search, seems to be caused by the SIGCHLD handler (see djpohly/dwl#177 (comment) and fix in djpohly/dwl#212).

@tych0
Copy link
Member

tych0 commented Nov 27, 2024

Ah man, that is... unfortunate.

I don't think it's double fork, but our SIGCHLD handler, based on: https://gitlab.freedesktop.org/wlroots/wlroots/-/commit/871646d22522141c45db2c0bfa1528d595bb69df the wlroots library wants to fork (which seems slightly impolite) an X server. When its waitpid() races with our SIGCHLD handler, it fails.

I think if wlroots really wants to do this, they should mask off the SIGCHLD handler while they're doing their own thing. Probably we should send them a patch, but in the meantime, we can manage it ourselves. Does: tych0@dbe76e9 work?

If not, we'll have to do something like what the patch you linked did (or maybe pywlroots should, like I mention flacjacket/pywlroots#207 ?). But really wlroots proper should do that. I don't have enough wayland-fu to be building my own wayland stuff to test patches, though.

@elParaguayo
Copy link
Member

Your patch works for me.

Would be good to get @jwijenbergh thoughts here too as he's more familiar with the wlroots stuff.

tych0 added a commit to tych0/qtile that referenced this issue Nov 27, 2024
the wayland backend via wlroots wants to double fork an X server for
XWayland, and expects to waitpid() on the middle fork to make sure things
were successful. our SIGCHLD handler races with this process and
interferes, causing things like:

    waitpid for Xwayland fork failed: No child processes

let's delay installing our SIGCHLD handler until after XWayland is
initialized to hopefully dodge this error.

Fixes qtile#5101

Signed-off-by: Tycho Andersen <tycho@tycho.pizza>
@tych0
Copy link
Member

tych0 commented Nov 27, 2024

Ok, thanks for confirming. Happy to wait for @jwijenbergh's review, although I am reasonably confident that's the right fix given the implementations you linked to.

I will have a think about how wlroots can really handle this. it feels like double posix_spawn() is pretty heavyweight for them, but also forking in library code means many downstream users have to do tap dancing like this to get things to work correctly, which is unfortunate.

tych0 added a commit to tych0/qtile that referenced this issue Nov 27, 2024
the wayland backend via wlroots wants to double fork an X server for
XWayland, and expects to waitpid() on the middle fork to make sure things
were successful. our SIGCHLD handler races with this process and
interferes, causing things like:

    waitpid for Xwayland fork failed: No child processes

let's delay installing our SIGCHLD handler until after XWayland is
initialized to hopefully dodge this error.

Fixes qtile#5101

Signed-off-by: Tycho Andersen <tycho@tycho.pizza>
@tych0
Copy link
Member

tych0 commented Nov 27, 2024

It turns out they already do some pipe-notify thing for xwayland, and so this waitpid() is just about zombie prevention, so I think we can safely ignore it. I sent them a patch: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4926

If they merge it, then once we move to that wlroots version, we can revert my fix.

@elParaguayo
Copy link
Member

I've merged your fix for now as it solves a real issue for some users. We can revert and implement a different fix if necessary later.

@cr1ogen
Copy link

cr1ogen commented Dec 2, 2024

I've merged your fix for now as it solves a real issue for some users. We can revert and implement a different fix if necessary later.

Hi, I started having this problem when I updated to the latest dev. Do you know how to go back to a previous version? Thanks

@tych0
Copy link
Member

tych0 commented Dec 2, 2024

Can you say exactly which commit you're on (qtile --version)? The latest version should have it fixed.

@cr1ogen
Copy link

cr1ogen commented Dec 2, 2024

Can you say exactly which commit you're on (qtile --version)? The latest version should have it fixed.

Of course
qtile --version 0.29.1.dev41+g4897d0d1

@cr1ogen
Copy link

cr1ogen commented Dec 2, 2024

I don't know if it's relevant, but if I run an Xwayland Window and then run steam inside it, it works.

@Gurjaka
Copy link
Contributor Author

Gurjaka commented Dec 2, 2024

I don't know if it's relevant, but if I run an Xwayland Window and then run steam inside it, it works.

I dont really understand how that works but steam isnt native to wayland so it runs xwayland

@tych0
Copy link
Member

tych0 commented Dec 2, 2024

I don't know if it's relevant, but if I run an Xwayland Window and then run steam inside it, it works.

I'm confused. I thought the issue was fixed?

@cr1ogen
Copy link

cr1ogen commented Dec 2, 2024

I don't know if it's relevant, but if I run an Xwayland Window and then run steam inside it, it works.

I'm confused. I thought the issue was fixed?

Maybe it's a problem with my system so I don't want to bother you, I use debian sid. Have you been able to reproduce it again?

@Gurjaka
Copy link
Contributor Author

Gurjaka commented Dec 2, 2024

I don't know if it's relevant, but if I run an Xwayland Window and then run steam inside it, it works.

I'm confused. I thought the issue was fixed?

Maybe it's a problem with my system so I don't want to bother you, I use debian sid. Have you been able to reproduce it again?

I am on nixos, and after the patch didnt encounter any problems, this is my version

0.29.0+4897d0d.flake

if it still occurs than its something devs have to dig in
(not closing issue for now)

@tych0
Copy link
Member

tych0 commented Dec 2, 2024

Maybe it's a problem with my system so I don't want to bother you, I use debian sid. Have you been able to reproduce it again?

I believe the patch fixes the issue, so it's likely yours is something different. I don't use wayland myself, so I was never able to reproduce it.

@cr1ogen
Copy link

cr1ogen commented Dec 2, 2024

Maybe it's a problem with my system so I don't want to bother you, I use debian sid. Have you been able to reproduce it again?

I believe the patch fixes the issue, so it's likely yours is something different. I don't use wayland myself, so I was never able to reproduce it.

I have 2 erros in my log file

2024-12-02 17:21:00,670 WARNING libqtile base.py:__getattr__():L273 Deprecation Warning: commands exposed via IPC no longer use the 'cmd_' prefix. Please replace 'cmd_spawn' with 'spawn' in your code.

2024-12-02 18:09:51,824 ERROR wlroots log.py:log_func_callback():L15 [xwayland/server.c:261] waitpid for Xwayland fork failed: No hay ningún proceso hijo

@cr1ogen
Copy link

cr1ogen commented Dec 2, 2024

In hyprland work

this is qtile

  File "/usr/local/lib/python3.12/dist-packages/libqtile/ipc.py", line 180, in async_send
    reader, writer = await asyncio.wait_for(
                     ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/asyncio/tasks.py", line 520, in wait_for
    return await fut
           ^^^^^^^^^
  File "/usr/lib/python3.12/asyncio/streams.py", line 97, in open_unix_connection
    transport, _ = await loop.create_unix_connection(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/asyncio/unix_events.py", line 261, in create_unix_connection
    await self.sock_connect(sock, path)
  File "/usr/lib/python3.12/asyncio/selector_events.py", line 651, in sock_connect
    return await fut
           ^^^^^^^^^
  File "/usr/lib/python3.12/asyncio/selector_events.py", line 659, in _sock_connect
    sock.connect(address)
FileNotFoundError: [Errno 2] No such file or directory

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/bin/qtile", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/libqtile/scripts/main.py", line 79, in main
    func(options)
  File "/usr/local/lib/python3.12/dist-packages/libqtile/scripts/cmd_obj.py", line 178, in cmd_obj
    ret = run_function(obj, args.function, args.args)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/libqtile/scripts/cmd_obj.py", line 132, in run_function
    ret = client.call(funcname, *args, lifted=True)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/libqtile/command/client.py", line 126, in call
    if name not in self.commands:
                   ^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/libqtile/command/client.py", line 146, in commands
    return self._command.execute(command_call, (), {})
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/libqtile/command/interface.py", line 248, in execute
    status, result = self._client.send(
                     ^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/libqtile/ipc.py", line 171, in send
    return asyncio.run(self.async_send(msg))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/asyncio/runners.py", line 194, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/asyncio/base_events.py", line 686, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/libqtile/ipc.py", line 184, in async_send
    raise IPCError(f"Could not open {self.socket_path}")
libqtile.ipc.IPCError: Could not open /home/cr1ogen/.cache/qtile/qtilesocket.wayland-1

@tych0
Copy link
Member

tych0 commented Dec 3, 2024

2024-12-02 18:09:51,824 ERROR wlroots log.py:log_func_callback():L15 [xwayland/server.c:261] waitpid for Xwayland fork failed: No hay ningún proceso hijo

This one should be fixed in the current git master. You're saying you get it still? Can you confirm which qtile version you're on?

@tych0
Copy link
Member

tych0 commented Dec 3, 2024

Assuming it's the one you posted here: #5101 (comment) I wouldn't expect you to see it.

Can you add some logging around the areas in e73ea6e to see what exactly happens when if so? I wonder if we are racing and installing the signal handler still before xwayland starts up somehow.

@cr1ogen
Copy link

cr1ogen commented Dec 3, 2024

2024-12-02 18:09:51,824 ERROR wlroots log.py:log_func_callback():L15 [xwayland/server.c:261] waitpid for Xwayland fork failed: No hay ningún proceso hijo

This one should be fixed in the current git master. You're saying you get it still? Can you confirm which qtile version you're on?

I'm still have it
qtile --version 0.29.1.dev41+g4897d0d1

@cr1ogen
Copy link

cr1ogen commented Dec 3, 2024

Assuming it's the one you posted here: #5101 (comment) I wouldn't expect you to see it.

Can you add some logging around the areas in e73ea6e to see what exactly happens when if so? I wonder if we are racing and installing the signal handler still before xwayland starts up somehow.

Is it for me? Or maybe you forgot to tag someone? I don't understand how to do it.

@tych0
Copy link
Member

tych0 commented Dec 3, 2024

Is it for me? Or maybe you forgot to tag someone? I don't understand how to do it.

Yes, I'd like to fix this if you are still experiencing the problem, but I don't run wayland and therefore can't reproduce, so I need some information to debug it. In particular, I'd like to know the order of:

  1. when we start xwayland
  2. when we install the SIGHILD handler
  3. when we reap the xwayland pid (probably just log all pids from the SIGCHILD handler)

@cr1ogen
Copy link

cr1ogen commented Dec 3, 2024

Is it for me? Or maybe you forgot to tag someone? I don't understand how to do it.

Yes, I'd like to fix this if you are still experiencing the problem, but I don't run wayland and therefore can't reproduce, so I need some information to debug it. In particular, I'd like to know the order of:

  1. when we start xwayland
  2. when we install the SIGHILD handler
  3. when we reap the xwayland pid (probably just log all pids from the SIGCHILD handler)

Sorry, I have no idea how to do what you're asking, I'm just an end user. If you could be more specific I would appreciate it.

@tych0
Copy link
Member

tych0 commented Dec 4, 2024

You can just edit the file and install it as you would a normal development version of qtile.

@cr1ogen
Copy link

cr1ogen commented Dec 5, 2024

You can just edit the file and install it as you would a normal development version of qtile.

Which file do I have to edit? In commit e73ea6e there are 3 files: core.py, manage.py and utils.py

@tych0
Copy link
Member

tych0 commented Dec 5, 2024

Ideally all three, I'd like to know when the events from each happen.

nschloe pushed a commit to live-clones/wlroots that referenced this issue Dec 6, 2024
SIGCHLD here isn't fatal: we have other means of notifying that things were
successful or failure, and it causes many compositors to have to do a bunch
of extra work:

qtile/qtile#5101
flacjacket/pywlroots#207 (comment)
djpohly/dwl#212

Signed-off-by: Tycho Andersen <tycho@tycho.pizza>
@cr1ogen
Copy link

cr1ogen commented Dec 9, 2024

I put what you told me but in qtile.log no error appears, only this 2024-12-08 20:52:42,935 ERROR wlroots log.py:log_func_callback():L15 [xwayland/server.c:261] waitpid for Xwayland fork failed: There is no child process I must be doing something wrong

@tych0
Copy link
Member

tych0 commented Dec 9, 2024

I suspect the qtile you are installing and the qtile you are actually running are different versions. I would double check that you're running the custom installed qtile instead of one from distro packaging or whatever else.

@cr1ogen
Copy link

cr1ogen commented Dec 9, 2024

I discovered something that happens to me in Qtile. I use Waypaper as wallpaper manager, for some reason when I start Qtile, the wallpaper doesn't appear.
Now, if I want to start Steam or any X11 application before launching waypaper and choose a wallpaper, I get the error
ERROR wlroots log.py:log_func_callback():L15 [xwayland/server.c:261] waitpid for Xwayland fork failed: There is no child process
but if I choose the wallpaper before launching any X11 application it works without problems

@cr1ogen
Copy link

cr1ogen commented Dec 9, 2024

I was looking and it's like when there is no wallpaper, Xwayland can't start, since I put a wallpaper with the Qtile manager and an Xwayland process was formed and when I closed that process it gave the child process error, and it only works again if I start Xwayland manually.

@tych0
Copy link
Member

tych0 commented Dec 9, 2024

I am not really a wayland person, but it could be that someone else is starting xwayland in that case, so wlroots doesn't have to? Not sure. Either way, I really do think the patch I have landed fixes the bug, so I would try to confirm which version of qtile you are actually running, since I believe the bug is fixed.

@cr1ogen
Copy link

cr1ogen commented Dec 9, 2024

Yesterday I updated from the Git repository using git pull, the version I have is
qtile --version 0.29.1.dev52+ga49ed891
I'm uploading a video for you to see

https://youtu.be/rU8UYkx-Ax8

@cr1ogen
Copy link

cr1ogen commented Dec 9, 2024

241209_17-07-08

@tych0
Copy link
Member

tych0 commented Dec 9, 2024

Can you confirm that the version that you get from your shell is the same as the version that your xsession starts?

@cr1ogen
Copy link

cr1ogen commented Dec 10, 2024

Can you confirm that the version that you get from your shell is the same as the version that your xsession starts?

If you mean that Xsession and Wayland-session are the same version, I confirm

@tych0
Copy link
Member

tych0 commented Dec 10, 2024

Ok. Can you add the log messages so we can figure out what order things are happening in that causes the issue?

@cr1ogen
Copy link

cr1ogen commented Dec 15, 2024

2024-12-15 20:42:30,504 WARNING libqtile base.py:__getattr__():L273 Deprecation Warning: commands exposed via IPC no longer use the 'cmd_' prefix. Please replace 'cmd_spawn' with 'spawn' in your code.
2024-12-15 20:42:30,585 WARNING libqtile base.py:__getattr__():L273 Deprecation Warning: commands exposed via IPC no longer use the 'cmd_' prefix. Please replace 'cmd_spawn' with 'spawn' in your code.
2024-12-15 20:42:33,884 ERROR wlroots log.py:log_func_callback():L15 [xwayland/server.c:261] waitpid for Xwayland fork failed: No hay ningún proceso hijo
2024-12-15 20:43:05,232 ERROR wlroots log.py:log_func_callback():L15 [libinput] event7  - Razer Razer DeathAdder: client bug: event processing lagging behind by 32ms, your system is too slow

2024-12-15 20:43:38,772 ERROR pywayland.server listener.py:notify_func():L42 Exception in callback function
Traceback (most recent call last):
  File "/home/cr1ogen/Git/pywlroots-0.17.0/.eggs/pywayland-0.4.18-py3.12-linux-x86_64.egg/pywayland/server/listener.py", line 40, in notify_func
    callback(listener, data)
  File "/usr/local/lib/python3.12/dist-packages/libqtile/backend/wayland/core.py", line 728, in _on_cursor_button
    handled = self._process_cursor_button(button, pressed)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/libqtile/backend/wayland/core.py", line 1189, in _process_cursor_button
    self._hovered_window.process_button_click(
  File "/usr/local/lib/python3.12/dist-packages/libqtile/bar.py", line 538, in process_button_click
    widget.button_press(
  File "/usr/local/lib/python3.12/dist-packages/libqtile/widget/tasklist.py", line 480, in button_press
    base._Widget.button_press(self, x, y, button)
  File "/usr/local/lib/python3.12/dist-packages/libqtile/widget/base.py", line 295, in button_press
    cmd()
  File "/usr/local/lib/python3.12/dist-packages/libqtile/widget/tasklist.py", line 491, in select_window
    window.toggle_minimize()
  File "/usr/local/lib/python3.12/dist-packages/libqtile/backend/wayland/window.py", line 706, in toggle_minimize
    self.minimized = not self.minimized
    ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/libqtile/backend/wayland/window.py", line 508, in minimized
    self.floating = False
    ^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/libqtile/backend/wayland/window.py", line 434, in floating
    self.group.mark_floating(self, False)
  File "/usr/local/lib/python3.12/dist-packages/libqtile/group.py", line 342, in mark_floating
    i.add_client(win)
  File "/usr/local/lib/python3.12/dist-packages/libqtile/layout/plasma.py", line 952, in add_client
    self.root.restore(new)
  File "/usr/local/lib/python3.12/dist-packages/libqtile/layout/plasma.py", line 634, in restore
    node.siblings[0].size = sizes[1]
    ~~~~~~~~~~~~~^^^
IndexError: list index out of range
2024-12-15 20:43:39,281 ERROR pywayland.server listener.py:notify_func():L42 Exception in callback function
Traceback (most recent call last):
  File "/home/cr1ogen/Git/pywlroots-0.17.0/.eggs/pywayland-0.4.18-py3.12-linux-x86_64.egg/pywayland/server/listener.py", line 40, in notify_func
    callback(listener, data)
  File "/usr/local/lib/python3.12/dist-packages/libqtile/backend/wayland/core.py", line 728, in _on_cursor_button
    handled = self._process_cursor_button(button, pressed)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/libqtile/backend/wayland/core.py", line 1189, in _process_cursor_button
    self._hovered_window.process_button_click(
  File "/usr/local/lib/python3.12/dist-packages/libqtile/bar.py", line 538, in process_button_click
    widget.button_press(
  File "/usr/local/lib/python3.12/dist-packages/libqtile/widget/tasklist.py", line 480, in button_press
    base._Widget.button_press(self, x, y, button)
  File "/usr/local/lib/python3.12/dist-packages/libqtile/widget/base.py", line 295, in button_press
    cmd()
  File "/usr/local/lib/python3.12/dist-packages/libqtile/widget/tasklist.py", line 491, in select_window
    window.toggle_minimize()
  File "/usr/local/lib/python3.12/dist-packages/libqtile/backend/wayland/window.py", line 706, in toggle_minimize
    self.minimized = not self.minimized
    ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/libqtile/backend/wayland/window.py", line 505, in minimized
    self._reconfigure_floating(new_float_state=FloatStates.MINIMIZED)
  File "/usr/local/lib/python3.12/dist-packages/libqtile/backend/wayland/window.py", line 571, in _reconfigure_floating
    self.group.mark_floating(self, True)
  File "/usr/local/lib/python3.12/dist-packages/libqtile/group.py", line 327, in mark_floating
    self.tiled_windows.remove(win)
KeyError: XdgWindow(name='Xwayland on :0', wid=9)
2024-12-15 20:44:02,012 WARNING libqtile base.py:__getattr__():L273 Deprecation Warning: commands exposed via IPC no longer use the 'cmd_' prefix. Please replace 'cmd_spawn' with 'spawn' in your code.

@elParaguayo
Copy link
Member

I'm actually still hitting this bug too but it's intermittent.

@elParaguayo elParaguayo reopened this Dec 16, 2024
@Gurjaka
Copy link
Contributor Author

Gurjaka commented Dec 16, 2024

I'm actually still hitting this bug too but it's intermittent.

Hm, made the change to wayland?

@cr1ogen
Copy link

cr1ogen commented Dec 16, 2024

I'm actually still hitting this bug too but it's intermittent.

If it is intermittent, in my case more than less xD

@Gurjaka
Copy link
Contributor Author

Gurjaka commented Dec 16, 2024

Tbh I haven't faced that issue in a while, got to check latest commits

@elParaguayo
Copy link
Member

It seems that some apps trigger a crash and others don't.

@jwijenbergh
Copy link
Contributor

Yeah I can reproduce this, sometimes NO xwayland apps start. The only way to fix it is to restart qtile

@Gurjaka
Copy link
Contributor Author

Gurjaka commented Jan 7, 2025

Yeah I can reproduce this, sometimes NO xwayland apps start. The only way to fix it is to restart qtile

I myself haven't faced this issue in a while, weird

@arjan-s
Copy link

arjan-s commented Jan 27, 2025

I'm encountering this issue as well. It's a regression in 0.30.0 and is what is keeping NixOS/nixpkgs#371737 from being merged.

What I see happening as a user is the following:

  • Qtile starts an Xwayland process on login
  • The Xwayland process quits after 10 seconds if it isn't being used
  • Once some application needs Xorg, Qtile 0.29.0 starts a new Xwayland process, but Qtile 0.30.0 doesn't

When I start an Xorg application within 10 seconds after login, it uses the initial Xwayland process and it all works fine. Except when I quit it, then the Xwayland process quits after 10 seconds and I'm back to not having a working Xwayland.

Simply reverting #5102 doesn't solve the issue, so I'm not sure where else to search.

@Gurjaka
Copy link
Contributor Author

Gurjaka commented Feb 3, 2025

@tych0 I was scrolling through qtile wayland core code, and found this comment:

# Set up XWayland. wlroots wants to fork() and waitpid() for the

then I checked your free desktop merge request to wlroots, which has been merged 1 month ago: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4926

so I think reverting the code might fix everything related to this topic, mind checking?

@jwijenbergh
Copy link
Contributor

so I think reverting the code might fix everything related to this topic, mind checking?

we would first have to move to a new wlroots

@Gurjaka
Copy link
Contributor Author

Gurjaka commented Feb 3, 2025

so I think reverting the code might fix everything related to this topic, mind checking?

we would first have to move to a new wlroots

Only thing I can say is release 0.30.0 is buggy on wayland and we need new release that fixes this

@cr1ogen
Copy link

cr1ogen commented Feb 3, 2025

so I think reverting the code might fix everything related to this topic, mind checking?

we would first have to move to a new wlroots

wlroots .018 does not allow compiling pywlroots flacjacket/pywlroots#228

@cr1ogen
Copy link

cr1ogen commented Feb 3, 2025

and Flacjacket doesn't seem to be very active lately

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants