-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Description
This proposal addresses #159, #343, and #3506.
Definitions
The below model of surfaces, windows, etc. is heavily inspired by Wayland; though it maps well to other platforms.
Window manager
For the purpose of this design proposal, the window manager (abbreviated WM) is software that handles the positioning, compositing, and display of surfaces. This is equivalent to X11 server and window manager on X11 and the compositor on Wayland.
Surface
A surface is a rectangular buffer owned by the window manager that can be drawn to, and is usually displayed on screen in some fashion. Not all surfaces can be positioned programmatically; for some window managers this is purely by design (i.e. Wayland). Functions and properties common to most surfaces include:
- the ability to grab input (usually upon user action)
- the ability to be visually transparent or translucent
- the ability to blur their background if transparent
- the ability to be resized
- the ability to request a repaint
Generally, window managers support different roles for surfaces, which govern their lifetime and purpose. Most window managers can define the roles of window, popup, and subview.
Platform equivalents:
- Windows:
HWND
- MacOS:
NSView
? - X11:
XID
- Wayland:
wl_surface
Window
A window is a long-lived surface that can be positioned by the user. They can also be stacked or tiled as the window manager deems appropriate. Functions and properties unique to windows include:
- decorations and/or frame
- the ability to be modal to another window
- the ability to trigger the system move/resize handles
- the ability to be repositioned (on some WMs: Windows, macOS, X11 (not advised))
- an icon (on some WMs: Windows, macOS, X11)
- a window class (on some WMs: X11, Wayland)
- the ability to request activation
Platform equivalents:
- Windows:
WS_OVERLAPPEDWINDOW
- MacOS:
NSWindow
- X11: ??
- Wayland:
xdg_toplevel
Popup
A popup is a short-lived surface bound to a window that disappears when unfocused. They are generally used to implement context menus and tooltips. Functions and properties unique to popups include:
-
the ability to be repositioned
-
the ability to steal focus from its parent window
-
Windows:
WS_POPUPWINDOW
-
MacOS:
NSWindow
, with additional settings:[window setDecorated:NO]; [window setExcludedFromWindowsMenu:YES]; [window setLevel:NSPopUpMenuWindowLevel];
-
X11: override-redirect/save-under window, no decorations
-
Wayland:
xdg_popup
Subview
A subview is a long-lived surface bound to some other surface, be it a window, popup, or even another subview. They are generally clipped to their parent surface. Functions and properties unique to subviews include:
- the ability to be repositioned
- the ability to be restacked relative to other subviews
Platform equivalents:
- Windows:
WS_CHILD
- MacOS: Subclass
NSView
- X11: just parent the window and don't request decoration
- Wayland:
wl_subsurface
, usewp_viewporter
protocol to clip output
Structure
The existing Window
trait should be split into two separate traits: Surface
representing the common functionality, and Window
representing functionality specific to top-level windows. This opens up room for traits like Popup
or Subview
. The existing WindowId
class would be renamed to SurfaceId
for consistency, though it could exist as a deprecated alias during a transition period.
The trait hierarchy would look something like this:
trait Surface: HasWindowHandle {
fn id() -> SurfaceId
// Downcast to the corresponding "common" role, if it is one
fn as_role(&self) -> Option<SurfaceRole>;
fn as_role_mut(&mut self) -> Option<SurfaceRoleMut>;
// Upcast to Surface
fn as_surface(&self) -> &dyn Surface;
fn as_surface_mut(&mut self) -> &dyn mut Surface;
}
trait Window: Surface {
// window operations
}
trait Popup: Surface {
// popup operations
}
trait Subview: Surface {
// subview operations
}
enum SurfaceRole {
Window(&dyn Window),
Popup(&dyn Popup),
Subview(&dyn Subview),
}
enum SurfaceRoleMut {
Window(&dyn mut Window),
Popup(&dyn mut Popup),
Subview(&dyn mut Subview),
}
Ideally, the Surface::as_surface
/Surface::as_surface_mut
are obsoleted once trait upcasting is stabilized.
Event handling
- Subviews cannot receive keyboard focus on Wayland.
- Subviews will not receive keyboard focus by default, instead passing it to their parent window.
- On MacOS and X11, subviews can automatically bubble events up to their ancestors, whereas on Windows and Wayland, they don't.
- Subviews will handle all pointer events they receive unless they have explicitly been made invisible to cursor hit test. Further testing will be needed to ensure consistency between platforms.
Changelog
- Added plan for event bubbling
- Specified how subviews will catch events
Relevant platforms
Windows, macOS, Wayland, X11