From d7b783877fb90e697619953e71e8b7c3519545f2 Mon Sep 17 00:00:00 2001 From: Ottatop Date: Wed, 13 Dec 2023 20:07:19 -0600 Subject: [PATCH] Merge override redirect windows into main window vec I previously stuck all X11 override redirect windows in their own stack which is really lazy. Still need to make it so child OR windows will render above their parents, even when fullscreen. --- api/lua/example_config.lua | 70 +++++++++------------ api/lua/test_config.lua | 82 ++++++++++-------------- src/backend/udev.rs | 4 -- src/backend/winit.rs | 1 - src/focus.rs | 8 ++- src/grab/resize_grab.rs | 2 + src/handlers/xwayland.rs | 11 +--- src/input.rs | 7 ++- src/layout.rs | 16 ++++- src/render.rs | 14 +++-- src/state.rs | 4 +- src/state/api_handlers.rs | 5 +- src/window.rs | 126 ++++++++++++++++++++++++++----------- src/window/window_state.rs | 4 ++ 14 files changed, 198 insertions(+), 156 deletions(-) diff --git a/api/lua/example_config.lua b/api/lua/example_config.lua index f39ba86..b420ee1 100644 --- a/api/lua/example_config.lua +++ b/api/lua/example_config.lua @@ -1,5 +1,4 @@ -- SPDX-License-Identifier: MIT - -- Just like in Awesome, if you want access to Luarocks packages, this needs to be called. -- NOTE: The loader doesn't load from the local Luarocks directory (probably in ~/.luarocks), -- | so if you have any rocks installed with --local, @@ -28,8 +27,6 @@ require("pinnacle").setup(function(pinnacle) local terminal = "alacritty" - process.set_env("MOZ_ENABLE_WAYLAND", "1") - -- Outputs ----------------------------------------------------------------------- -- You can set your own monitor layout as I have done below for my monitors. -- @@ -46,55 +43,49 @@ require("pinnacle").setup(function(pinnacle) -- Mousebinds -------------------------------------------------------------------- - input.mousebind({ "Ctrl" }, buttons.left, "Press", function() - window.begin_move(buttons.left) - end) - input.mousebind({ "Ctrl" }, buttons.right, "Press", function() - window.begin_resize(buttons.right) - end) + input.mousebind({"Ctrl"}, buttons.left, "Press", + function() window.begin_move(buttons.left) end) + input.mousebind({"Ctrl"}, buttons.right, "Press", + function() window.begin_resize(buttons.right) end) -- Keybinds ---------------------------------------------------------------------- -- mod_key + Alt + q quits the compositor - input.keybind({ mod_key, "Alt" }, keys.q, pinnacle.quit) + input.keybind({mod_key, "Alt"}, keys.q, pinnacle.quit) -- mod_key + Alt + c closes the focused window - input.keybind({ mod_key, "Alt" }, keys.c, function() - window.get_focused():close() - end) + input.keybind({mod_key, "Alt"}, keys.c, + function() window.get_focused():close() end) -- mod_key + return spawns a terminal - input.keybind({ mod_key }, keys.Return, function() + input.keybind({mod_key}, keys.Return, function() process.spawn(terminal, function(stdout, stderr, exit_code, exit_msg) -- do something with the output here end) end) -- mod_key + Alt + Space toggle floating on the focused window - input.keybind({ mod_key, "Alt" }, keys.space, function() - window.get_focused():toggle_floating() - end) + input.keybind({mod_key, "Alt"}, keys.space, + function() window.get_focused():toggle_floating() end) -- mod_key + f toggles fullscreen on the focused window - input.keybind({ mod_key }, keys.f, function() - window.get_focused():toggle_fullscreen() - end) + input.keybind({mod_key}, keys.f, + function() window.get_focused():toggle_fullscreen() end) -- mod_key + m toggles maximized on the focused window - input.keybind({ mod_key }, keys.m, function() - window.get_focused():toggle_maximized() - end) + input.keybind({mod_key}, keys.m, + function() window.get_focused():toggle_maximized() end) -- Tags --------------------------------------------------------------------------- - local tags = { "1", "2", "3", "4", "5" } + local tags = {"1", "2", "3", "4", "5"} output.connect_for_all(function(op) -- Add tags 1, 2, 3, 4 and 5 on all monitors, and toggle tag 1 active by default op:add_tags(tags) -- Same as tag.add(op, "1", "2", "3", "4", "5") - tag.toggle({ name = "1", output = op }) + tag.toggle({name = "1", output = op}) -- Window rules -- Add your own window rules here. Below is an example. @@ -121,35 +112,30 @@ require("pinnacle").setup(function(pinnacle) -- Create a layout cycler to cycle your tag layouts. This will store which layout each tag has -- and change to the next or previous one in the array when the respective function is called. local layout_cycler = tag.layout_cycler({ - "MasterStack", - "Dwindle", - "Spiral", - "CornerTopLeft", - "CornerTopRight", - "CornerBottomLeft", - "CornerBottomRight", + "MasterStack", "Dwindle", "Spiral", "CornerTopLeft", "CornerTopRight", + "CornerBottomLeft", "CornerBottomRight" }) - input.keybind({ mod_key }, keys.space, layout_cycler.next) - input.keybind({ mod_key, "Shift" }, keys.space, layout_cycler.prev) + input.keybind({mod_key}, keys.space, layout_cycler.next) + input.keybind({mod_key, "Shift"}, keys.space, layout_cycler.prev) -- Tag manipulation for _, tag_name in pairs(tags) do -- mod_key + 1-5 switches tags - input.keybind({ mod_key }, tag_name, function() - tag.switch_to(tag_name) - end) + input.keybind({mod_key}, tag_name, + function() tag.switch_to(tag_name) end) -- mod_key + Shift + 1-5 toggles tags - input.keybind({ mod_key, "Shift" }, tag_name, function() - tag.toggle(tag_name) - end) + input.keybind({mod_key, "Shift"}, tag_name, + function() tag.toggle(tag_name) end) -- mod_key + Alt + 1-5 moves windows to tags - input.keybind({ mod_key, "Alt" }, tag_name, function() + input.keybind({mod_key, "Alt"}, tag_name, + function() window:get_focused():move_to_tag(tag_name) end) -- mod_key + Shift + Alt + 1-5 toggles tags on windows - input.keybind({ mod_key, "Shift", "Alt" }, tag_name, function() + input.keybind({mod_key, "Shift", "Alt"}, tag_name, + function() window.get_focused():toggle_tag(tag_name) end) end diff --git a/api/lua/test_config.lua b/api/lua/test_config.lua index ac0b956..9a1bdea 100644 --- a/api/lua/test_config.lua +++ b/api/lua/test_config.lua @@ -1,5 +1,4 @@ -- SPDX-License-Identifier: MIT - -- Just like in Awesome, if you want access to Luarocks packages, this needs to be called. -- NOTE: The loader doesn't load from the local Luarocks directory (probably in ~/.luarocks), -- | so if you have any rocks installed with --local, @@ -28,8 +27,6 @@ require("pinnacle").setup(function(pinnacle) local terminal = "alacritty" - process.set_env("MOZ_ENABLE_WAYLAND", "1") - -- Outputs ----------------------------------------------------------------------- -- You can set your own monitor layout as I have done below for my monitors. -- @@ -46,74 +43,64 @@ require("pinnacle").setup(function(pinnacle) -- Mousebinds -------------------------------------------------------------------- - input.mousebind({ "Ctrl" }, buttons.left, "Press", function() - window.begin_move(buttons.left) - end) - input.mousebind({ "Ctrl" }, buttons.right, "Press", function() - window.begin_resize(buttons.right) - end) + input.mousebind({"Ctrl"}, buttons.left, "Press", + function() window.begin_move(buttons.left) end) + input.mousebind({"Ctrl"}, buttons.right, "Press", + function() window.begin_resize(buttons.right) end) -- Keybinds ---------------------------------------------------------------------- - input.keybind({ mod_key }, keys.t, function() - window.get_focused():set_size({ w = 500, h = 500 }) + input.keybind({mod_key}, keys.t, function() + window.get_focused():set_size({w = 500, h = 500}) end) -- mod_key + Alt + q quits the compositor - input.keybind({ mod_key, "Alt" }, keys.q, pinnacle.quit) + input.keybind({mod_key, "Alt"}, keys.q, pinnacle.quit) -- mod_key + Alt + c closes the focused window - input.keybind({ mod_key, "Alt" }, keys.c, function() + input.keybind({mod_key, "Alt"}, keys.c, function() -- The commented out line may crash the config process if you have no windows open. -- There is no nil warning here due to limitations in Lua LS type checking, so check for nil as shown below. -- window.get_focused():close() local win = window.get_focused() - if win ~= nil then - win:close() - end + if win ~= nil then win:close() end end) -- mod_key + return spawns a terminal - input.keybind({ mod_key }, keys.Return, function() + input.keybind({mod_key}, keys.Return, function() process.spawn(terminal, function(stdout, stderr, exit_code, exit_msg) -- do something with the output here end) end) -- mod_key + Alt + Space toggle floating on the focused window - input.keybind({ mod_key, "Alt" }, keys.space, function() + input.keybind({mod_key, "Alt"}, keys.space, function() local win = window.get_focused() - if win ~= nil then - win:toggle_floating() - end + if win ~= nil then win:toggle_floating() end end) -- mod_key + f toggles fullscreen on the focused window - input.keybind({ mod_key }, keys.f, function() + input.keybind({mod_key}, keys.f, function() local win = window.get_focused() - if win ~= nil then - win:toggle_fullscreen() - end + if win ~= nil then win:toggle_fullscreen() end end) -- mod_key + m toggles maximized on the focused window - input.keybind({ mod_key }, keys.m, function() + input.keybind({mod_key}, keys.m, function() local win = window.get_focused() - if win ~= nil then - win:toggle_maximized() - end + if win ~= nil then win:toggle_maximized() end end) -- Tags --------------------------------------------------------------------------- - local tags = { "1", "2", "3", "4", "5" } + local tags = {"1", "2", "3", "4", "5"} output.connect_for_all(function(op) -- Add tags 1, 2, 3, 4 and 5 on all monitors, and toggle tag 1 active by default op:add_tags(tags) -- Same as tag.add(op, "1", "2", "3", "4", "5") - tag.toggle({ name = "1", output = op }) + tag.toggle({name = "1", output = op}) -- Window rules -- Add your own window rules here. Below is an example. @@ -140,36 +127,31 @@ require("pinnacle").setup(function(pinnacle) -- Create a layout cycler to cycle your tag layouts. This will store which layout each tag has -- and change to the next or previous one in the array when the respective function is called. local layout_cycler = tag.layout_cycler({ - "MasterStack", - "Dwindle", - "Spiral", - "CornerTopLeft", - "CornerTopRight", - "CornerBottomLeft", - "CornerBottomRight", + "MasterStack", "Dwindle", "Spiral", "CornerTopLeft", "CornerTopRight", + "CornerBottomLeft", "CornerBottomRight" }) - input.keybind({ mod_key }, keys.space, layout_cycler.next) - input.keybind({ mod_key, "Shift" }, keys.space, layout_cycler.prev) + input.keybind({mod_key}, keys.space, layout_cycler.next) + input.keybind({mod_key, "Shift"}, keys.space, layout_cycler.prev) -- Tag manipulation for _, tag_name in pairs(tags) do -- mod_key + 1-5 switches tags - input.keybind({ mod_key }, tag_name, function() - tag.switch_to(tag_name) - end) + input.keybind({mod_key}, tag_name, + function() tag.switch_to(tag_name) end) -- mod_key + Shift + 1-5 toggles tags - input.keybind({ mod_key, "Shift" }, tag_name, function() - tag.toggle(tag_name) - end) + input.keybind({mod_key, "Shift"}, tag_name, + function() tag.toggle(tag_name) end) -- mod_key + Alt + 1-5 moves windows to tags - input.keybind({ mod_key, "Alt" }, tag_name, function() - local _ = window.get_focused() and window:get_focused():move_to_tag(tag_name) + input.keybind({mod_key, "Alt"}, tag_name, function() + local _ = window.get_focused() and + window:get_focused():move_to_tag(tag_name) end) -- mod_key + Shift + Alt + 1-5 toggles tags on windows - input.keybind({ mod_key, "Shift", "Alt" }, tag_name, function() - local _ = window.get_focused() and window.get_focused():toggle_tag(tag_name) + input.keybind({mod_key, "Shift", "Alt"}, tag_name, function() + local _ = window.get_focused() and + window.get_focused():toggle_tag(tag_name) end) end end) diff --git a/src/backend/udev.rs b/src/backend/udev.rs index 2329ff2..7acc858 100644 --- a/src/backend/udev.rs +++ b/src/backend/udev.rs @@ -67,7 +67,6 @@ use smithay::{ }, utils::{Clock, DeviceFd, IsAlive, Logical, Monotonic, Point, Transform}, wayland::dmabuf::{DmabufFeedback, DmabufFeedbackBuilder, DmabufGlobal, DmabufState}, - xwayland::X11Surface, }; use smithay_drm_extras::{ drm_scanner::{DrmScanEvent, DrmScanner}, @@ -1316,7 +1315,6 @@ impl State { output, &self.space, &windows, - &self.override_redirect_windows, self.dnd_icon.as_ref(), &mut self.cursor_status, &pointer_image, @@ -1357,7 +1355,6 @@ fn render_surface( space: &Space, windows: &[WindowElement], - override_redirect_windows: &[X11Surface], dnd_icon: Option<&WlSurface>, cursor_status: &mut CursorImageStatus, @@ -1428,7 +1425,6 @@ fn render_surface( renderer, space, windows, - override_redirect_windows, pointer_location, cursor_status, dnd_icon, diff --git a/src/backend/winit.rs b/src/backend/winit.rs index f2b246d..6a9b1c7 100644 --- a/src/backend/winit.rs +++ b/src/backend/winit.rs @@ -335,7 +335,6 @@ impl State { winit.backend.renderer(), &self.space, &self.focus_state.focus_stack, - &self.override_redirect_windows, self.pointer_location, &mut self.cursor_status, self.dnd_icon.as_ref(), diff --git a/src/focus.rs b/src/focus.rs index a12b07e..61c1e98 100644 --- a/src/focus.rs +++ b/src/focus.rs @@ -39,7 +39,7 @@ impl State { .any(|win_tag| output_tags.iter().any(|op_tag| win_tag == op_tag)) }); - windows.next().cloned() + windows.find(|win| !win.is_x11_override_redirect()).cloned() } /// Update the focus. This will raise the current focus and activate it, @@ -48,6 +48,8 @@ impl State { let current_focus = self.focused_window(output); if let Some(win) = ¤t_focus { + assert!(!win.is_x11_override_redirect()); + self.space.raise_element(win, true); if let WindowElement::Wayland(w) = win { w.toplevel().send_configure(); @@ -363,7 +365,9 @@ impl WaylandFocus for FocusTarget { ) -> bool { match self { FocusTarget::Window(WindowElement::Wayland(window)) => window.same_client_as(object_id), - FocusTarget::Window(WindowElement::X11(surface)) => surface.same_client_as(object_id), + FocusTarget::Window( + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface), + ) => surface.same_client_as(object_id), FocusTarget::Popup(popup) => popup.wl_surface().id().same_client_as(object_id), FocusTarget::LayerSurface(surf) => surf.wl_surface().id().same_client_as(object_id), } diff --git a/src/grab/resize_grab.rs b/src/grab/resize_grab.rs index 2780d37..563d02a 100644 --- a/src/grab/resize_grab.rs +++ b/src/grab/resize_grab.rs @@ -178,6 +178,7 @@ impl PointerGrab for ResizeSurfaceGrab { .configure(Rectangle::from_loc_and_size(loc, self.last_window_size)) .expect("failed to configure x11 win"); } + WindowElement::X11OverrideRedirect(_) => (), } } @@ -233,6 +234,7 @@ impl PointerGrab for ResizeSurfaceGrab { }; }); } + WindowElement::X11OverrideRedirect(_) => (), } } } diff --git a/src/handlers/xwayland.rs b/src/handlers/xwayland.rs index 85b0ae2..58685e5 100644 --- a/src/handlers/xwayland.rs +++ b/src/handlers/xwayland.rs @@ -163,9 +163,9 @@ impl XwmHandler for CalloopData { let loc = window.geometry().loc; tracing::debug!("or win geo is {:?}", window.geometry()); - self.state.override_redirect_windows.push(window.clone()); + let window = WindowElement::X11OverrideRedirect(window); + self.state.windows.push(window.clone()); - let window = WindowElement::X11(window); window.with_state(|state| { state.tags = match ( &self.state.focus_state.focused_output, @@ -187,6 +187,7 @@ impl XwmHandler for CalloopData { // tracing::debug!("mapped_override_redirect_window to loc {loc:?}"); self.state.space.map_element(window.clone(), loc, true); + self.state.focus_state.set_focus(window); } fn unmapped_window(&mut self, _xwm: XwmId, window: X11Surface) { @@ -229,12 +230,6 @@ impl XwmHandler for CalloopData { } fn destroyed_window(&mut self, _xwm: XwmId, window: X11Surface) { - if window.is_override_redirect() { - self.state - .override_redirect_windows - .retain(|win| win != &window); - } - self.state.focus_state.focus_stack.retain(|win| { win.wl_surface() .is_some_and(|surf| Some(surf) != window.wl_surface()) diff --git a/src/input.rs b/src/input.rs index 52b5a4b..ef45e05 100644 --- a/src/input.rs +++ b/src/input.rs @@ -455,8 +455,10 @@ impl State { // TODO: use update_keyboard_focus from anvil - if !matches!(&focus, FocusTarget::Window(WindowElement::X11(surf)) if surf.is_override_redirect()) - { + if !matches!( + &focus, + FocusTarget::Window(WindowElement::X11OverrideRedirect(_)) + ) { keyboard.set_focus(self, Some(focus.clone()), serial); } @@ -481,6 +483,7 @@ impl State { .expect("failed to deactivate x11 win"); // INFO: do i need to configure this? } + WindowElement::X11OverrideRedirect(_) => (), }); keyboard.set_focus(self, None, serial); } diff --git a/src/layout.rs b/src/layout.rs index cb4c37c..46a4a2c 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -63,9 +63,15 @@ impl State { let (windows_on_foc_tags, mut windows_not_on_foc_tags): (Vec<_>, _) = output.with_state(|state| { let focused_tags = state.focused_tags().collect::>(); - self.windows.iter().cloned().partition(|win| { - win.with_state(|state| state.tags.iter().any(|tg| focused_tags.contains(&tg))) - }) + self.windows + .iter() + .filter(|win| !win.is_x11_override_redirect()) + .cloned() + .partition(|win| { + win.with_state(|state| { + state.tags.iter().any(|tg| focused_tags.contains(&tg)) + }) + }) }); // Don't unmap windows that aren't on `output` (that would clear all other monitors) @@ -153,6 +159,10 @@ impl State { state.loc_request_state = LocationRequestState::Idle; non_pending_wins.push((loc, window.clone())); } + WindowElement::X11OverrideRedirect(_) => { + // filtered out up there somewhere + unreachable!(); + } } } }); diff --git a/src/render.rs b/src/render.rs index b4de8c6..07535e2 100644 --- a/src/render.rs +++ b/src/render.rs @@ -28,7 +28,6 @@ use smithay::{ render_elements, utils::{IsAlive, Logical, Physical, Point, Scale}, wayland::{compositor, shell::wlr_layer}, - xwayland::X11Surface, }; use crate::{ @@ -73,7 +72,7 @@ where WindowElement::Wayland(window) => { window.render_elements(renderer, location, scale, alpha) } - WindowElement::X11(surface) => { + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { surface.render_elements(renderer, location, scale, alpha) } } @@ -181,7 +180,6 @@ pub fn generate_render_elements( renderer: &mut R, space: &Space, windows: &[WindowElement], - override_redirect_windows: &[X11Surface], pointer_location: Point, cursor_status: &mut CursorImageStatus, dnd_icon: Option<&WlSurface>, @@ -200,6 +198,12 @@ where let scale = Scale::from(output.current_scale().fractional_scale()); let mut custom_render_elements: Vec> = Vec::new(); + + let (windows, override_redirect_windows) = windows + .iter() + .cloned() + .partition::, _>(|win| !win.is_x11_override_redirect()); + // // draw input method surface if any // let rectangle = input_method.coordinates(); // let position = Point::from(( @@ -270,7 +274,7 @@ where surf.render_elements::>( renderer, space - .element_location(&WindowElement::X11(surf.clone())) + .element_location(surf) .unwrap_or((0, 0).into()) .to_physical_precise_round(scale), scale, @@ -329,7 +333,7 @@ where overlay, } = layer_render_elements(output, renderer, scale); - let window_render_elements = tag_render_elements::(windows, space, renderer, scale); + let window_render_elements = tag_render_elements::(&windows, space, renderer, scale); let mut output_render_elements = Vec::>>::new(); diff --git a/src/state.rs b/src/state.rs index e4141dd..3d95733 100644 --- a/src/state.rs +++ b/src/state.rs @@ -43,7 +43,7 @@ use smithay::{ socket::ListeningSocketSource, viewporter::ViewporterState, }, - xwayland::{X11Surface, X11Wm, XWayland, XWaylandEvent}, + xwayland::{X11Wm, XWayland, XWaylandEvent}, }; use crate::input::InputState; @@ -96,7 +96,6 @@ pub struct State { pub xwayland: XWayland, pub xwm: Option, pub xdisplay: Option, - pub override_redirect_windows: Vec, } impl State { @@ -280,7 +279,6 @@ impl State { xwayland, xwm: None, xdisplay: None, - override_redirect_windows: vec![], }) } diff --git a/src/state/api_handlers.rs b/src/state/api_handlers.rs index 0b40e18..d72a2ea 100644 --- a/src/state/api_handlers.rs +++ b/src/state/api_handlers.rs @@ -78,6 +78,7 @@ impl State { WindowElement::X11(surface) => { surface.close().expect("failed to close x11 win"); } + WindowElement::X11OverrideRedirect(_) => (), } } } @@ -503,7 +504,9 @@ impl State { (None, None) } } - WindowElement::X11(surface) => (Some(surface.class()), Some(surface.title())), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + (Some(surface.class()), Some(surface.title())) + } }); let focused = window.as_ref().and_then(|win| { let output = win.output(self)?; diff --git a/src/window.rs b/src/window.rs index efc96ef..681c5ee 100644 --- a/src/window.rs +++ b/src/window.rs @@ -45,6 +45,7 @@ pub mod window_state; pub enum WindowElement { Wayland(Window), X11(X11Surface), + X11OverrideRedirect(X11Surface), } impl WindowElement { @@ -55,9 +56,11 @@ impl WindowElement { ) -> Option<(WlSurface, Point)> { match self { WindowElement::Wayland(window) => window.surface_under(location, window_type), - WindowElement::X11(surface) => surface.wl_surface().and_then(|wl_surf| { - under_from_surface_tree(&wl_surf, location, (0, 0), window_type) - }), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + surface.wl_surface().and_then(|wl_surf| { + under_from_surface_tree(&wl_surf, location, (0, 0), window_type) + }) + } } } @@ -67,7 +70,7 @@ impl WindowElement { { match self { WindowElement::Wayland(window) => window.with_surfaces(processor), - WindowElement::X11(surface) => { + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { if let Some(surface) = surface.wl_surface() { with_surfaces_surface_tree(&surface, processor); } @@ -89,7 +92,7 @@ impl WindowElement { WindowElement::Wayland(window) => { window.send_frame(output, time, throttle, primary_scan_out_output) } - WindowElement::X11(surface) => { + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { if let Some(surface) = surface.wl_surface() { send_frames_surface_tree( &surface, @@ -120,7 +123,7 @@ impl WindowElement { select_dmabuf_feedback, ); } - WindowElement::X11(surface) => { + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { if let Some(surface) = surface.wl_surface() { send_dmabuf_feedback_surface_tree( &surface, @@ -150,7 +153,7 @@ impl WindowElement { presentation_feedback_flags, ); } - WindowElement::X11(surface) => { + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { if let Some(surface) = surface.wl_surface() { take_presentation_feedback_surface_tree( &surface, @@ -166,14 +169,18 @@ impl WindowElement { pub fn wl_surface(&self) -> Option { match self { WindowElement::Wayland(window) => window.wl_surface(), - WindowElement::X11(surface) => surface.wl_surface(), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + surface.wl_surface() + } } } pub fn user_data(&self) -> &UserDataMap { match self { WindowElement::Wayland(window) => window.user_data(), - WindowElement::X11(surface) => surface.user_data(), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + surface.user_data() + } } } @@ -191,10 +198,13 @@ impl WindowElement { state.size = Some(new_geo.size); }); } - WindowElement::X11(surface) => { - surface - .configure(new_geo) - .expect("failed to configure x11 win"); + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + // TODO: maybe move this check elsewhere idk + if !surface.is_override_redirect() { + surface + .configure(new_geo) + .expect("failed to configure x11 win"); + } } } self.with_state(|state| { @@ -216,7 +226,9 @@ impl WindowElement { .clone() }) } - WindowElement::X11(surface) => Some(surface.class()), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + Some(surface.class()) + } } } @@ -234,7 +246,9 @@ impl WindowElement { .clone() }) } - WindowElement::X11(surface) => Some(surface.title()), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + Some(surface.title()) + } } } @@ -277,13 +291,23 @@ impl WindowElement { pub fn is_x11(&self) -> bool { matches!(self, Self::X11(..)) } + + /// Returns `true` if the window element is [`X11OverrideRedirect`]. + /// + /// [`X11OverrideRedirect`]: WindowElement::X11OverrideRedirect + #[must_use] + pub fn is_x11_override_redirect(&self) -> bool { + matches!(self, Self::X11OverrideRedirect(..)) + } } impl IsAlive for WindowElement { fn alive(&self) -> bool { match self { WindowElement::Wayland(window) => window.alive(), - WindowElement::X11(surface) => surface.alive(), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + surface.alive() + } } } } @@ -292,7 +316,9 @@ impl PointerTarget for WindowElement { fn frame(&self, seat: &Seat, data: &mut State) { match self { WindowElement::Wayland(window) => window.frame(seat, data), - WindowElement::X11(surface) => surface.frame(seat, data), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + surface.frame(seat, data) + } } } @@ -300,7 +326,9 @@ impl PointerTarget for WindowElement { // TODO: ssd match self { WindowElement::Wayland(window) => PointerTarget::enter(window, seat, data, event), - WindowElement::X11(surface) => PointerTarget::enter(surface, seat, data, event), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + PointerTarget::enter(surface, seat, data, event) + } } } @@ -308,7 +336,9 @@ impl PointerTarget for WindowElement { // TODO: ssd match self { WindowElement::Wayland(window) => PointerTarget::motion(window, seat, data, event), - WindowElement::X11(surface) => PointerTarget::motion(surface, seat, data, event), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + PointerTarget::motion(surface, seat, data, event) + } } } @@ -323,7 +353,7 @@ impl PointerTarget for WindowElement { WindowElement::Wayland(window) => { PointerTarget::relative_motion(window, seat, data, event); } - WindowElement::X11(surface) => { + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { PointerTarget::relative_motion(surface, seat, data, event); } } @@ -338,7 +368,9 @@ impl PointerTarget for WindowElement { // TODO: ssd match self { WindowElement::Wayland(window) => PointerTarget::button(window, seat, data, event), - WindowElement::X11(surface) => PointerTarget::button(surface, seat, data, event), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + PointerTarget::button(surface, seat, data, event) + } } } @@ -346,7 +378,9 @@ impl PointerTarget for WindowElement { // TODO: ssd match self { WindowElement::Wayland(window) => PointerTarget::axis(window, seat, data, frame), - WindowElement::X11(surface) => PointerTarget::axis(surface, seat, data, frame), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + PointerTarget::axis(surface, seat, data, frame) + } } } @@ -356,7 +390,9 @@ impl PointerTarget for WindowElement { WindowElement::Wayland(window) => { PointerTarget::leave(window, seat, data, serial, time); } - WindowElement::X11(surface) => PointerTarget::leave(surface, seat, data, serial, time), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + PointerTarget::leave(surface, seat, data, serial, time) + } } } @@ -445,14 +481,18 @@ impl KeyboardTarget for WindowElement { WindowElement::Wayland(window) => { KeyboardTarget::enter(window, seat, data, keys, serial); } - WindowElement::X11(surface) => KeyboardTarget::enter(surface, seat, data, keys, serial), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + KeyboardTarget::enter(surface, seat, data, keys, serial) + } } } fn leave(&self, seat: &Seat, data: &mut State, serial: Serial) { match self { WindowElement::Wayland(window) => KeyboardTarget::leave(window, seat, data, serial), - WindowElement::X11(surface) => KeyboardTarget::leave(surface, seat, data, serial), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + KeyboardTarget::leave(surface, seat, data, serial) + } } } @@ -469,7 +509,7 @@ impl KeyboardTarget for WindowElement { WindowElement::Wayland(window) => { KeyboardTarget::key(window, seat, data, key, state, serial, time); } - WindowElement::X11(surface) => { + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { KeyboardTarget::key(surface, seat, data, key, state, serial, time); } } @@ -486,7 +526,7 @@ impl KeyboardTarget for WindowElement { WindowElement::Wayland(window) => { KeyboardTarget::modifiers(window, seat, data, modifiers, serial); } - WindowElement::X11(surface) => { + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { KeyboardTarget::modifiers(surface, seat, data, modifiers, serial); } } @@ -498,7 +538,9 @@ impl SpaceElement for WindowElement { // TODO: ssd match self { WindowElement::Wayland(window) => SpaceElement::geometry(window), - WindowElement::X11(surface) => SpaceElement::geometry(surface), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + SpaceElement::geometry(surface) + } } } @@ -506,7 +548,9 @@ impl SpaceElement for WindowElement { // TODO: ssd match self { WindowElement::Wayland(window) => SpaceElement::bbox(window), - WindowElement::X11(surface) => SpaceElement::bbox(surface), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + SpaceElement::bbox(surface) + } } } @@ -514,42 +558,54 @@ impl SpaceElement for WindowElement { // TODO: ssd match self { WindowElement::Wayland(window) => SpaceElement::is_in_input_region(window, point), - WindowElement::X11(surface) => SpaceElement::is_in_input_region(surface, point), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + SpaceElement::is_in_input_region(surface, point) + } } } fn z_index(&self) -> u8 { match self { WindowElement::Wayland(window) => SpaceElement::z_index(window), - WindowElement::X11(surface) => SpaceElement::z_index(surface), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + SpaceElement::z_index(surface) + } } } fn set_activate(&self, activated: bool) { match self { WindowElement::Wayland(window) => SpaceElement::set_activate(window, activated), - WindowElement::X11(surface) => SpaceElement::set_activate(surface, activated), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + SpaceElement::set_activate(surface, activated) + } } } fn output_enter(&self, output: &Output, overlap: Rectangle) { match self { WindowElement::Wayland(window) => SpaceElement::output_enter(window, output, overlap), - WindowElement::X11(surface) => SpaceElement::output_enter(surface, output, overlap), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + SpaceElement::output_enter(surface, output, overlap) + } } } fn output_leave(&self, output: &Output) { match self { WindowElement::Wayland(window) => SpaceElement::output_leave(window, output), - WindowElement::X11(surface) => SpaceElement::output_leave(surface, output), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + SpaceElement::output_leave(surface, output) + } } } fn refresh(&self) { match self { WindowElement::Wayland(window) => SpaceElement::refresh(window), - WindowElement::X11(surface) => SpaceElement::refresh(surface), + WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { + SpaceElement::refresh(surface) + } } } } diff --git a/src/window/window_state.rs b/src/window/window_state.rs index a1a609b..297488b 100644 --- a/src/window/window_state.rs +++ b/src/window/window_state.rs @@ -156,6 +156,7 @@ impl WindowElement { .set_fullscreen(true) .expect("failed to set x11 win to not fullscreen"); } + WindowElement::X11OverrideRedirect(_) => (), } } FullscreenOrMaximized::Fullscreen => { @@ -201,6 +202,7 @@ impl WindowElement { .set_fullscreen(false) .expect("failed to set x11 win to not fullscreen"); } + Self::X11OverrideRedirect(_) => (), } } FullscreenOrMaximized::Maximized => { @@ -239,6 +241,7 @@ impl WindowElement { .set_fullscreen(false) .expect("failed to set x11 win to not fullscreen"); } + Self::X11OverrideRedirect(_) => (), } } @@ -262,6 +265,7 @@ impl WindowElement { .set_fullscreen(false) .expect("failed to set x11 win to not fullscreen"); } + WindowElement::X11OverrideRedirect(_) => (), } } }