Skip to content

Commit

Permalink
Add x11 window type settings to viewport builder (#4175)
Browse files Browse the repository at this point in the history
Not sure about the api, currently I've mapped the whole XWindowType
enum, but maybe there's something more sensible to do?

* Closes <#4150>

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
  • Loading branch information
psethwick and emilk authored Mar 21, 2024
1 parent 365d035 commit 2c9c5f0
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 0 deletions.
27 changes: 27 additions & 0 deletions crates/egui-winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1540,6 +1540,9 @@ pub fn create_winit_window_builder<T>(
// wayland:
app_id: _app_id,

// x11
window_type: _window_type,

mouse_passthrough: _, // handled in `apply_viewport_builder_to_window`
} = viewport_builder;

Expand Down Expand Up @@ -1612,6 +1615,30 @@ pub fn create_winit_window_builder<T>(
window_builder = window_builder.with_name(app_id, "");
}

#[cfg(all(feature = "x11", target_os = "linux"))]
{
if let Some(window_type) = _window_type {
use winit::platform::x11::WindowBuilderExtX11 as _;
use winit::platform::x11::XWindowType;
window_builder = window_builder.with_x11_window_type(vec![match window_type {
egui::X11WindowType::Normal => XWindowType::Normal,
egui::X11WindowType::Utility => XWindowType::Utility,
egui::X11WindowType::Dock => XWindowType::Dock,
egui::X11WindowType::Desktop => XWindowType::Desktop,
egui::X11WindowType::Toolbar => XWindowType::Toolbar,
egui::X11WindowType::Menu => XWindowType::Menu,
egui::X11WindowType::Splash => XWindowType::Splash,
egui::X11WindowType::Dialog => XWindowType::Dialog,
egui::X11WindowType::DropdownMenu => XWindowType::DropdownMenu,
egui::X11WindowType::PopupMenu => XWindowType::PopupMenu,
egui::X11WindowType::Tooltip => XWindowType::Tooltip,
egui::X11WindowType::Notification => XWindowType::Notification,
egui::X11WindowType::Combo => XWindowType::Combo,
egui::X11WindowType::Dnd => XWindowType::Dnd,
}]);
}
}

#[cfg(target_os = "windows")]
{
use winit::platform::windows::WindowBuilderExtWindows as _;
Expand Down
73 changes: 73 additions & 0 deletions crates/egui/src/viewport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,9 @@ pub struct ViewportBuilder {
pub window_level: Option<WindowLevel>,

pub mouse_passthrough: Option<bool>,

// X11
pub window_type: Option<X11WindowType>,
}

impl ViewportBuilder {
Expand Down Expand Up @@ -583,6 +586,15 @@ impl ViewportBuilder {
self
}

/// ### On X11
/// This sets the window type.
/// Maps directly to [`_NET_WM_WINDOW_TYPE`](https://specifications.freedesktop.org/wm-spec/wm-spec-1.5.html).
#[inline]
pub fn with_window_type(mut self, value: X11WindowType) -> Self {
self.window_type = Some(value);
self
}

/// Update this `ViewportBuilder` with a delta,
/// returning a list of commands and a bool indicating if the window needs to be recreated.
#[must_use]
Expand Down Expand Up @@ -613,6 +625,7 @@ impl ViewportBuilder {
window_level: new_window_level,
mouse_passthrough: new_mouse_passthrough,
taskbar: new_taskbar,
window_type: new_window_type,
} = new_vp_builder;

let mut commands = Vec::new();
Expand Down Expand Up @@ -786,6 +799,11 @@ impl ViewportBuilder {
recreate_window = true;
}

if new_window_type.is_some() && self.window_type != new_window_type {
self.window_type = new_window_type;
recreate_window = true;
}

(commands, recreate_window)
}
}
Expand All @@ -799,6 +817,61 @@ pub enum WindowLevel {
AlwaysOnTop,
}

#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum X11WindowType {
/// This is a normal, top-level window.
#[default]
Normal,

/// A desktop feature. This can include a single window containing desktop icons with the same dimensions as the
/// screen, allowing the desktop environment to have full control of the desktop, without the need for proxying
/// root window clicks.
Desktop,

/// A dock or panel feature. Typically a Window Manager would keep such windows on top of all other windows.
Dock,

/// Toolbar windows. "Torn off" from the main application.
Toolbar,

/// Pinnable menu windows. "Torn off" from the main application.
Menu,

/// A small persistent utility window, such as a palette or toolbox.
Utility,

/// The window is a splash screen displayed as an application is starting up.
Splash,

/// This is a dialog window.
Dialog,

/// A dropdown menu that usually appears when the user clicks on an item in a menu bar.
/// This property is typically used on override-redirect windows.
DropdownMenu,

/// A popup menu that usually appears when the user right clicks on an object.
/// This property is typically used on override-redirect windows.
PopupMenu,

/// A tooltip window. Usually used to show additional information when hovering over an object with the cursor.
/// This property is typically used on override-redirect windows.
Tooltip,

/// The window is a notification.
/// This property is typically used on override-redirect windows.
Notification,

/// This should be used on the windows that are popped up by combo boxes.
/// This property is typically used on override-redirect windows.
Combo,

/// This indicates the the window is being dragged.
/// This property is typically used on override-redirect windows.
Dnd,
}

#[derive(Clone, Copy, Default, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum IMEPurpose {
Expand Down

0 comments on commit 2c9c5f0

Please sign in to comment.