udiskie icon indicating copy to clipboard operation
udiskie copied to clipboard

Password dialog does not float under sway

Open EricPraline opened this issue 3 years ago • 6 comments

Hi, I am using udiskie 2.2.0 under sway 1.5.1 and I like it a lot. I noticed that the password prompt gets tiled by default. This is trivially resolved by adding a for_window rule to the sway config, but I think it might be a good idea to change the default behavior. (This is probably easy, but I have never dealt with GTK.)

Thanks for writing udiskie :)

EricPraline avatar Dec 30 '20 13:12 EricPraline

Hi,

could be related to #75, #76, #79. udiskie uses a dialog type hint on the password dialog. Can you check your window manager config whether it has rules to float dialog windows?

Best, Thomas

coldfix avatar Dec 30 '20 22:12 coldfix

I belive that that the issues/PRs you referred to deal with X only, but the password prompt uses xdg-shell/wayland by default under sway. Since dialogs and popups are floated correctly with other programs (e. g. evince, sublime text), this is probably not a sway bug.

EricPraline avatar Jan 01 '21 10:01 EricPraline

Hi,

I think this is related to https://github.com/swaywm/sway/issues/4655. According to progandy:

As far as I know, wayland doesn't have any way to assign a window type for toplevel windows. You can only create a popup as the child of another window.

gtk2 uses xwayland where that is still possible.

[...]

Sway floats windows that have a fixed size (minimum size equals maximum size)

This would explain why the "dialog" type hint isn't recognized, and why it might work for some other apps (that still use gtk2 or do set a fixed size or a parent window).

FYI, zenity shows the same behaviour as udiskie (non-floating dialogs) for me, try it yourself:

zenity --info

I experimented a little, and so far didn't find a way to make it floatable on sway other than setting a fixed size or setting a (visible) parent window. Both are undesirable.

from gi import require_version
require_version('GLib', '2.0')
require_version('Gdk', '3.0')
require_version('Gtk', '3.0')
from gi.repository import GLib, Gdk, Gtk


def create_dialog(parent, title, mainloop):
    window = Gtk.Dialog()
    window.connect("response", lambda *_: mainloop.quit())
    window.set_transient_for(parent)
    window.set_title(title)
    window.set_role('dialog')
    window.set_modal(False)
    window.set_type_hint(Gdk.WindowTypeHint.DIALOG)
    window.set_keep_above(True)
    window.add_buttons(Gtk.STOCK_OK, Gtk.ResponseType.OK)
    window.get_content_area().add(Gtk.Label(label=title))
    window.show_all()
    return window


def main():
    if not Gtk.init_check(None)[0]:
        raise RuntimeError("Failed to initialize GTK!")

    mainloop = GLib.MainLoop()

    win0 = None
    win1 = None
    win2 = Gtk.Window(title="WIN 222")
    win3 = Gtk.Window(title="WIN 333")
    win3.show()

    diag0 = create_dialog(win0, "DIAG 00000", mainloop)
    diag1 = create_dialog(win1, "DIAG 11111", mainloop)
    diag2 = create_dialog(win2, "DIAG 22222", mainloop)
    diag3 = create_dialog(win3, "DIAG 33333", mainloop)

    diag1.set_resizable(False)

    diag0.present()
    diag1.present()
    diag2.present()
    diag3.present()

    if False:
        # Don't do this, it crashes sway (segfault):
        win3.hide()

    mainloop.run()


if __name__ == '__main__':
    main()

The example creates 4 dialogs which are all floated in awesome-wm. Sway displays them as follows:

  1. without parent, resizable (like in udiskie and zenity) → tiled
  2. without parent, non-resizable → floats
  3. with hidden parent→ tiled
  4. with shown parent → floats

This is with the following sway config:

for_window [window_type="dialog"]            floating enable
for_window [window_role="dialog"]            floating enable

Surprisingly, not even the rule for window_role helps, even though it is set explicitly. According to the answhere here, this might be a general lack in wayland.

So far, I see no way to fix this in udiskie. I think it's a problem with either wayland, sway, or GTK. Not sure who gets the credit. I'm of course open to suggestions, if anyone finds an application-level solution.

For the record, I believe this seems to be a common issue. At least I found several sway configs that match many applications explicitly, see e.g. here, here, or here.

coldfix avatar Jan 01 '21 15:01 coldfix

Thank you for investigating this so thoroughly. Judging from your references, I probably could (should) have found that out by myself. It is a bit frustrating to see that wayland is still so rough around the edges after all the time, but that's another topic. This is clearly not a problem with udiskie. I'll simply leave the for_window line in my config.

EricPraline avatar Jan 01 '21 17:01 EricPraline

I'll leave this issue open for now, since it's not solved. Even though there is currently no apparent fix.

coldfix avatar Jan 27 '21 21:01 coldfix

For the record, I believe this seems to be a common issue. At least I found several sway configs that match many applications explicitly, see e.g. here, here, or here.

Generally the way to fix this is to run swaymsg -t get_tree then identify the window.

The open dialog:

{
  "floating_nodes": [
    {
      "name": "Open disc image",
      "window": null,
      "nodes": [],
      "floating_nodes": [],
      "focus": [],
      "fullscreen_mode": 0,
      "sticky": false,
      "pid": 4568,
      "app_id": "udiskie",
      "visible": true,
      "max_render_time": 0,
      "shell": "xdg_shell",
      "inhibit_idle": false,
      "idle_inhibitors": {
        "user": "fullscreen",
        "application": "none"
      }
    }
  ]
}

and the password dialog:

{
  "floating_nodes": [
    {
      "name": "udiskie",
      "window": null,
      "nodes": [],
      "floating_nodes": [],
      "focus": [],
      "fullscreen_mode": 0,
      "sticky": false,
      "pid": 4568,
      "app_id": "udiskie",
      "visible": false,
      "max_render_time": 0,
      "shell": "xdg_shell",
      "inhibit_idle": false,
      "idle_inhibitors": {
        "user": "fullscreen",
        "application": "none"
      }
    }
  ]
}

We can then create some rules in our sway config:

for_window [title="Open disc image" app_id="udiskie"] {
    floating enable
    resize set width 1200px
    resize set height 800px
}

for_window [title="udiskie" app_id="udiskie"] {
    floating enable
}

dngray avatar Feb 02 '22 03:02 dngray