diff --git a/build/vulkan/hash.rs b/build/vulkan/hash.rs index d67b87aa..6ca12f4f 100644 --- a/build/vulkan/hash.rs +++ b/build/vulkan/hash.rs @@ -8,33 +8,31 @@ pub struct Tree { pub shaders: &'static [&'static str], } -pub const TREES: &[Tree] = &[ - Tree { - root: "src/gfx_apis/vulkan/shaders", - hash: "src/gfx_apis/vulkan/shaders_hash.txt", - bin: "src/gfx_apis/vulkan/shaders_bin", - shaders: &[ - "fill.frag", - "fill.vert", - "tex.vert", - "tex.frag", - "out.vert", - "out.frag", - "rounded_fill.frag", - "rounded_fill.vert", - "rounded_tex.frag", - "rounded_tex.vert", - "legacy/fill.frag", - "legacy/fill.vert", - "legacy/tex.vert", - "legacy/tex.frag", - "legacy/rounded_fill.frag", - "legacy/rounded_fill.vert", - "legacy/rounded_tex.frag", - "legacy/rounded_tex.vert", - ], - }, -]; +pub const TREES: &[Tree] = &[Tree { + root: "src/gfx_apis/vulkan/shaders", + hash: "src/gfx_apis/vulkan/shaders_hash.txt", + bin: "src/gfx_apis/vulkan/shaders_bin", + shaders: &[ + "fill.frag", + "fill.vert", + "tex.vert", + "tex.frag", + "out.vert", + "out.frag", + "rounded_fill.frag", + "rounded_fill.vert", + "rounded_tex.frag", + "rounded_tex.vert", + "legacy/fill.frag", + "legacy/fill.vert", + "legacy/tex.vert", + "legacy/tex.frag", + "legacy/rounded_fill.frag", + "legacy/rounded_fill.vert", + "legacy/rounded_tex.frag", + "legacy/rounded_tex.vert", + ], +}]; fn calculate_hash(tree: &Tree) -> anyhow::Result { let dir = WalkDir::new(tree.root); diff --git a/jay-config/src/client.rs b/jay-config/src/client.rs index 7093687f..38a82d42 100644 --- a/jay-config/src/client.rs +++ b/jay-config/src/client.rs @@ -233,5 +233,7 @@ bitflags! { pub const CC_GAMMA_CONTROL_MANAGER = 1 << 14, /// Grants access to the `zwlr_virtual_pointer_manager_v1` global. pub const CC_VIRTUAL_POINTER = 1 << 15, + /// Grants access to the `ext_foreign_toplevel_geometry_tracking_manager_v1` global. + pub const CC_FOREIGN_TOPLEVEL_GEOMETRY_TRACKING = 1 << 16, } } diff --git a/jay-config/src/lib.rs b/jay-config/src/lib.rs index 56c9167a..e25710f9 100644 --- a/jay-config/src/lib.rs +++ b/jay-config/src/lib.rs @@ -437,4 +437,3 @@ pub fn on_unload(f: impl FnOnce() + 'static) { pub fn set_middle_click_paste_enabled(enabled: bool) { get!().set_middle_click_paste_enabled(enabled); } - diff --git a/src/backends/metal/video.rs b/src/backends/metal/video.rs index eea31b5b..64dc1c59 100644 --- a/src/backends/metal/video.rs +++ b/src/backends/metal/video.rs @@ -321,7 +321,6 @@ impl BackendDrmDevice for MetalDrmDevice { } } } - } pub struct HandleEvents { diff --git a/src/client.rs b/src/client.rs index 0d408eb1..e21665ba 100644 --- a/src/client.rs +++ b/src/client.rs @@ -64,10 +64,11 @@ bitflags! { CAP_DRM_LEASE = 1 << 9, CAP_INPUT_METHOD = 1 << 10, CAP_WORKSPACE = 1 << 11, - CAP_FOREIGN_TOPLEVEL_MANAGER = 1 << 12, - CAP_HEAD_MANAGER = 1 << 13, - CAP_GAMMA_CONTROL_MANAGER = 1 << 14, - CAP_VIRTUAL_POINTER_MANAGER = 1 << 15, + CAP_FOREIGN_TOPLEVEL_MANAGER = 1 << 12, + CAP_HEAD_MANAGER = 1 << 13, + CAP_GAMMA_CONTROL_MANAGER = 1 << 14, + CAP_VIRTUAL_POINTER_MANAGER = 1 << 15, + CAP_FOREIGN_TOPLEVEL_GEOMETRY_TRACKING = 1 << 16, } impl StaticText for ClientCapsEnum { @@ -89,6 +90,9 @@ impl StaticText for ClientCapsEnum { ClientCapsEnum::CAP_HEAD_MANAGER => "head-manager", ClientCapsEnum::CAP_GAMMA_CONTROL_MANAGER => "gamma-control-manager", ClientCapsEnum::CAP_VIRTUAL_POINTER_MANAGER => "virtual-pointer", + ClientCapsEnum::CAP_FOREIGN_TOPLEVEL_GEOMETRY_TRACKING => { + "foreign-toplevel-geometry-tracking" + } } } } diff --git a/src/compositor.rs b/src/compositor.rs index 38d25121..45d2a018 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -60,9 +60,8 @@ use { tree::{ DisplayNode, NodeIds, OutputNode, TearingMode, Transform, VrrMode, WorkspaceDisplayOrder, WorkspaceNode, container_layout, container_render_positions, - float_layout, output_render_data, + container_tab_render_textures, float_layout, output_render_data, placeholder_render_textures, - container_tab_render_textures, }, user_session::import_environment, utils::{ diff --git a/src/config/handler.rs b/src/config/handler.rs index e30fefcf..50d2acbf 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -3371,9 +3371,7 @@ impl ConfigProxyHandler { .handle_set_bar_position(position) .wrn("set_bar_position")?, ClientMessage::GetBarPosition => self.handle_get_bar_position(), - ClientMessage::SetCornerRadius { radius } => { - self.handle_set_corner_radius(radius) - } + ClientMessage::SetCornerRadius { radius } => self.handle_set_corner_radius(radius), ClientMessage::GetCornerRadius => self.handle_get_corner_radius(), ClientMessage::SeatFocusHistory { seat, timeline } => self .handle_seat_focus_history(seat, timeline) @@ -3393,13 +3391,12 @@ impl ConfigProxyHandler { ClientMessage::SeatFocusTiles { seat } => { self.handle_seat_focus_tiles(seat).wrn("seat_focus_tiles")? } - ClientMessage::SeatFocusFloats { seat } => { - self.handle_seat_focus_floats(seat).wrn("seat_focus_floats")? - } - ClientMessage::SeatToggleFocusFloatTiled { seat } => { - self.handle_seat_toggle_focus_float_tiled(seat) - .wrn("seat_toggle_focus_float_tiled")? - } + ClientMessage::SeatFocusFloats { seat } => self + .handle_seat_focus_floats(seat) + .wrn("seat_focus_floats")?, + ClientMessage::SeatToggleFocusFloatTiled { seat } => self + .handle_seat_toggle_focus_float_tiled(seat) + .wrn("seat_toggle_focus_float_tiled")?, ClientMessage::SetMiddleClickPasteEnabled { enabled } => { self.handle_set_middle_click_paste_enabled(enabled) } @@ -3497,9 +3494,9 @@ impl ConfigProxyHandler { } => self .handle_window_resize(window, dx1, dy1, dx2, dy2) .wrn("window_resize")?, - ClientMessage::SeatToggleTab { seat } => self - .handle_seat_toggle_tab(seat) - .wrn("seat_toggle_tab")?, + ClientMessage::SeatToggleTab { seat } => { + self.handle_seat_toggle_tab(seat).wrn("seat_toggle_tab")? + } ClientMessage::SeatMakeGroup { seat, axis, diff --git a/src/criteria/clm.rs b/src/criteria/clm.rs index 80a79784..96e78a03 100644 --- a/src/criteria/clm.rs +++ b/src/criteria/clm.rs @@ -233,7 +233,6 @@ impl ClMatcherManager { pub fn tag(&self, string: CritLiteralOrRegex) -> Rc { self.root(ClmMatchTag::new(string)) } - } impl CritTarget for Rc { diff --git a/src/cursor_user.rs b/src/cursor_user.rs index 2af875df..6d911048 100644 --- a/src/cursor_user.rs +++ b/src/cursor_user.rs @@ -198,7 +198,6 @@ impl CursorUserGroup { } } - fn output_center(&self, output: &Rc) -> (Fixed, Fixed) { let pos = output.global.pos.get(); let x = Fixed::from_int((pos.x1() + pos.x2()) / 2); diff --git a/src/gfx_apis/gl.rs b/src/gfx_apis/gl.rs index ef256a6b..dc43a79c 100644 --- a/src/gfx_apis/gl.rs +++ b/src/gfx_apis/gl.rs @@ -205,8 +205,7 @@ fn run_ops(fb: &Framebuffer, ops: &[GfxApiOpt]) -> Option { Some(c) if c == fr.color => {} _ => break, } - let [top_right, top_left, bottom_right, bottom_left] = - fr.rect.to_points(); + let [top_right, top_left, bottom_right, bottom_left] = fr.rect.to_points(); triangles.extend_from_slice(&[ top_right, top_left, diff --git a/src/gfx_apis/vulkan/renderer.rs b/src/gfx_apis/vulkan/renderer.rs index c920b570..d0a48d26 100644 --- a/src/gfx_apis/vulkan/renderer.rs +++ b/src/gfx_apis/vulkan/renderer.rs @@ -615,7 +615,7 @@ impl VulkanRenderer { format: pipelines.format, vert: self.rounded_tex_vert_shader.clone(), frag: self.rounded_tex_frag_shader.clone(), - blend: true, // always blend since corners are transparent + blend: true, // always blend since corners are transparent src_has_alpha: true, // rounding makes everything have alpha has_alpha_mult, alpha_mode: key.tex_alpha_mode, @@ -973,7 +973,9 @@ impl VulkanRenderer { } VulkanOp::RoundedFill(mut f) => { f.range_address = memory.data_buffer.len() as DeviceAddress; - memory.data_buffer.extend_from_slice(uapi::as_bytes(&f.target)); + memory + .data_buffer + .extend_from_slice(uapi::as_bytes(&f.target)); mops.push(VulkanOp::RoundedFill(f)); } VulkanOp::RoundedTex(mut c) => { @@ -1370,8 +1372,18 @@ impl VulkanRenderer { for pass in RenderPass::variants() { for cmd in &mut memory.ops[pass] { let tex_data = match cmd { - VulkanOp::Tex(c) => Some((&c.tex, &mut c.buffer_resv, &mut c.acquire_sync, c.release_sync)), - VulkanOp::RoundedTex(c) => Some((&c.tex, &mut c.buffer_resv, &mut c.acquire_sync, c.release_sync)), + VulkanOp::Tex(c) => Some(( + &c.tex, + &mut c.buffer_resv, + &mut c.acquire_sync, + c.release_sync, + )), + VulkanOp::RoundedTex(c) => Some(( + &c.tex, + &mut c.buffer_resv, + &mut c.acquire_sync, + c.release_sync, + )), _ => None, }; if let Some((tex, buffer_resv, acquire_sync, release_sync)) = tex_data { @@ -1623,8 +1635,7 @@ impl VulkanRenderer { let memory = &*self.memory.borrow(); let fill_pl = self.get_or_create_fill_pipelines(target.format.vk_format)?; let tex_pl = self.get_or_create_tex_pipelines(target.format.vk_format, target_cd); - let rounded_fill_pl = - self.get_or_create_rounded_fill_pipelines(target.format.vk_format)?; + let rounded_fill_pl = self.get_or_create_rounded_fill_pipelines(target.format.vk_format)?; let rounded_tex_pl = self.get_or_create_rounded_tex_pipelines(target.format.vk_format, target_cd); let dev = &self.device.device; @@ -2416,9 +2427,7 @@ impl VulkanRenderer { // but they do paint pixels and need paint regions. (false, rf.rect) } - GfxApiOpt::RoundedCopyTexture(ct) => { - (false, ct.target) - } + GfxApiOpt::RoundedCopyTexture(ct) => (false, ct.target), }; if opaque || bb.is_none() { tag |= 1; diff --git a/src/globals.rs b/src/globals.rs index af74f100..dbc5a650 100644 --- a/src/globals.rs +++ b/src/globals.rs @@ -29,7 +29,6 @@ use { wl_output::WlOutputGlobal, wl_registry::WlRegistry, wl_seat::{ - WlSeatGlobal, ext_transient_seat_manager_v1::ExtTransientSeatManagerV1Global, tablet::zwp_tablet_manager_v2::ZwpTabletManagerV2Global, text_input::{ @@ -41,6 +40,7 @@ use { zwp_pointer_gestures_v1::ZwpPointerGesturesV1Global, zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1Global, zwp_virtual_keyboard_manager_v1::ZwpVirtualKeyboardManagerV1Global, + WlSeatGlobal, }, wl_shm::WlShmGlobal, wl_subcompositor::WlSubcompositorGlobal, @@ -65,6 +65,7 @@ use { xdg_toplevel_tag_manager_v1::XdgToplevelTagManagerV1Global, xdg_wm_base::XdgWmBaseGlobal, xdg_wm_dialog_v1::XdgWmDialogV1Global, + xx_foreign_toplevel_geometry_tracking_manager_v1::XxForeignToplevelGeometryTrackingManagerV1Global, zwlr_foreign_toplevel_manager_v1::ZwlrForeignToplevelManagerV1Global, zwlr_gamma_control_manager_v1::ZwlrGammaControlManagerV1Global, zwlr_layer_shell_v1::ZwlrLayerShellV1Global, @@ -252,6 +253,7 @@ singletons! { WpLinuxDrmSyncobjManagerV1, WpPresentation, ZwlrVirtualPointerManagerV1, + XxForeignToplevelGeometryTrackingManagerV1, } pub struct Globals { diff --git a/src/ifs.rs b/src/ifs.rs index 32464c2c..f29b0d67 100644 --- a/src/ifs.rs +++ b/src/ifs.rs @@ -88,6 +88,8 @@ pub mod xdg_toplevel_drag_v1; pub mod xdg_toplevel_tag_manager_v1; pub mod xdg_wm_base; pub mod xdg_wm_dialog_v1; +pub mod xx_foreign_toplevel_geometry_tracker_v1; +pub mod xx_foreign_toplevel_geometry_tracking_manager_v1; pub mod zwlr_foreign_toplevel_handle_v1; pub mod zwlr_foreign_toplevel_manager_v1; pub mod zwlr_gamma_control_manager_v1; diff --git a/src/ifs/hyprland_focus_grab_v1.rs b/src/ifs/hyprland_focus_grab_v1.rs index 597dc7d6..1039fdb8 100644 --- a/src/ifs/hyprland_focus_grab_v1.rs +++ b/src/ifs/hyprland_focus_grab_v1.rs @@ -1,18 +1,14 @@ use { crate::{ client::{Client, ClientError}, - ifs::wl_seat::SeatFocusGrab, - ifs::wl_surface::WlSurface, + ifs::{wl_seat::SeatFocusGrab, wl_surface::WlSurface}, leaks::Tracker, object::{Object, Version}, tree::NodeId, wire::{HyprlandFocusGrabV1Id, hyprland_focus_grab_v1::*}, }, ahash::AHashMap, - std::{ - cell::Cell, - rc::Rc, - }, + std::{cell::Cell, rc::Rc}, thiserror::Error, }; @@ -56,7 +52,8 @@ impl HyprlandFocusGrabV1 { if let Some(old) = seat.focus_grab.get() { old.clear(); } - seat.focus_grab.set(Some(self.clone() as Rc)); + seat.focus_grab + .set(Some(self.clone() as Rc)); if let Some(node) = focus_node.clone() { seat.grab(node); } diff --git a/src/ifs/jay_compositor.rs b/src/ifs/jay_compositor.rs index 7441206c..4373125e 100644 --- a/src/ifs/jay_compositor.rs +++ b/src/ifs/jay_compositor.rs @@ -542,7 +542,6 @@ impl JayCompositorRequestHandler for JayCompositor { }); Ok(()) } - } object_base! { diff --git a/src/ifs/wl_seat.rs b/src/ifs/wl_seat.rs index ebfc66b4..5fba889c 100644 --- a/src/ifs/wl_seat.rs +++ b/src/ifs/wl_seat.rs @@ -83,9 +83,9 @@ use { rect::Rect, state::{DeviceHandlerData, State}, tree::{ - ContainerNode, ContainerSplit, ChangeGroupAction, Direction, FoundNode, Node, NodeId, NodeLayer, - NodeLayerLink, NodeLocation, OutputNode, StackedNode, ToplevelNode, WorkspaceNode, - generic_node_visitor, toplevel_create_split, toplevel_parent_container, + ChangeGroupAction, ContainerNode, ContainerSplit, Direction, FoundNode, Node, NodeId, + NodeLayer, NodeLayerLink, NodeLocation, OutputNode, StackedNode, ToplevelNode, + WorkspaceNode, generic_node_visitor, toplevel_create_split, toplevel_parent_container, toplevel_set_floating, toplevel_set_workspace, }, utils::{ @@ -862,8 +862,7 @@ impl WlSeatGlobal { && let Some(c) = p.node_into_container() { c.move_focus_from_child(self, tl.deref(), direction); - } else if let Some(float) = data.float.get() - { + } else if let Some(float) = data.float.get() { let ws = float.workspace.get(); let floats: Vec<_> = ws .stacked @@ -1742,7 +1741,6 @@ impl WlSeatGlobal { pub fn set_pointer_revert_key(&self, key: KeySym) { self.revert_key.set(key); } - } impl CursorUserOwner for WlSeatGlobal { diff --git a/src/ifs/wl_surface.rs b/src/ifs/wl_surface.rs index 0f399afb..547b7e2a 100644 --- a/src/ifs/wl_surface.rs +++ b/src/ifs/wl_surface.rs @@ -1448,8 +1448,7 @@ impl WlSurface { // already called damage() when removing the child, and for tiled windows the // deferred layout damage system handles repainting once siblings have resized. // Emitting damage here creates an intermediate frame showing an empty gap. - let becoming_invisible = - was_visible && !self.visible.get() && self.buffer.is_none(); + let becoming_invisible = was_visible && !self.visible.get() && self.buffer.is_none(); if !becoming_invisible || self.toplevel.is_none() { let mut damage = buffer_abs_pos.with_size_saturating(max_surface_size.0, max_surface_size.1); diff --git a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs index 9cf4667a..768a8367 100644 --- a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs +++ b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs @@ -424,7 +424,9 @@ impl XdgToplevel { self.min_height.get(), self.max_height.get(), ) { - (Some(min_w), Some(max_w), Some(min_h), Some(max_h)) if min_w == max_w && min_h == max_h => { + (Some(min_w), Some(max_w), Some(min_h), Some(max_h)) + if min_w == max_w && min_h == max_h => + { Some((min_w, min_h)) } _ => None, diff --git a/src/ifs/wp_cursor_shape_device_v1.rs b/src/ifs/wp_cursor_shape_device_v1.rs index 7cd56264..c9e58f1a 100644 --- a/src/ifs/wp_cursor_shape_device_v1.rs +++ b/src/ifs/wp_cursor_shape_device_v1.rs @@ -139,7 +139,6 @@ impl KnownCursor { }; Some(cursor) } - } object_base! { diff --git a/src/ifs/xx_foreign_toplevel_geometry_tracker_v1.rs b/src/ifs/xx_foreign_toplevel_geometry_tracker_v1.rs new file mode 100644 index 00000000..d3977902 --- /dev/null +++ b/src/ifs/xx_foreign_toplevel_geometry_tracker_v1.rs @@ -0,0 +1,94 @@ +use { + crate::{ + client::{Client, ClientError}, + leaks::Tracker, + object::{Object, Version}, + rect::Rect, + state::State, + tree::ToplevelOpt, + wire::{XxForeignToplevelGeometryTrackerV1Id, xx_foreign_toplevel_geometry_tracker_v1::*}, + }, + std::rc::Rc, + thiserror::Error, +}; + +pub struct XxForeignToplevelGeometryTrackerV1 { + pub id: XxForeignToplevelGeometryTrackerV1Id, + pub client: Rc, + pub tracker: Tracker, + pub toplevel: ToplevelOpt, + pub version: Version, +} + +impl XxForeignToplevelGeometryTrackerV1 { + fn detach(&self) { + if let Some(tl) = self.toplevel.get() { + tl.tl_data() + .geometry_trackers + .remove(&(self.client.id, self.id)); + } + } + + pub fn send_finished(&self) { + self.client.event(Finished { self_id: self.id }); + } + + pub fn send_geometry_update(&self, rect: &Rect, state: &State) { + if rect.is_empty() { + self.client.event(Done { self_id: self.id }); + return; + } + for output in state.globals.outputs.lock().values() { + let output_pos = output.pos.get(); + if !rect.intersects(&output_pos) { + continue; + } + let scale = output.persistent.scale.get().to_f64(); + let rel_x = rect.x1() - output_pos.x1(); + let rel_y = rect.y1() - output_pos.y1(); + let hw_x = (rel_x as f64 * scale).round() as i32; + let hw_y = (rel_y as f64 * scale).round() as i32; + let hw_w = (rect.width() as f64 * scale).round() as u32; + let hw_h = (rect.height() as f64 * scale).round() as u32; + self.client.event(Geometry { + self_id: self.id, + output: output.name.raw(), + x: hw_x, + y: hw_y, + width: hw_w, + height: hw_h, + }); + } + self.client.event(Done { self_id: self.id }); + } +} + +impl XxForeignToplevelGeometryTrackerV1RequestHandler for XxForeignToplevelGeometryTrackerV1 { + type Error = XxForeignToplevelGeometryTrackerV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { + self.detach(); + self.client.remove_obj(self)?; + Ok(()) + } +} + +object_base! { + self = XxForeignToplevelGeometryTrackerV1; + version = self.version; +} + +impl Object for XxForeignToplevelGeometryTrackerV1 { + fn break_loops(&self) { + self.detach(); + } +} + +simple_add_obj!(XxForeignToplevelGeometryTrackerV1); + +#[derive(Debug, Error)] +pub enum XxForeignToplevelGeometryTrackerV1Error { + #[error(transparent)] + ClientError(Box), +} +efrom!(XxForeignToplevelGeometryTrackerV1Error, ClientError); diff --git a/src/ifs/xx_foreign_toplevel_geometry_tracking_manager_v1.rs b/src/ifs/xx_foreign_toplevel_geometry_tracking_manager_v1.rs new file mode 100644 index 00000000..c1a23f51 --- /dev/null +++ b/src/ifs/xx_foreign_toplevel_geometry_tracking_manager_v1.rs @@ -0,0 +1,125 @@ +use { + crate::{ + client::{CAP_FOREIGN_TOPLEVEL_GEOMETRY_TRACKING, Client, ClientCaps, ClientError}, + globals::{Global, GlobalName}, + ifs::{ + ext_foreign_toplevel_handle_v1::ExtForeignToplevelHandleV1, + xx_foreign_toplevel_geometry_tracker_v1::XxForeignToplevelGeometryTrackerV1, + }, + leaks::Tracker, + object::{Object, Version}, + wire::{ + XxForeignToplevelGeometryTrackingManagerV1Id, + xx_foreign_toplevel_geometry_tracking_manager_v1::*, + }, + }, + std::rc::Rc, + thiserror::Error, +}; + +pub struct XxForeignToplevelGeometryTrackingManagerV1Global { + pub name: GlobalName, +} + +impl XxForeignToplevelGeometryTrackingManagerV1Global { + pub fn new(name: GlobalName) -> Self { + Self { name } + } + + fn bind_( + self: Rc, + id: XxForeignToplevelGeometryTrackingManagerV1Id, + client: &Rc, + version: Version, + ) -> Result<(), XxForeignToplevelGeometryTrackingManagerV1Error> { + let obj = Rc::new(XxForeignToplevelGeometryTrackingManagerV1 { + id, + client: client.clone(), + tracker: Default::default(), + version, + }); + track!(client, obj); + client.add_client_obj(&obj)?; + Ok(()) + } +} + +pub struct XxForeignToplevelGeometryTrackingManagerV1 { + pub id: XxForeignToplevelGeometryTrackingManagerV1Id, + pub client: Rc, + pub tracker: Tracker, + pub version: Version, +} + +impl XxForeignToplevelGeometryTrackingManagerV1RequestHandler + for XxForeignToplevelGeometryTrackingManagerV1 +{ + type Error = XxForeignToplevelGeometryTrackingManagerV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { + self.client.remove_obj(self)?; + Ok(()) + } + + fn get_geometry_tracker( + &self, + req: GetGeometryTracker, + _slf: &Rc, + ) -> Result<(), Self::Error> { + let handle: Rc = self.client.lookup(req.toplevel)?; + let toplevel = handle.toplevel.clone(); + let tracker_obj = Rc::new(XxForeignToplevelGeometryTrackerV1 { + id: req.tracker, + client: self.client.clone(), + tracker: Default::default(), + toplevel: toplevel.clone(), + version: self.version, + }); + track!(self.client, tracker_obj); + self.client.add_client_obj(&tracker_obj)?; + if let Some(tl) = toplevel.get() { + let data = tl.tl_data(); + data.geometry_trackers + .set((self.client.id, req.tracker), tracker_obj.clone()); + let rect = tl.node_absolute_position(); + tracker_obj.send_geometry_update(&rect, &data.state); + } else { + tracker_obj.send_finished(); + } + Ok(()) + } +} + +global_base!( + XxForeignToplevelGeometryTrackingManagerV1Global, + XxForeignToplevelGeometryTrackingManagerV1, + XxForeignToplevelGeometryTrackingManagerV1Error +); + +impl Global for XxForeignToplevelGeometryTrackingManagerV1Global { + fn version(&self) -> u32 { + 1 + } + + fn required_caps(&self) -> ClientCaps { + CAP_FOREIGN_TOPLEVEL_GEOMETRY_TRACKING + } +} + +simple_add_global!(XxForeignToplevelGeometryTrackingManagerV1Global); + +object_base! { + self = XxForeignToplevelGeometryTrackingManagerV1; + version = self.version; +} + +impl Object for XxForeignToplevelGeometryTrackingManagerV1 {} + +simple_add_obj!(XxForeignToplevelGeometryTrackingManagerV1); + +#[derive(Debug, Error)] +pub enum XxForeignToplevelGeometryTrackingManagerV1Error { + #[error(transparent)] + ClientError(Box), +} +efrom!(XxForeignToplevelGeometryTrackingManagerV1Error, ClientError); diff --git a/src/renderer.rs b/src/renderer.rs index 0eeb670f..543757e7 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -299,8 +299,7 @@ impl Renderer<'_> { // RoundedFillRect z1 – rounded border ring (on top of bg) // RoundedCopyTexture – title text (on top of everything) for entry in &tab_bar.entries { - let (bg_color, border_color, _text_color) = - TabBar::entry_colors(self.state, entry); + let (bg_color, border_color, _text_color) = TabBar::entry_colors(self.state, entry); let ex = entry.x.get(); let ew = entry.width.get(); let tab_rect = Rect::new_sized_saturating(ex, 0, ew, bar_height); @@ -308,7 +307,12 @@ impl Renderer<'_> { // Tiny FillRect strip to establish Vulkan paint regions (visually hidden // behind the RoundedFillRect bg that renders later). - let strip = Rect::new_sized_saturating(ex + radius, bar_height / 2, (ew - 2 * radius).max(1), 1); + let strip = Rect::new_sized_saturating( + ex + radius, + bar_height / 2, + (ew - 2 * radius).max(1), + 1, + ); self.base .fill_boxes2(slice::from_ref(&strip), &bg_color, srgb, perceptual, x, y); @@ -350,7 +354,10 @@ impl Renderer<'_> { let text_x = match self.state.theme.tab_title_align.get() { TabTitleAlign::Start => x + ex + text_padding + border_width, TabTitleAlign::Center => { - x + ex + border_width + (tab_inner.max(0) - tex_width).max(0) / 2 + text_padding.min(tab_inner.max(0) / 2) + x + ex + + border_width + + (tab_inner.max(0) - tex_width).max(0) / 2 + + text_padding.min(tab_inner.max(0) / 2) } TabTitleAlign::End => { let end_x = x + ex + ew - tex_width - text_padding - border_width; @@ -405,8 +412,7 @@ impl Renderer<'_> { let srgb_srgb = self.state.color_manager.srgb_gamma22(); let bw = self.state.theme.sizes.border_width.get(); let border_color = self.state.theme.colors.border.get(); - let focused_border_color = - self.state.theme.colors.focused_title_background.get(); + let focused_border_color = self.state.theme.colors.focused_title_background.get(); let c = if child.active.get() { &focused_border_color } else { @@ -423,10 +429,21 @@ impl Renderer<'_> { let frame_rects = [ Rect::new_sized_saturating(mb.x1() - bw, frame_y, bw, frame_h), Rect::new_sized_saturating(mb.x2(), frame_y, bw, frame_h), - Rect::new_sized_saturating(mb.x1() - bw, frame_y - bw, full_w + 2 * bw, bw), - Rect::new_sized_saturating(mb.x1() - bw, frame_y + frame_h, full_w + 2 * bw, bw), + Rect::new_sized_saturating( + mb.x1() - bw, + frame_y - bw, + full_w + 2 * bw, + bw, + ), + Rect::new_sized_saturating( + mb.x1() - bw, + frame_y + frame_h, + full_w + 2 * bw, + bw, + ), ]; - self.base.fill_boxes2(&frame_rects, c, srgb, perceptual, x, y); + self.base + .fill_boxes2(&frame_rects, c, srgb, perceptual, x, y); } else { let outer = Rect::new_sized_saturating( mb.x1() - bw, @@ -477,12 +494,7 @@ impl Renderer<'_> { let bw = self.state.theme.sizes.border_width.get(); let border_color = self.state.theme.colors.border.get(); let focused_border_color = self.state.theme.colors.focused_title_background.get(); - ( - Some(srgb_srgb), - bw, - border_color, - focused_border_color, - ) + (Some(srgb_srgb), bw, border_color, focused_border_color) } else { (None, 0, Color::SOLID_BLACK, Color::SOLID_BLACK) }; @@ -507,10 +519,21 @@ impl Renderer<'_> { let frame_rects = [ Rect::new_sized_saturating(body.x1() - bw, body.y1(), bw, full_h), Rect::new_sized_saturating(body.x2(), body.y1(), bw, full_h), - Rect::new_sized_saturating(body.x1() - bw, body.y1() - bw, full_w + 2 * bw, bw), - Rect::new_sized_saturating(body.x1() - bw, body.y2(), full_w + 2 * bw, bw), + Rect::new_sized_saturating( + body.x1() - bw, + body.y1() - bw, + full_w + 2 * bw, + bw, + ), + Rect::new_sized_saturating( + body.x1() - bw, + body.y2(), + full_w + 2 * bw, + bw, + ), ]; - self.base.fill_boxes2(&frame_rects, c, srgb, perceptual, x, y); + self.base + .fill_boxes2(&frame_rects, c, srgb, perceptual, x, y); } else { let outer = Rect::new_sized_saturating( body.x1() - bw, @@ -533,11 +556,12 @@ impl Renderer<'_> { } } let content = child.content.get(); - self.stretch = if content.width() != body.width() || content.height() != body.height() { - Some(self.base.scale_point(body.width(), body.height())) - } else { - None - }; + self.stretch = + if content.width() != body.width() || content.height() != body.height() { + Some(self.base.scale_point(body.width(), body.height())) + } else { + None + }; if !cr.is_zero() && !child.node.node_is_container() && gap != 0 { let scalef = self.base.scalef as f32; let inner_cr = cr.expanded_by(-(bw as f32)).scaled_by(scalef); @@ -624,7 +648,6 @@ impl Renderer<'_> { self.render_surface_scaled(surface, x, y, None, bounds, false); } - pub fn render_surface_scaled( &mut self, surface: &WlSurface, @@ -797,18 +820,8 @@ impl Renderer<'_> { let borders = [ Rect::new_sized_saturating(x, y, pos.width(), bw), Rect::new_sized_saturating(x, y + bw, bw, pos.height() - bw), - Rect::new_sized_saturating( - x + pos.width() - bw, - y + bw, - bw, - pos.height() - bw, - ), - Rect::new_sized_saturating( - x + bw, - y + pos.height() - bw, - pos.width() - 2 * bw, - bw, - ), + Rect::new_sized_saturating(x + pos.width() - bw, y + bw, bw, pos.height() - bw), + Rect::new_sized_saturating(x + bw, y + pos.height() - bw, pos.width() - 2 * bw, bw), ]; self.base.fill_boxes(&borders, &bc, srgb, perceptual); } else { @@ -825,12 +838,8 @@ impl Renderer<'_> { bw as f32 * scalef, ); } - let body = Rect::new_sized_saturating( - x + bw, - y + bw, - pos.width() - 2 * bw, - pos.height() - 2 * bw, - ); + let body = + Rect::new_sized_saturating(x + bw, y + bw, pos.width() - 2 * bw, pos.height() - 2 * bw); let scissor_body = self.base.scale_rect(body); if !cr.is_zero() { let scalef = self.base.scalef as f32; diff --git a/src/renderer/renderer_base.rs b/src/renderer/renderer_base.rs index dce5bfa8..221ae7b7 100644 --- a/src/renderer/renderer_base.rs +++ b/src/renderer/renderer_base.rs @@ -260,7 +260,16 @@ impl RendererBase<'_> { corner_radius: CornerRadius, border_width: f32, ) { - self.fill_rounded_rect_z(rect, color, alpha, cd, render_intent, corner_radius, border_width, 0) + self.fill_rounded_rect_z( + rect, + color, + alpha, + cd, + render_intent, + corner_radius, + border_width, + 0, + ) } pub fn fill_rounded_rect_z( @@ -283,27 +292,26 @@ impl RendererBase<'_> { let scale = self.scalef as f32; let fitted = corner_radius.fit_to(width, height); let cr: [f32; 4] = fitted.into(); - self.ops - .push(GfxApiOpt::RoundedFillRect(RoundedFillRect { - rect: FramebufferRect::new( - rect.x1() as f32, - rect.y1() as f32, - rect.x2() as f32, - rect.y2() as f32, - self.transform, - self.fb_width, - self.fb_height, - ), - color: *color, - alpha, - render_intent, - cd: cd.clone(), - size: [width, height], - corner_radius: cr, - border_width, - scale, - z_order, - })); + self.ops.push(GfxApiOpt::RoundedFillRect(RoundedFillRect { + rect: FramebufferRect::new( + rect.x1() as f32, + rect.y1() as f32, + rect.x2() as f32, + rect.y2() as f32, + self.transform, + self.fb_width, + self.fb_height, + ), + color: *color, + alpha, + render_intent, + cd: cd.clone(), + size: [width, height], + corner_radius: cr, + border_width, + scale, + z_order, + })); } pub fn render_rounded_texture( diff --git a/src/tree/container.rs b/src/tree/container.rs index 574527c4..afd87e03 100644 --- a/src/tree/container.rs +++ b/src/tree/container.rs @@ -5,8 +5,7 @@ use { cursor_user::CursorUser, fixed::Fixed, ifs::wl_seat::{ - BTN_LEFT, NodeSeatState, SeatId, WlSeatGlobal, collect_kb_foci, - collect_kb_foci2, + BTN_LEFT, NodeSeatState, SeatId, WlSeatGlobal, collect_kb_foci, collect_kb_foci2, tablet::{TabletTool, TabletToolChanges, TabletToolId}, wl_pointer::PendingScroll, }, @@ -19,7 +18,9 @@ use { ContainingNode, Direction, FindTreeResult, FindTreeUsecase, FloatNode, FoundNode, Node, NodeId, NodeLayerLink, NodeLocation, OutputNode, TddType, TileDragDestination, ToplevelData, ToplevelNode, ToplevelNodeBase, ToplevelType, WorkspaceNode, - default_tile_drag_bounds, tab_bar::{TabBar, TabBarEntry}, toplevel_set_workspace, + default_tile_drag_bounds, + tab_bar::{TabBar, TabBarEntry}, + toplevel_set_workspace, walker::NodeVisitor, }, utils::{ @@ -399,11 +400,7 @@ impl ContainerNode { } ContainerSplit::Vertical => { let spacing = gap.max(bw); - let content_h = self - .height - .get() - .sub((nc - 1) * spacing) - .max(0); + let content_h = self.height.get().sub((nc - 1) * spacing).max(0); (self.width.get(), content_h / nc) } } @@ -478,7 +475,6 @@ impl ContainerNode { self.schedule_compute_render_positions(); self.layout_complete.trigger(); if self.all_children_match_body() { - self.all_children_resized.trigger(); if self.toplevel_data.visible.get() { self.damage(); @@ -574,11 +570,7 @@ impl ContainerNode { } ContainerSplit::Vertical => { let spacing = gap.max(border_width); - let new_content_size = self - .height - .get() - .sub((nc - 1) as i32 * spacing) - .max(0); + let new_content_size = self.height.get().sub((nc - 1) as i32 * spacing).max(0); self.content_height.set(new_content_size); self.content_width.set(self.width.get()); } @@ -741,7 +733,8 @@ impl ContainerNode { } } if self.toplevel_data.visible.get() { - self.state.damage(Rect::new_sized_saturating(abs_x, abs_y, cwidth, cheight)); + self.state + .damage(Rect::new_sized_saturating(abs_x, abs_y, cwidth, cheight)); } } @@ -936,7 +929,15 @@ impl ContainerNode { let mono_ref = mono.as_ref().unwrap(); let active_id = mono_ref.node.node_id(); let height = self.state.theme.sizes.tab_bar_height.get(); - let render_scale = self.workspace.get().output.get().global.persistent.scale.get(); + let render_scale = self + .workspace + .get() + .output + .get() + .global + .persistent + .scale + .get(); let mut bar = TabBar::new(height, render_scale); for child in self.children.iter() { let child_id = child.node.node_id(); @@ -982,12 +983,7 @@ impl ContainerNode { let was_ephemeral = self.ephemeral.replace(Ephemeral::Off); self.clone().cnode_remove_child2(&*focused_node, true); self.ephemeral.set(was_ephemeral); - let sub = ContainerNode::new( - &self.state, - &self.workspace.get(), - focused_node, - split, - ); + let sub = ContainerNode::new(&self.state, &self.workspace.get(), focused_node, split); if ephemeral { sub.ephemeral.set(Ephemeral::On); } @@ -1451,8 +1447,7 @@ impl ContainerNode { }; break 'res ( SeatOpKind::Resize { - dist_left: seat_data.x - - prev.body.get().x2(), + dist_left: seat_data.x - prev.body.get().x2(), dist_right: child.body.get().x1() - seat_data.x, }, child, @@ -1465,8 +1460,7 @@ impl ContainerNode { }; break 'res ( SeatOpKind::Resize { - dist_left: seat_data.y - - prev.body.get().y2(), + dist_left: seat_data.y - prev.body.get().y2(), dist_right: child.body.get().y1() - seat_data.y, }, child, @@ -1477,10 +1471,7 @@ impl ContainerNode { } return; }; - seat_data.op = Some(SeatOp { - child, - kind, - }) + seat_data.op = Some(SeatOp { child, kind }) } else if !pressed { seat_data.op = None; drop(seat_datas); @@ -1694,16 +1685,27 @@ pub async fn container_tab_render_textures(state: Rc) { impl ContainerNode { fn update_tab_textures_phase1( self: &Rc, - ) -> (Rc, Vec>>>) { + ) -> ( + Rc, + Vec>>>, + ) { let on_completed = Rc::new(OnDropEvent::default()); let (entries, bar_height, render_scale) = { let tab_bar = self.tab_bar.borrow(); let Some(tb) = tab_bar.as_ref() else { return (on_completed.event(), vec![]); }; - let entries: Vec<_> = tb.entries.iter().map(|e| { - (e.title.clone(), TabBar::entry_colors(&self.state, e), e.title_texture.clone()) - }).collect(); + let entries: Vec<_> = tb + .entries + .iter() + .map(|e| { + ( + e.title.clone(), + TabBar::entry_colors(&self.state, e), + e.title_texture.clone(), + ) + }) + .collect(); (entries, tb.height, tb.render_scale) }; let Some(ctx) = self.state.render_ctx.get() else { @@ -1864,7 +1866,6 @@ impl Node for ContainerNode { self.update_child_size(node, width, height); } if self.all_children_match_body() { - self.all_children_resized.trigger(); if self.toplevel_data.visible.get() { self.damage(); @@ -2280,12 +2281,8 @@ impl ContainingNode for ContainerNode { ci = 1; } let (new_delta, between) = match split { - ContainerSplit::Horizontal => { - (self.abs_x1.get(), gap.max(bw)) - } - ContainerSplit::Vertical => { - (self.abs_y1.get(), gap.max(bw)) - } + ContainerSplit::Horizontal => (self.abs_x1.get(), gap.max(bw)), + ContainerSplit::Vertical => (self.abs_y1.get(), gap.max(bw)), }; let new_i1 = new_i1.map(|v| v - new_delta); let new_i2 = new_i2.map(|v| v - new_delta); diff --git a/src/tree/float.rs b/src/tree/float.rs index 7e9fffff..dc0b44f4 100644 --- a/src/tree/float.rs +++ b/src/tree/float.rs @@ -515,12 +515,7 @@ impl FloatNode { let theme = &self.state.theme.sizes; let bw = theme.border_width.get(); let pos = self.position.get(); - let body = Rect::new( - pos.x1() + bw, - pos.y1() + bw, - pos.x2() - bw, - pos.y2() - bw, - )?; + let body = Rect::new(pos.x1() + bw, pos.y1() + bw, pos.x2() - bw, pos.y2() - bw)?; child.tl_tile_drag_destination(source, None, body, abs_x, abs_y) } } diff --git a/src/tree/tab_bar.rs b/src/tree/tab_bar.rs index ef93f9f4..4dd1f485 100644 --- a/src/tree/tab_bar.rs +++ b/src/tree/tab_bar.rs @@ -1,12 +1,9 @@ use { - crate::{ - scale::Scale, - state::State, - text::TextTexture, - theme::Color, - tree::NodeId, + crate::{scale::Scale, state::State, text::TextTexture, theme::Color, tree::NodeId}, + std::{ + cell::{Cell, RefCell}, + rc::Rc, }, - std::{cell::{Cell, RefCell}, rc::Rc}, }; /// A single entry (tab) within a tab bar. diff --git a/src/tree/toplevel.rs b/src/tree/toplevel.rs index a196286d..02bba848 100644 --- a/src/tree/toplevel.rs +++ b/src/tree/toplevel.rs @@ -21,6 +21,7 @@ use { xdg_surface::xdg_toplevel::XdgToplevelToplevelData, }, wp_content_type_v1::ContentType, + xx_foreign_toplevel_geometry_tracker_v1::XxForeignToplevelGeometryTrackerV1, zwlr_foreign_toplevel_handle_v1::ZwlrForeignToplevelHandleV1, zwlr_foreign_toplevel_manager_v1::ZwlrForeignToplevelManagerV1, }, @@ -37,7 +38,7 @@ use { }, wire::{ ExtForeignToplevelHandleV1Id, ExtImageCopyCaptureSessionV1Id, JayScreencastId, - JayToplevelId, ZwlrForeignToplevelHandleV1Id, + JayToplevelId, XxForeignToplevelGeometryTrackerV1Id, ZwlrForeignToplevelHandleV1Id, }, }, jay_config::{window, window::WindowType}, @@ -195,7 +196,13 @@ impl ToplevelNode for T { data.float_width.set(rect.width()); data.float_height.set(rect.height()); } - self.tl_change_extents_impl(rect) + let _ = data; + let slf = self.clone(); + self.tl_change_extents_impl(rect); + let data = slf.tl_data(); + for tracker in data.geometry_trackers.lock().values() { + tracker.send_geometry_update(rect, &data.state); + } } fn tl_set_visible(&self, visible: bool) { @@ -401,6 +408,10 @@ pub struct ToplevelData { pub identifier: Cell, pub handles: CopyHashMap<(ClientId, ExtForeignToplevelHandleV1Id), Rc>, + pub geometry_trackers: CopyHashMap< + (ClientId, XxForeignToplevelGeometryTrackerV1Id), + Rc, + >, pub manager_handles: CopyHashMap<(ClientId, ZwlrForeignToplevelHandleV1Id), Rc>, pub render_highlight: NumCell, @@ -459,6 +470,7 @@ impl ToplevelData { app_id: Default::default(), identifier: Cell::new(id), handles: Default::default(), + geometry_trackers: Default::default(), manager_handles: Default::default(), render_highlight: Default::default(), jay_toplevels: Default::default(), @@ -563,6 +575,12 @@ impl ToplevelData { handle.send_closed(); } } + { + let mut trackers = self.geometry_trackers.lock(); + for tracker in trackers.drain_values() { + tracker.send_finished(); + } + } self.detach_node(node); self.property_changed(TL_CHANGED_DESTROYED); } @@ -951,7 +969,6 @@ impl ToplevelData { }; parent.node_is_workspace() } - } impl Drop for ToplevelData { diff --git a/src/video/dmabuf.rs b/src/video/dmabuf.rs index bbcb9ace..e19def66 100644 --- a/src/video/dmabuf.rs +++ b/src/video/dmabuf.rs @@ -113,7 +113,6 @@ impl DmaBuf { } Ok(()) } - } const DMA_BUF_BASE: u64 = b'b' as _; diff --git a/src/wl_usr/usr_ifs/usr_jay_compositor.rs b/src/wl_usr/usr_ifs/usr_jay_compositor.rs index 77c8b516..d19d4658 100644 --- a/src/wl_usr/usr_ifs/usr_jay_compositor.rs +++ b/src/wl_usr/usr_ifs/usr_jay_compositor.rs @@ -187,7 +187,6 @@ impl UsrJayCompositor { self.con.add_object(obj.clone()); obj } - } impl JayCompositorEventHandler for UsrJayCompositor { diff --git a/src/wl_usr/usr_ifs/usr_wl_data_device.rs b/src/wl_usr/usr_ifs/usr_wl_data_device.rs index a64a173e..293ae4cd 100644 --- a/src/wl_usr/usr_ifs/usr_wl_data_device.rs +++ b/src/wl_usr/usr_ifs/usr_wl_data_device.rs @@ -3,11 +3,7 @@ use { object::Version, utils::clonecell::CloneCell, wire::{WlDataDeviceId, wl_data_device::*}, - wl_usr::{ - UsrCon, - usr_ifs::usr_wl_data_offer::UsrWlDataOffer, - usr_object::UsrObject, - }, + wl_usr::{UsrCon, usr_ifs::usr_wl_data_offer::UsrWlDataOffer, usr_object::UsrObject}, }, std::{convert::Infallible, rc::Rc}, }; diff --git a/src/wl_usr/usr_ifs/usr_wl_seat.rs b/src/wl_usr/usr_ifs/usr_wl_seat.rs index 08b48f1f..82db0a05 100644 --- a/src/wl_usr/usr_ifs/usr_wl_seat.rs +++ b/src/wl_usr/usr_ifs/usr_wl_seat.rs @@ -3,11 +3,7 @@ use { object::Version, utils::clonecell::CloneCell, wire::{WlSeatId, wl_seat::*}, - wl_usr::{ - UsrCon, - usr_ifs::usr_wl_pointer::UsrWlPointer, - usr_object::UsrObject, - }, + wl_usr::{UsrCon, usr_ifs::usr_wl_pointer::UsrWlPointer, usr_object::UsrObject}, }, std::{cell::Cell, convert::Infallible, rc::Rc}, }; @@ -46,7 +42,6 @@ impl UsrWlSeat { }); ptr } - } impl WlSeatEventHandler for UsrWlSeat { diff --git a/toml-config/src/config/parsers/capabilities.rs b/toml-config/src/config/parsers/capabilities.rs index 4cde9158..8477ef9a 100644 --- a/toml-config/src/config/parsers/capabilities.rs +++ b/toml-config/src/config/parsers/capabilities.rs @@ -7,10 +7,11 @@ use { }, }, jay_config::client::{ - CC_DATA_CONTROL, CC_DRM_LEASE, CC_FOREIGN_TOPLEVEL_LIST, CC_FOREIGN_TOPLEVEL_MANAGER, - CC_GAMMA_CONTROL_MANAGER, CC_HEAD_MANAGER, CC_IDLE_NOTIFIER, CC_INPUT_METHOD, - CC_LAYER_SHELL, CC_SCREENCOPY, CC_SEAT_MANAGER, CC_SESSION_LOCK, CC_VIRTUAL_KEYBOARD, - CC_VIRTUAL_POINTER, CC_WORKSPACE_MANAGER, ClientCapabilities, + CC_DATA_CONTROL, CC_DRM_LEASE, CC_FOREIGN_TOPLEVEL_GEOMETRY_TRACKING, + CC_FOREIGN_TOPLEVEL_LIST, CC_FOREIGN_TOPLEVEL_MANAGER, CC_GAMMA_CONTROL_MANAGER, + CC_HEAD_MANAGER, CC_IDLE_NOTIFIER, CC_INPUT_METHOD, CC_LAYER_SHELL, CC_SCREENCOPY, + CC_SEAT_MANAGER, CC_SESSION_LOCK, CC_VIRTUAL_KEYBOARD, CC_VIRTUAL_POINTER, + CC_WORKSPACE_MANAGER, ClientCapabilities, }, thiserror::Error, }; @@ -49,6 +50,7 @@ impl Parser for CapabilitiesParser { "head-manager" => CC_HEAD_MANAGER, "gamma-control-manager" => CC_GAMMA_CONTROL_MANAGER, "virtual-pointer" => CC_VIRTUAL_POINTER, + "foreign-toplevel-geometry-tracking" => CC_FOREIGN_TOPLEVEL_GEOMETRY_TRACKING, _ => { return Err( CapabilitiesParserError::UnknownCapability(string.to_owned()).spanned(span), diff --git a/toml-config/src/config/parsers/theme.rs b/toml-config/src/config/parsers/theme.rs index fe8156f4..84f2d580 100644 --- a/toml-config/src/config/parsers/theme.rs +++ b/toml-config/src/config/parsers/theme.rs @@ -114,7 +114,13 @@ impl Parser for ThemeParser<'_> { tab_bar_height, tab_bar_padding, ), - (tab_bar_radius, tab_bar_border_width, tab_bar_text_padding, tab_bar_gap, tab_title_align_val), + ( + tab_bar_radius, + tab_bar_border_width, + tab_bar_text_padding, + tab_bar_gap, + tab_title_align_val, + ), ) = ext.extract(( ( opt(val("tab-active-bg-color")), diff --git a/toml-config/src/lib.rs b/toml-config/src/lib.rs index c15ace34..7b596921 100644 --- a/toml-config/src/lib.rs +++ b/toml-config/src/lib.rs @@ -37,12 +37,12 @@ use { is_reload, keyboard::Keymap, logging::{clean_logs_older_than, set_log_level}, - on_devices_enumerated, on_idle, on_unload, quit, reload, - set_color_management_enabled, set_default_workspace_capture, set_explicit_sync_enabled, - set_float_above_fullscreen, set_idle, set_idle_grace_period, - set_floating_titles, set_middle_click_paste_enabled, set_show_bar, set_show_float_pin_icon, - set_show_titles, set_corner_radius, set_autotile, set_tab_title_align, - set_ui_drag_enabled, set_ui_drag_threshold, + on_devices_enumerated, on_idle, on_unload, quit, reload, set_autotile, + set_color_management_enabled, set_corner_radius, set_default_workspace_capture, + set_explicit_sync_enabled, set_float_above_fullscreen, set_floating_titles, set_idle, + set_idle_grace_period, set_middle_click_paste_enabled, set_show_bar, + set_show_float_pin_icon, set_show_titles, set_tab_title_align, set_ui_drag_enabled, + set_ui_drag_threshold, status::{set_i3bar_separator, set_status, set_status_command, unset_status_command}, switch_to_vt, tasks::{self, JoinHandle}, @@ -256,28 +256,18 @@ impl Action { b.new(move || persistent.seat.warp_mouse_to_focus()) } SimpleCommand::ToggleTab => b.new(move || s.toggle_tab()), - SimpleCommand::MakeGroupH => { - b.new(move || s.make_group(Axis::Horizontal, true)) - } - SimpleCommand::MakeGroupV => { - b.new(move || s.make_group(Axis::Vertical, true)) - } - SimpleCommand::MakeGroupTab => { - b.new(move || { - s.make_group(Axis::Horizontal, true); - s.toggle_tab(); - }) - } - SimpleCommand::ChangeGroupOpposite => { - b.new(move || s.change_group_opposite()) - } + SimpleCommand::MakeGroupH => b.new(move || s.make_group(Axis::Horizontal, true)), + SimpleCommand::MakeGroupV => b.new(move || s.make_group(Axis::Vertical, true)), + SimpleCommand::MakeGroupTab => b.new(move || { + s.make_group(Axis::Horizontal, true); + s.toggle_tab(); + }), + SimpleCommand::ChangeGroupOpposite => b.new(move || s.change_group_opposite()), SimpleCommand::Equalize => b.new(move || s.equalize(false)), SimpleCommand::EqualizeRecursive => b.new(move || s.equalize(true)), SimpleCommand::MoveTabLeft => b.new(move || s.move_tab(false)), SimpleCommand::MoveTabRight => b.new(move || s.move_tab(true)), - SimpleCommand::SetAutotile(enabled) => { - b.new(move || set_autotile(enabled)) - } + SimpleCommand::SetAutotile(enabled) => b.new(move || set_autotile(enabled)), SimpleCommand::ToggleAutotile => { b.new(move || { // Toggle not directly supported; set to true diff --git a/wire/xx_foreign_toplevel_geometry_tracker_v1.txt b/wire/xx_foreign_toplevel_geometry_tracker_v1.txt new file mode 100644 index 00000000..b3956c2f --- /dev/null +++ b/wire/xx_foreign_toplevel_geometry_tracker_v1.txt @@ -0,0 +1,16 @@ +request destroy (destructor) { +} + +event finished { +} + +event done { +} + +event geometry { + output: u32, + x: i32, + y: i32, + width: u32, + height: u32, +} diff --git a/wire/xx_foreign_toplevel_geometry_tracking_manager_v1.txt b/wire/xx_foreign_toplevel_geometry_tracking_manager_v1.txt new file mode 100644 index 00000000..befd6942 --- /dev/null +++ b/wire/xx_foreign_toplevel_geometry_tracking_manager_v1.txt @@ -0,0 +1,7 @@ +request destroy (destructor) { +} + +request get_geometry_tracker { + tracker: id(xx_foreign_toplevel_geometry_tracker_v1) (new), + toplevel: id(ext_foreign_toplevel_handle_v1), +}