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

feat: Cross-platform popup windows #2693

Closed

Conversation

notgull
Copy link
Member

@notgull notgull commented Feb 23, 2023

  • Tested on all platforms changed
  • Added an entry to CHANGELOG.md if knowledge of this change could be valuable to users
  • Updated documentation to reflect any user-facing changes, including notes of platform-specific behavior
  • Created or updated an example program if it would help users understand this functionality
  • Updated feature matrix, if new features were added or implemented

This PR adds a cross-platform way of creating popup windows; basically, what with_owner_window does for Windows, but cross platform. This should allow us to create popup windows on all platforms that support them.

I've only implemented Windows and X11 for now, since those are the platforms I'm most familiar with. We should also be able to add some of the other platforms.

Blocked on #2614

@madsmtm madsmtm added DS - windows DS - x11 S - api Design and usability S - platform parity Unintended platform differences labels Feb 23, 2023
@notgull notgull mentioned this pull request May 2, 2023

if let Some(owner) = owner {
unsafe {
(xconn.xlib.XSetTransientForHint)(xconn.display, window.xwindow, owner);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I understand, for right click menus, drop downs, etc. override_redirect Windows are typically used on X11. This is what GdkPopover uses. GDK separately has a method that sets WM_TRANSIENT_FOR: https://docs.gtk.org/gdk4/method.Toplevel.set_transient_for.html. On Wayland that corresponds to https://wayland.app/protocols/xdg-shell#xdg_toplevel:request:set_parent.

Setting the override_redirect attribute True for a window allows a window to be mapped, moved, resized, or its border width changed without the intervention of the window manager. This override is usually done for menus that are frequently mapped and almost immediately unmapped again.

Under properly designed window managers, there is a property you can set to tell the window manager to allow a window to pop up with minimal intervention (XA_WM_TRANSIENT_FOR). This is used for dialog boxes, as described in 12.3.1.4.6 Transient Window Field.

https://www.oreilly.com/library/view/xlib-programming-manual/9780596806187/ch04s03.html

So in Wayland and X, a "popup" and a "transient toplevel" are different things.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for telling me! I'll rework this PR once #2614 lands and I can more easily mold the X11 backend into something that is more conducive to this

@ids1024
Copy link
Member

ids1024 commented May 2, 2023

So using GDK4's terminology (which is based on X11 and Wayland terminology), "popup surfaces" and "transient toplevels" are both useful features, but separate.

I'm not so sure what naming should be used in the winit APIs. It's not really possible to use terms like "menu" and "popup" without people interpreting them in different ways... Maybe "parent" window, as Wayland calls it, would make sense here. That may make more sense than "transient_for" or "owner". But then, "parent" means something different with X11 and Windows, where child windows are contained within the bounds of their parent...

Anyway, a transient toplevel may have window decoration, appear in the taskbar/etc, and otherwise behave mostly like a window without a parent. A popup is different, and on Wayland has to be positioned relative to its parent using xdg_positioner. So while on other platforms a "popup" might be similar to a toplevel but with a couple extra properties set, and the window placed in a particular position, on Wayland popups need a more specialized API. Which probably should be separate from the Window type.

@notgull notgull force-pushed the popup-windows-win32-x11 branch from e80a5bf to 6cc3abd Compare July 21, 2023 23:20
@notgull notgull force-pushed the popup-windows-win32-x11 branch from 6cc3abd to 92630d6 Compare July 21, 2023 23:21
@notgull notgull marked this pull request as ready for review July 21, 2023 23:21
@notgull
Copy link
Member Author

notgull commented Jul 21, 2023

This is no longer blocked on x11rb support.

@kchibisov
Copy link
Member

While I do want popups inside the winit, I don't think this is the way as of now. I'm thinking of having a separate type and we'd need to put more research into it, which I can't really now.

The thing is that popup is not really a regular window in the end on at least Wayland, and we really want have a way to deal with not really a window, but you can still draw into it type of things.

@notgull
Copy link
Member Author

notgull commented Jul 22, 2023

While I do want popups inside the winit, I don't think this is the way as of now. I'm thinking of having a separate type and we'd need to put more research into it, which I can't really now.

I see, sounds good for now. I'll close until we can decide on a better API.

@notgull notgull closed this Jul 22, 2023
@notgull notgull deleted the popup-windows-win32-x11 branch July 22, 2023 15:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DS - windows DS - x11 S - api Design and usability S - platform parity Unintended platform differences
Development

Successfully merging this pull request may close these issues.

4 participants