From b604192bf021202141d84e52aa214d4cb656e9cb Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Tue, 24 Feb 2026 19:48:28 +0100 Subject: [PATCH 1/6] theme: add BarPosition --- src/config/handler.rs | 14 +++++++-- src/ifs/wl_surface/tray/jay_tray_item_v1.rs | 6 ++-- src/theme.rs | 32 ++++++++++++++++++++- src/tree/output.rs | 4 +-- 4 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/config/handler.rs b/src/config/handler.rs index 76eb6e74..e9fdd404 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -1433,14 +1433,18 @@ impl ConfigProxyHandler { }); } - fn handle_set_bar_position(&self, position: BarPosition) { + fn handle_set_bar_position(&self, position: BarPosition) -> Result<(), CphError> { + let Ok(position) = position.try_into() else { + return Err(CphError::UnknownBarPosition(position)); + }; self.state.theme.bar_position.set(position); self.spaces_change(); + Ok(()) } fn handle_get_bar_position(&self) { self.respond(Response::GetBarPosition { - position: self.state.theme.bar_position.get(), + position: self.state.theme.bar_position.get().into(), }); } @@ -3289,7 +3293,9 @@ impl ConfigProxyHandler { ClientMessage::GetShowBar => self.handle_get_show_bar(), ClientMessage::SetShowTitles { show } => self.handle_set_show_titles(show), ClientMessage::GetShowTitles => self.handle_get_show_titles(), - ClientMessage::SetBarPosition { position } => self.handle_set_bar_position(position), + ClientMessage::SetBarPosition { position } => self + .handle_set_bar_position(position) + .wrn("set_bar_position")?, ClientMessage::GetBarPosition => self.handle_get_bar_position(), ClientMessage::SeatFocusHistory { seat, timeline } => self .handle_seat_focus_history(seat, timeline) @@ -3524,6 +3530,8 @@ enum CphError { ModifyConnectorState(#[source] BackendConnectorTransactionError), #[error("Unknown blend space {0:?}")] UnknownBlendSpace(ConfigBlendSpace), + #[error("Unknown bar position {0:?}")] + UnknownBarPosition(BarPosition), } trait WithRequestName { diff --git a/src/ifs/wl_surface/tray/jay_tray_item_v1.rs b/src/ifs/wl_surface/tray/jay_tray_item_v1.rs index 5385d41a..88b5731f 100644 --- a/src/ifs/wl_surface/tray/jay_tray_item_v1.rs +++ b/src/ifs/wl_surface/tray/jay_tray_item_v1.rs @@ -15,11 +15,11 @@ use { }, leaks::Tracker, object::{Object, Version}, + theme::BarPosition, tree::NodeVisitor, utils::copyhashmap::CopyHashMap, wire::{JayTrayItemV1Id, XdgPopupId, jay_tray_item_v1::*}, }, - jay_config::theme::BarPosition, std::rc::Rc, thiserror::Error, }; @@ -64,7 +64,7 @@ impl JayTrayItemV1 { fn send_preferred_anchor(&self) { let anchor = match self.data.client.state.theme.bar_position.get() { BarPosition::Bottom => ANCHOR_TOP_RIGHT, - BarPosition::Top | _ => ANCHOR_BOTTOM_RIGHT, + BarPosition::Top => ANCHOR_BOTTOM_RIGHT, }; self.data.client.event(PreferredAnchor { self_id: self.id, @@ -75,7 +75,7 @@ impl JayTrayItemV1 { fn send_preferred_gravity(&self) { let gravity = match self.data.client.state.theme.bar_position.get() { BarPosition::Bottom => ANCHOR_TOP_LEFT, - BarPosition::Top | _ => ANCHOR_BOTTOM_LEFT, + BarPosition::Top => ANCHOR_BOTTOM_LEFT, }; self.data.client.event(PreferredGravity { self_id: self.id, diff --git a/src/theme.rs b/src/theme.rs index 8deda63d..f470993e 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -6,7 +6,8 @@ use { gfx_api::AlphaMode, utils::clonecell::CloneCell, }, - jay_config::theme::BarPosition, + jay_config::theme::BarPosition as ConfigBarPosition, + linearize::Linearize, num_traits::Float, std::{cell::Cell, cmp::Ordering, ops::Mul, sync::Arc}, }; @@ -515,6 +516,35 @@ sizes! { pub const DEFAULT_FONT: &str = "monospace 8"; +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Default, Linearize)] +pub enum BarPosition { + #[default] + Top, + Bottom, +} + +impl TryFrom for BarPosition { + type Error = (); + + fn try_from(value: ConfigBarPosition) -> Result { + let v = match value { + ConfigBarPosition::Top => Self::Top, + ConfigBarPosition::Bottom => Self::Bottom, + _ => return Err(()), + }; + Ok(v) + } +} + +impl Into for BarPosition { + fn into(self) -> ConfigBarPosition { + match self { + BarPosition::Top => ConfigBarPosition::Top, + BarPosition::Bottom => ConfigBarPosition::Bottom, + } + } +} + pub struct Theme { pub colors: ThemeColors, pub sizes: ThemeSizes, diff --git a/src/tree/output.rs b/src/tree/output.rs index 55707c92..ff4baad8 100644 --- a/src/tree/output.rs +++ b/src/tree/output.rs @@ -43,6 +43,7 @@ use { scale::Scale, state::State, text::TextTexture, + theme::BarPosition, tree::{ Direction, FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, NodeLayerLink, NodeLocation, PinnedNode, StackedNode, TddType, TileDragDestination, @@ -67,7 +68,6 @@ use { }, ahash::AHashMap, jay_config::{ - theme::BarPosition, video::{TearingMode as ConfigTearingMode, Transform, VrrMode as ConfigVrrMode}, workspace::WorkspaceDisplayOrder, }, @@ -794,7 +794,7 @@ impl OutputNode { Rect::new_sized_saturating(x1, y1 + height - bh - bsw, width, bsw); bar_rect = Rect::new_sized_saturating(x1, y1 + height - bh, width, bh); } - BarPosition::Top | _ => { + BarPosition::Top => { bar_rect = Rect::new_sized_saturating(x1, y1, width, bh); bar_separator_rect = Rect::new_sized_saturating(x1, y1 + bh, width, bsw); bar_rect_with_separator = Rect::new_sized_saturating(x1, y1, width, bh + bsw); From ca6e3891af82f8b8c5b57f402dbb06a52dade044 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Tue, 24 Feb 2026 19:56:51 +0100 Subject: [PATCH 2/6] gfx-api: add GfxApi --- src/backend.rs | 4 +-- src/backends/metal/video.rs | 3 +- src/backends/x.rs | 5 +-- src/compositor.rs | 7 ++--- src/config/handler.rs | 5 +++ src/gfx_api.rs | 48 ++++++++++++++++++++++++++++- src/gfx_apis.rs | 4 +-- src/gfx_apis/gl/renderer/context.rs | 6 ++-- src/gfx_apis/vulkan.rs | 3 +- src/ifs/jay_randr.rs | 7 ++--- src/it/test_gfx_api.rs | 3 +- src/portal/ptl_display.rs | 3 +- src/state.rs | 9 ++---- src/utils.rs | 1 - src/utils/gfx_api_ext.rs | 25 --------------- 15 files changed, 72 insertions(+), 61 deletions(-) delete mode 100644 src/utils/gfx_api_ext.rs diff --git a/src/backend.rs b/src/backend.rs index fd733270..ddfc98c0 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -9,7 +9,7 @@ use { drm_feedback::DrmFeedback, fixed::Fixed, format::Format, - gfx_api::{GfxFramebuffer, SyncFile}, + gfx_api::{GfxApi, GfxFramebuffer, SyncFile}, ifs::{ wl_output::OutputId, wl_seat::{ @@ -28,7 +28,7 @@ use { HDMI_EOTF_TRADITIONAL_GAMMA_SDR, }, }, - jay_config::{input::SwitchEvent, video::GfxApi}, + jay_config::input::SwitchEvent, linearize::Linearize, std::{ any::Any, diff --git a/src/backends/metal/video.rs b/src/backends/metal/video.rs index 8509b0bf..a8a1e720 100644 --- a/src/backends/metal/video.rs +++ b/src/backends/metal/video.rs @@ -26,7 +26,7 @@ use { drm_feedback::DrmFeedback, edid::{CtaDataBlock, Descriptor, EdidExtension}, format::{Format, XRGB8888}, - gfx_api::{GfxContext, GfxFramebuffer, SyncFile}, + gfx_api::{GfxApi, GfxContext, GfxFramebuffer, SyncFile}, ifs::{ wl_output::OutputId, wp_presentation_feedback::{KIND_HW_COMPLETION, KIND_VSYNC, KIND_ZERO_COPY}, @@ -57,7 +57,6 @@ use { bstr::{BString, ByteSlice}, indexmap::{IndexSet, indexset}, isnt::std_1::collections::IsntHashMapExt, - jay_config::video::GfxApi, std::{ cell::{Cell, OnceCell, RefCell}, collections::hash_map::Entry, diff --git a/src/backends/x.rs b/src/backends/x.rs index 866f8a08..f338c446 100644 --- a/src/backends/x.rs +++ b/src/backends/x.rs @@ -17,7 +17,9 @@ use { cmm::cmm_primaries::Primaries, fixed::Fixed, format::{Format, XRGB8888}, - gfx_api::{AcquireSync, GfxContext, GfxError, GfxFramebuffer, GfxTexture, ReleaseSync}, + gfx_api::{ + AcquireSync, GfxApi, GfxContext, GfxError, GfxFramebuffer, GfxTexture, ReleaseSync, + }, ifs::wl_output::OutputId, state::State, time::Time, @@ -57,7 +59,6 @@ use { }, }, ahash::AHashMap, - jay_config::video::GfxApi, std::{ any::Any, borrow::Cow, diff --git a/src/compositor.rs b/src/compositor.rs index 28901c13..15550c80 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -28,6 +28,7 @@ use { ei::ei_client::EiClients, forker, format::XRGB8888, + gfx_api::GfxApi, globals::Globals, ifs::{ head_management::{ @@ -81,11 +82,7 @@ use { }, ahash::AHashSet, forker::ForkerProxy, - jay_config::{ - _private::DEFAULT_SEAT_NAME, - video::{GfxApi, Transform}, - workspace::WorkspaceDisplayOrder, - }, + jay_config::{_private::DEFAULT_SEAT_NAME, video::Transform, workspace::WorkspaceDisplayOrder}, std::{ cell::{Cell, RefCell}, env, diff --git a/src/config/handler.rs b/src/config/handler.rs index e9fdd404..042af16b 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -954,6 +954,9 @@ impl ConfigProxyHandler { } fn handle_set_gfx_api(&self, device: Option, api: GfxApi) -> Result<(), CphError> { + let Ok(api) = api.try_into() else { + return Err(CphError::UnknownGfxApi(api)); + }; match device { Some(dev) => self.get_drm_device(dev)?.dev.set_gfx_api(api), _ => self.state.default_gfx_api.set(api), @@ -3532,6 +3535,8 @@ enum CphError { UnknownBlendSpace(ConfigBlendSpace), #[error("Unknown bar position {0:?}")] UnknownBarPosition(BarPosition), + #[error("Unknown gfx API {0:?}")] + UnknownGfxApi(GfxApi), } trait WithRequestName { diff --git a/src/gfx_api.rs b/src/gfx_api.rs index cb4f6643..d5104b60 100644 --- a/src/gfx_api.rs +++ b/src/gfx_api.rs @@ -18,7 +18,8 @@ use { }, ahash::AHashMap, indexmap::{IndexMap, IndexSet}, - jay_config::video::{GfxApi, Transform}, + jay_config::video::{GfxApi as ConfigGfxApi, Transform}, + linearize::Linearize, std::{ any::Any, cell::Cell, @@ -33,6 +34,51 @@ use { uapi::OwnedFd, }; +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Linearize)] +pub enum GfxApi { + OpenGl, + Vulkan, +} + +impl TryFrom for GfxApi { + type Error = (); + + fn try_from(value: ConfigGfxApi) -> Result { + let v = match value { + ConfigGfxApi::OpenGl => GfxApi::OpenGl, + ConfigGfxApi::Vulkan => GfxApi::Vulkan, + _ => return Err(()), + }; + Ok(v) + } +} + +impl Into for GfxApi { + fn into(self) -> ConfigGfxApi { + match self { + GfxApi::OpenGl => ConfigGfxApi::OpenGl, + GfxApi::Vulkan => ConfigGfxApi::Vulkan, + } + } +} + +impl GfxApi { + pub fn to_str(&self) -> &'static str { + match self { + GfxApi::OpenGl => "OpenGl", + GfxApi::Vulkan => "Vulkan", + } + } + + pub fn from_str_lossy(s: &str) -> Option { + match &*s.to_ascii_lowercase() { + "opengl" => Some(Self::OpenGl), + "vulkan" => Some(Self::Vulkan), + _ => None, + } + } +} + pub enum GfxApiOpt { Sync, FillRect(FillRect), diff --git a/src/gfx_apis.rs b/src/gfx_apis.rs index 261b0b1b..f0d1aaa2 100644 --- a/src/gfx_apis.rs +++ b/src/gfx_apis.rs @@ -2,13 +2,12 @@ pub use vulkan::create_vulkan_allocator; use { crate::{ async_engine::AsyncEngine, - gfx_api::{GfxContext, GfxError}, + gfx_api::{GfxApi, GfxContext, GfxError}, io_uring::IoUring, pr_caps::PrCapsThread, utils::errorfmt::ErrorFmt, video::drm::Drm, }, - jay_config::video::GfxApi, std::rc::Rc, }; @@ -57,6 +56,5 @@ fn create_gfx_context_( match api { GfxApi::OpenGl => gl::create_gfx_context(drm, software), GfxApi::Vulkan => vulkan::create_graphics_context(eng, ring, drm, caps_thread, software), - _ => unreachable!(), } } diff --git a/src/gfx_apis/gl/renderer/context.rs b/src/gfx_apis/gl/renderer/context.rs index 17441ea3..7c50214f 100644 --- a/src/gfx_apis/gl/renderer/context.rs +++ b/src/gfx_apis/gl/renderer/context.rs @@ -4,8 +4,9 @@ use { cpu_worker::CpuWorker, format::{Format, XRGB8888}, gfx_api::{ - AsyncShmGfxTexture, BufferResvUser, GfxBlendBuffer, GfxContext, GfxError, GfxFormat, - GfxFramebuffer, GfxImage, GfxInternalFramebuffer, ResetStatus, ShmGfxTexture, + AsyncShmGfxTexture, BufferResvUser, GfxApi, GfxBlendBuffer, GfxContext, GfxError, + GfxFormat, GfxFramebuffer, GfxImage, GfxInternalFramebuffer, ResetStatus, + ShmGfxTexture, }, gfx_apis::gl::{ GfxGlState, RenderError, Texture, @@ -24,7 +25,6 @@ use { }, }, ahash::AHashMap, - jay_config::video::GfxApi, linearize::{Linearize, StaticMap, static_map}, std::{ cell::{Cell, RefCell}, diff --git a/src/gfx_apis/vulkan.rs b/src/gfx_apis/vulkan.rs index 36662e47..90928525 100644 --- a/src/gfx_apis/vulkan.rs +++ b/src/gfx_apis/vulkan.rs @@ -30,7 +30,7 @@ use { cpu_worker::{CpuWorker, jobs::read_write::ReadWriteJobError}, format::Format, gfx_api::{ - AsyncShmGfxTexture, GfxBlendBuffer, GfxBuffer, GfxContext, GfxError, GfxFormat, + AsyncShmGfxTexture, GfxApi, GfxBlendBuffer, GfxBuffer, GfxContext, GfxError, GfxFormat, GfxImage, GfxInternalFramebuffer, GfxStagingBuffer, GfxTexture, ResetStatus, STAGING_DOWNLOAD, STAGING_UPLOAD, ShmGfxTexture, StagingBufferUsecase, }, @@ -51,7 +51,6 @@ use { ahash::AHashMap, ash::vk, gpu_alloc::{AllocationError, MapError}, - jay_config::video::GfxApi, log::Level, std::{ cell::Cell, diff --git a/src/ifs/jay_randr.rs b/src/ifs/jay_randr.rs index 64915be9..f80d15e9 100644 --- a/src/ifs/jay_randr.rs +++ b/src/ifs/jay_randr.rs @@ -4,18 +4,17 @@ use { client::{Client, ClientError}, compositor::MAX_EXTENTS, format::named_formats, + gfx_api::GfxApi, ifs::wl_output, leaks::Tracker, object::{Object, Version}, scale::Scale, state::{ConnectorData, DrmDevData, OutputData, State}, tree::{OutputNode, TearingMode, VrrMode}, - utils::{errorfmt::ErrorFmt, gfx_api_ext::GfxApiExt, transform_ext::TransformExt}, + utils::{errorfmt::ErrorFmt, transform_ext::TransformExt}, wire::{JayRandrId, jay_randr::*}, }, - jay_config::video::{ - GfxApi, TearingMode as ConfigTearingMode, Transform, VrrMode as ConfigVrrMode, - }, + jay_config::video::{TearingMode as ConfigTearingMode, Transform, VrrMode as ConfigVrrMode}, linearize::LinearizeExt, std::rc::Rc, thiserror::Error, diff --git a/src/it/test_gfx_api.rs b/src/it/test_gfx_api.rs index 44993212..9d225aef 100644 --- a/src/it/test_gfx_api.rs +++ b/src/it/test_gfx_api.rs @@ -6,7 +6,7 @@ use { format::{ARGB8888, Format, XRGB8888}, gfx_api::{ AcquireSync, AsyncShmGfxTexture, AsyncShmGfxTextureCallback, CopyTexture, FillRect, - FramebufferRect, GfxApiOpt, GfxBlendBuffer, GfxContext, GfxError, GfxFormat, + FramebufferRect, GfxApi, GfxApiOpt, GfxBlendBuffer, GfxContext, GfxError, GfxFormat, GfxFramebuffer, GfxImage, GfxInternalFramebuffer, GfxStagingBuffer, GfxTexture, GfxWriteModifier, PendingShmTransfer, ReleaseSync, ResetStatus, ShmGfxTexture, ShmMemory, SyncFile, @@ -17,7 +17,6 @@ use { }, ahash::AHashMap, indexmap::IndexSet, - jay_config::video::GfxApi, std::{ any::Any, cell::{Cell, RefCell}, diff --git a/src/portal/ptl_display.rs b/src/portal/ptl_display.rs index e52e2e0c..2c59eeb4 100644 --- a/src/portal/ptl_display.rs +++ b/src/portal/ptl_display.rs @@ -1,6 +1,6 @@ use { crate::{ - gfx_api::{GfxFormat, cross_intersect_formats}, + gfx_api::{GfxApi, GfxFormat, cross_intersect_formats}, gfx_apis::create_gfx_context, ifs::wl_seat::POINTER, object::Version, @@ -46,7 +46,6 @@ use { }, }, ahash::AHashMap, - jay_config::video::GfxApi, std::{ cell::{Cell, RefCell}, ops::Deref, diff --git a/src/state.rs b/src/state.rs index 1e03be08..e349bd3f 100644 --- a/src/state.rs +++ b/src/state.rs @@ -31,7 +31,7 @@ use { forker::ForkerProxy, format::Format, gfx_api::{ - AcquireSync, AlphaMode, BufferResv, GfxBlendBuffer, GfxContext, GfxError, + AcquireSync, AlphaMode, BufferResv, GfxApi, GfxBlendBuffer, GfxContext, GfxError, GfxFramebuffer, GfxTexture, PendingShmTransfer, ReleaseSync, STAGING_DOWNLOAD, SampleRect, SyncFile, }, @@ -135,12 +135,7 @@ use { }, ahash::AHashMap, bstr::ByteSlice, - jay_config::{ - PciId, - video::{GfxApi, Transform}, - window::TileState, - workspace::WorkspaceDisplayOrder, - }, + jay_config::{PciId, video::Transform, window::TileState, workspace::WorkspaceDisplayOrder}, std::{ cell::{Cell, RefCell}, fmt::{Debug, Formatter}, diff --git a/src/utils.rs b/src/utils.rs index 46356d09..55e1df56 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -21,7 +21,6 @@ pub mod event_listener; pub mod fdcloser; pub mod free_list; pub mod geometric_decay; -pub mod gfx_api_ext; pub mod hash_map_ext; pub mod line_logger; pub mod linkedlist; diff --git a/src/utils/gfx_api_ext.rs b/src/utils/gfx_api_ext.rs deleted file mode 100644 index 4dd7fc0d..00000000 --- a/src/utils/gfx_api_ext.rs +++ /dev/null @@ -1,25 +0,0 @@ -use jay_config::video::GfxApi; - -pub trait GfxApiExt: Sized { - fn to_str(&self) -> &'static str; - - fn from_str_lossy(s: &str) -> Option; -} - -impl GfxApiExt for GfxApi { - fn to_str(&self) -> &'static str { - match self { - GfxApi::OpenGl => "OpenGl", - GfxApi::Vulkan => "Vulkan", - _ => "unknown", - } - } - - fn from_str_lossy(s: &str) -> Option { - match &*s.to_ascii_lowercase() { - "opengl" => Some(Self::OpenGl), - "vulkan" => Some(Self::Vulkan), - _ => None, - } - } -} From 727a1bc68b2f4c50a6fbb80ac4ee0250bb85540c Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Tue, 24 Feb 2026 20:00:45 +0100 Subject: [PATCH 3/6] seat: add FallbackOutputMode --- src/config/handler.rs | 5 +++++ src/ifs/wl_seat.rs | 31 ++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/config/handler.rs b/src/config/handler.rs index 042af16b..112f8024 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -523,6 +523,9 @@ impl ConfigProxyHandler { seat: Seat, mode: FallbackOutputMode, ) -> Result<(), CphError> { + let Ok(mode) = mode.try_into() else { + return Err(CphError::UnknownFallbackOutputMode(mode)); + }; let seat = self.get_seat(seat)?; seat.set_fallback_output_mode(mode); Ok(()) @@ -3537,6 +3540,8 @@ enum CphError { UnknownBarPosition(BarPosition), #[error("Unknown gfx API {0:?}")] UnknownGfxApi(GfxApi), + #[error("Unknown fallback output mode {0:?}")] + UnknownFallbackOutputMode(FallbackOutputMode), } trait WithRequestName { diff --git a/src/ifs/wl_seat.rs b/src/ifs/wl_seat.rs index ec5d0431..0b8f2652 100644 --- a/src/ifs/wl_seat.rs +++ b/src/ifs/wl_seat.rs @@ -106,10 +106,11 @@ use { }, ahash::AHashMap, jay_config::{ - input::FallbackOutputMode, + input::FallbackOutputMode as ConfigFallbackOutputMode, keyboard::syms::{KeySym, SYM_Escape}, }, kbvm::Keycode, + linearize::Linearize, run_on_drop::on_drop, smallvec::SmallVec, std::{ @@ -258,6 +259,34 @@ enum MarkMode { Jump, } +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Linearize)] +pub enum FallbackOutputMode { + Cursor, + Focus, +} + +impl TryFrom for FallbackOutputMode { + type Error = (); + + fn try_from(value: ConfigFallbackOutputMode) -> Result { + let v = match value { + ConfigFallbackOutputMode::Cursor => FallbackOutputMode::Cursor, + ConfigFallbackOutputMode::Focus => FallbackOutputMode::Focus, + _ => return Err(()), + }; + Ok(v) + } +} + +impl Into for FallbackOutputMode { + fn into(self) -> ConfigFallbackOutputMode { + match self { + FallbackOutputMode::Cursor => ConfigFallbackOutputMode::Cursor, + FallbackOutputMode::Focus => ConfigFallbackOutputMode::Focus, + } + } +} + const CHANGE_CURSOR_MOVED: u32 = 1 << 0; const CHANGE_TREE: u32 = 1 << 1; From c99a2dfafac86a45610238d4fd9730064dd58652 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Tue, 24 Feb 2026 20:06:08 +0100 Subject: [PATCH 4/6] tree: add TileState --- src/config.rs | 4 +-- src/config/handler.rs | 14 ++++++--- src/ifs/wl_surface/x_surface/xwindow.rs | 3 +- .../wl_surface/xdg_surface/xdg_toplevel.rs | 3 +- src/state.rs | 6 ++-- src/tree.rs | 30 ++++++++++++++++++- 6 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/config.rs b/src/config.rs index 85724ff8..5e1b7c49 100644 --- a/src/config.rs +++ b/src/config.rs @@ -9,7 +9,7 @@ use { config::handler::ConfigProxyHandler, ifs::wl_seat::SeatId, state::State, - tree::ToplevelData, + tree::{TileState, ToplevelData}, utils::{ clonecell::CloneCell, nice::{JAY_NO_REALTIME, dont_allow_config_so}, @@ -29,7 +29,7 @@ use { input::{InputDevice, Seat, SwitchEvent}, keyboard::{mods::Modifiers, syms::KeySym}, video::{Connector, DrmDevice}, - window::{self, TileState}, + window::{self}, }, libloading::Library, std::{cell::Cell, io, mem, path::Path, ptr, rc::Rc}, diff --git a/src/config/handler.rs b/src/config/handler.rs index 112f8024..31cd05d2 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -29,8 +29,9 @@ use { theme::{Color, ThemeSized}, tree::{ ContainerNode, ContainerSplit, FloatNode, Node, NodeVisitorBase, OutputNode, - TearingMode, ToplevelData, ToplevelNode, VrrMode, WorkspaceNode, toplevel_create_split, - toplevel_parent_container, toplevel_set_floating, toplevel_set_workspace, + TearingMode, TileState, ToplevelData, ToplevelNode, VrrMode, WorkspaceNode, + toplevel_create_split, toplevel_parent_container, toplevel_set_floating, + toplevel_set_workspace, }, utils::{ asyncevent::AsyncEvent, @@ -72,7 +73,7 @@ use { Format as ConfigFormat, GfxApi, TearingMode as ConfigTearingMode, Transform, VrrMode as ConfigVrrMode, }, - window::{TileState, Window, WindowMatcher}, + window::{TileState as ConfigTileState, Window, WindowMatcher}, workspace::WorkspaceDisplayOrder, xwayland::XScalingMode, }, @@ -2289,8 +2290,11 @@ impl ConfigProxyHandler { fn handle_set_window_matcher_initial_tile_state( &self, matcher: WindowMatcher, - tile_state: TileState, + tile_state: ConfigTileState, ) -> Result<(), CphError> { + let Ok(tile_state) = tile_state.try_into() else { + return Err(CphError::UnknownTileState(tile_state)); + }; let m = self.get_window_matcher(matcher)?; self.window_matcher_initial_tile_state .set(matcher, (m, tile_state)); @@ -3542,6 +3546,8 @@ enum CphError { UnknownGfxApi(GfxApi), #[error("Unknown fallback output mode {0:?}")] UnknownFallbackOutputMode(FallbackOutputMode), + #[error("Unknown tile state {0:?}")] + UnknownTileState(ConfigTileState), } trait WithRequestName { diff --git a/src/ifs/wl_surface/x_surface/xwindow.rs b/src/ifs/wl_surface/x_surface/xwindow.rs index a1761d18..f1c68730 100644 --- a/src/ifs/wl_surface/x_surface/xwindow.rs +++ b/src/ifs/wl_surface/x_surface/xwindow.rs @@ -13,7 +13,7 @@ use { tree::{ ContainerSplit, Direction, FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, NodeLayerLink, NodeLocation, NodeVisitor, OutputNode, StackedNode, TileDragDestination, - ToplevelData, ToplevelNode, ToplevelNodeBase, ToplevelType, WorkspaceNode, + TileState, ToplevelData, ToplevelNode, ToplevelNodeBase, ToplevelType, WorkspaceNode, default_tile_drag_destination, }, utils::{clonecell::CloneCell, copyhashmap::CopyHashMap, linkedlist::LinkedNode}, @@ -22,7 +22,6 @@ use { xwayland::XWaylandEvent, }, bstr::BString, - jay_config::window::TileState, std::{ cell::{Cell, RefCell}, ops::{Deref, Not}, diff --git a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs index d8c6decf..4d85be92 100644 --- a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs +++ b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs @@ -26,7 +26,7 @@ use { state::State, tree::{ ContainerSplit, Direction, FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, - NodeLayerLink, NodeLocation, NodeVisitor, OutputNode, TileDragDestination, + NodeLayerLink, NodeLocation, NodeVisitor, OutputNode, TileDragDestination, TileState, ToplevelData, ToplevelNode, ToplevelNodeBase, ToplevelNodeId, ToplevelType, WorkspaceNode, default_tile_drag_destination, }, @@ -37,7 +37,6 @@ use { }, ahash::AHashMap, arrayvec::ArrayVec, - jay_config::window::TileState, std::{ cell::{Cell, RefCell}, fmt::{Debug, Formatter}, diff --git a/src/state.rs b/src/state.rs index e349bd3f..7e277113 100644 --- a/src/state.rs +++ b/src/state.rs @@ -96,8 +96,8 @@ use { tree::{ ContainerNode, ContainerSplit, Direction, DisplayNode, FindTreeUsecase, FloatNode, FoundNode, LatchListener, Node, NodeIds, NodeVisitorBase, OutputNode, PlaceholderNode, - TearingMode, ToplevelData, ToplevelNode, ToplevelNodeBase, VrrMode, WorkspaceNode, - WsMoveConfig, generic_node_visitor, move_ws_to_output, + TearingMode, TileState, ToplevelData, ToplevelNode, ToplevelNodeBase, VrrMode, + WorkspaceNode, WsMoveConfig, generic_node_visitor, move_ws_to_output, }, udmabuf::UdmabufHolder, utils::{ @@ -135,7 +135,7 @@ use { }, ahash::AHashMap, bstr::ByteSlice, - jay_config::{PciId, video::Transform, window::TileState, workspace::WorkspaceDisplayOrder}, + jay_config::{PciId, video::Transform, workspace::WorkspaceDisplayOrder}, std::{ cell::{Cell, RefCell}, fmt::{Debug, Formatter}, diff --git a/src/tree.rs b/src/tree.rs index 5aeddbba..36636d6c 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -23,7 +23,7 @@ use { renderer::Renderer, utils::{linkedlist::NodeRef, numcell::NumCell}, }, - jay_config::Direction as JayDirection, + jay_config::{Direction as JayDirection, window::TileState as ConfigTileState}, linearize::{Linearize, LinearizeExt}, std::{ fmt::{Debug, Display}, @@ -46,6 +46,34 @@ mod toplevel; mod walker; mod workspace; +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Linearize)] +pub enum TileState { + Tiled, + Floating, +} + +impl TryFrom for TileState { + type Error = (); + + fn try_from(value: ConfigTileState) -> Result { + let v = match value { + ConfigTileState::Tiled => TileState::Tiled, + ConfigTileState::Floating => TileState::Floating, + _ => return Err(()), + }; + Ok(v) + } +} + +impl Into for TileState { + fn into(self) -> ConfigTileState { + match self { + TileState::Tiled => ConfigTileState::Tiled, + TileState::Floating => ConfigTileState::Floating, + } + } +} + #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum Direction { Unspecified, From 8b0bb61ee0c97dad8e8d35f8efc27f6e6982d91e Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Tue, 24 Feb 2026 20:22:24 +0100 Subject: [PATCH 5/6] tree: add Transform --- src/backends/metal/present.rs | 2 +- src/cli/randr.rs | 5 +- src/compositor.rs | 4 +- src/config/handler.rs | 2 +- src/cursor_user.rs | 2 +- src/damage.rs | 6 +- src/gfx_api.rs | 6 +- .../ext_image_copy_capture_frame_v1.rs | 8 +- src/ifs/head_management.rs | 4 +- .../jay_head_ext_compositor_space_info_v1.rs | 1 - ...ead_ext_compositor_space_transformer_v1.rs | 3 +- src/ifs/jay_randr.rs | 6 +- src/ifs/jay_screencast.rs | 5 +- src/ifs/wl_output.rs | 5 +- src/ifs/wl_surface.rs | 5 +- .../zwlr_output_configuration_head.rs | 4 +- .../wlr_output_manager/zwlr_output_head_v1.rs | 8 +- src/renderer/renderer_base.rs | 3 +- src/screenshoter.rs | 2 +- src/state.rs | 6 +- src/tasks/connector.rs | 3 +- src/tree.rs | 112 +++++++++++++++++- src/tree/output.rs | 5 +- src/utils.rs | 1 - src/utils/transform_ext.rs | 81 ------------- 25 files changed, 153 insertions(+), 136 deletions(-) delete mode 100644 src/utils/transform_ext.rs diff --git a/src/backends/metal/present.rs b/src/backends/metal/present.rs index 810531be..722faef2 100644 --- a/src/backends/metal/present.rs +++ b/src/backends/metal/present.rs @@ -18,7 +18,7 @@ use { time::Time, tracy::FrameName, tree::OutputNode, - utils::{errorfmt::ErrorFmt, oserror::OsError, transform_ext::TransformExt}, + utils::{errorfmt::ErrorFmt, oserror::OsError}, video::{ dmabuf::DmaBufId, drm::{ diff --git a/src/cli/randr.rs b/src/cli/randr.rs index b07ab20e..9ec490b5 100644 --- a/src/cli/randr.rs +++ b/src/cli/randr.rs @@ -7,7 +7,8 @@ use { ifs::wl_output::BlendSpace, scale::Scale, tools::tool_client::{Handle, ToolClient, with_tool_client}, - utils::{errorfmt::ErrorFmt, ordered_float::F64, transform_ext::TransformExt}, + tree::Transform, + utils::{errorfmt::ErrorFmt, ordered_float::F64}, wire::{JayRandrId, jay_compositor, jay_randr}, }, clap::{ @@ -15,7 +16,7 @@ use { builder::{PossibleValue, PossibleValuesParser}, }, isnt::std_1::vec::IsntVecExt, - jay_config::video::{TearingMode, Transform, VrrMode}, + jay_config::video::{TearingMode, VrrMode}, linearize::LinearizeExt, std::{ cell::RefCell, diff --git a/src/compositor.rs b/src/compositor.rs index 15550c80..0328260a 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -57,7 +57,7 @@ use { tasks::{self, handle_const_40hz_latch, idle}, tracy::enable_profiler, tree::{ - DisplayNode, NodeIds, OutputNode, TearingMode, VrrMode, WorkspaceNode, + DisplayNode, NodeIds, OutputNode, TearingMode, Transform, VrrMode, WorkspaceNode, container_layout, container_render_positions, container_render_titles, float_layout, float_titles, output_render_data, placeholder_render_textures, }, @@ -82,7 +82,7 @@ use { }, ahash::AHashSet, forker::ForkerProxy, - jay_config::{_private::DEFAULT_SEAT_NAME, video::Transform, workspace::WorkspaceDisplayOrder}, + jay_config::{_private::DEFAULT_SEAT_NAME, workspace::WorkspaceDisplayOrder}, std::{ cell::{Cell, RefCell}, env, diff --git a/src/config/handler.rs b/src/config/handler.rs index 31cd05d2..89c74bf3 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -1561,7 +1561,7 @@ impl ConfigProxyHandler { transform: Transform, ) -> Result<(), CphError> { let connector = self.get_output_node(connector)?; - connector.update_transform(transform); + connector.update_transform(transform.into()); Ok(()) } diff --git a/src/cursor_user.rs b/src/cursor_user.rs index b014728b..3b783636 100644 --- a/src/cursor_user.rs +++ b/src/cursor_user.rs @@ -10,7 +10,7 @@ use { tree::OutputNode, utils::{ clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, - hash_map_ext::HashMapExt, rc_eq::rc_eq, transform_ext::TransformExt, + hash_map_ext::HashMapExt, rc_eq::rc_eq, }, }, std::{cell::Cell, ops::Deref, rc::Rc}, diff --git a/src/damage.rs b/src/damage.rs index 4de915e9..a4785155 100644 --- a/src/damage.rs +++ b/src/damage.rs @@ -9,12 +9,10 @@ use { state::State, theme::Color, time::Time, - utils::{ - asyncevent::AsyncEvent, errorfmt::ErrorFmt, timer::TimerFd, transform_ext::TransformExt, - }, + tree::Transform, + utils::{asyncevent::AsyncEvent, errorfmt::ErrorFmt, timer::TimerFd}, }, isnt::std_1::primitive::IsntSliceExt, - jay_config::video::Transform, std::{ cell::{Cell, RefCell}, collections::VecDeque, diff --git a/src/gfx_api.rs b/src/gfx_api.rs index d5104b60..3e5fb256 100644 --- a/src/gfx_api.rs +++ b/src/gfx_api.rs @@ -12,13 +12,13 @@ use { scale::Scale, state::State, theme::Color, - tree::{Node, OutputNode}, - utils::{clonecell::UnsafeCellCloneSafe, transform_ext::TransformExt}, + tree::{Node, OutputNode, Transform}, + utils::clonecell::UnsafeCellCloneSafe, video::{Modifier, dmabuf::DmaBuf, drm::sync_obj::SyncObjCtx}, }, ahash::AHashMap, indexmap::{IndexMap, IndexSet}, - jay_config::video::{GfxApi as ConfigGfxApi, Transform}, + jay_config::video::GfxApi as ConfigGfxApi, linearize::Linearize, std::{ any::Any, diff --git a/src/ifs/ext_image_copy/ext_image_copy_capture_frame_v1.rs b/src/ifs/ext_image_copy/ext_image_copy_capture_frame_v1.rs index 5f47052b..c48cfaa0 100644 --- a/src/ifs/ext_image_copy/ext_image_copy_capture_frame_v1.rs +++ b/src/ifs/ext_image_copy/ext_image_copy_capture_frame_v1.rs @@ -14,8 +14,8 @@ use { leaks::Tracker, object::Object, rect::Region, - tree::{Node, OutputNode}, - utils::{cell_ext::CellExt, errorfmt::ErrorFmt, transform_ext::TransformExt}, + tree::{self, Node, OutputNode}, + utils::{cell_ext::CellExt, errorfmt::ErrorFmt}, wire::{ExtImageCopyCaptureFrameV1Id, ext_image_copy_capture_frame_v1::*}, }, std::rc::Rc, @@ -216,7 +216,7 @@ impl ExtImageCopyCaptureFrameV1 { &fb, aq, re, - jay_config::video::Transform::None, + tree::Transform::None, self.client.state.color_manager.srgb_gamma22(), on.global.pos.get(), render_hardware_cursors, @@ -244,7 +244,7 @@ impl ExtImageCopyCaptureFrameV1 { true, true, false, - jay_config::video::Transform::None, + tree::Transform::None, None, self.client.state.color_manager.srgb_linear(), ) diff --git a/src/ifs/head_management.rs b/src/ifs/head_management.rs index d7435cb0..f087ccfd 100644 --- a/src/ifs/head_management.rs +++ b/src/ifs/head_management.rs @@ -13,11 +13,11 @@ use { }, scale::Scale, state::OutputData, - tree::OutputNode, + tree::{OutputNode, Transform}, utils::{copyhashmap::CopyHashMap, hash_map_ext::HashMapExt, rc_eq::RcEq}, wire::JayHeadManagerSessionV1Id, }, - jay_config::video::{TearingMode, Transform, VrrMode}, + jay_config::video::{TearingMode, VrrMode}, std::{ cell::{Cell, RefCell}, rc::Rc, diff --git a/src/ifs/head_management/jay_head_ext/jay_head_ext_compositor_space_info_v1.rs b/src/ifs/head_management/jay_head_ext/jay_head_ext_compositor_space_info_v1.rs index acffb919..49465e35 100644 --- a/src/ifs/head_management/jay_head_ext/jay_head_ext_compositor_space_info_v1.rs +++ b/src/ifs/head_management/jay_head_ext/jay_head_ext_compositor_space_info_v1.rs @@ -1,7 +1,6 @@ use { crate::{ ifs::head_management::HeadState, - utils::transform_ext::TransformExt, wire::{ jay_head_ext_compositor_space_info_v1::{ Disabled, Enabled, Inside, JayHeadExtCompositorSpaceInfoV1RequestHandler, Outside, diff --git a/src/ifs/head_management/jay_head_ext/jay_head_ext_compositor_space_transformer_v1.rs b/src/ifs/head_management/jay_head_ext/jay_head_ext_compositor_space_transformer_v1.rs index 4535c7af..d21b4ddf 100644 --- a/src/ifs/head_management/jay_head_ext/jay_head_ext_compositor_space_transformer_v1.rs +++ b/src/ifs/head_management/jay_head_ext/jay_head_ext_compositor_space_transformer_v1.rs @@ -1,7 +1,7 @@ use { crate::{ ifs::head_management::{HeadOp, HeadState}, - utils::transform_ext::TransformExt, + tree::Transform, wire::{ jay_head_ext_compositor_space_transformer_v1::{ JayHeadExtCompositorSpaceTransformerV1RequestHandler, SetTransform, @@ -10,7 +10,6 @@ use { jay_head_manager_ext_compositor_space_transformer_v1::JayHeadManagerExtCompositorSpaceTransformerV1RequestHandler, }, }, - jay_config::video::Transform, std::rc::Rc, }; diff --git a/src/ifs/jay_randr.rs b/src/ifs/jay_randr.rs index f80d15e9..2a462f46 100644 --- a/src/ifs/jay_randr.rs +++ b/src/ifs/jay_randr.rs @@ -10,11 +10,11 @@ use { object::{Object, Version}, scale::Scale, state::{ConnectorData, DrmDevData, OutputData, State}, - tree::{OutputNode, TearingMode, VrrMode}, - utils::{errorfmt::ErrorFmt, transform_ext::TransformExt}, + tree::{OutputNode, TearingMode, Transform, VrrMode}, + utils::errorfmt::ErrorFmt, wire::{JayRandrId, jay_randr::*}, }, - jay_config::video::{TearingMode as ConfigTearingMode, Transform, VrrMode as ConfigVrrMode}, + jay_config::video::{TearingMode as ConfigTearingMode, VrrMode as ConfigVrrMode}, linearize::LinearizeExt, std::rc::Rc, thiserror::Error, diff --git a/src/ifs/jay_screencast.rs b/src/ifs/jay_screencast.rs index 0b392b40..9ec24eb1 100644 --- a/src/ifs/jay_screencast.rs +++ b/src/ifs/jay_screencast.rs @@ -12,7 +12,9 @@ use { object::{Object, Version}, scale::Scale, state::State, - tree::{LatchListener, OutputNode, ToplevelNode, WorkspaceNode, WorkspaceNodeId}, + tree::{ + LatchListener, OutputNode, ToplevelNode, Transform, WorkspaceNode, WorkspaceNodeId, + }, utils::{ clonecell::{CloneCell, UnsafeCellCloneSafe}, errorfmt::ErrorFmt, @@ -24,7 +26,6 @@ use { wire::{JayScreencastId, jay_screencast::*}, }, ahash::AHashSet, - jay_config::video::Transform, std::{ cell::{Cell, RefCell}, ops::DerefMut, diff --git a/src/ifs/wl_output.rs b/src/ifs/wl_output.rs index f6e2bbe2..fa83b826 100644 --- a/src/ifs/wl_output.rs +++ b/src/ifs/wl_output.rs @@ -21,15 +21,14 @@ use { object::{Object, Version}, rect::Rect, state::{ConnectorData, State}, - tree::{OutputNode, TearingMode, VrrMode, calculate_logical_size}, + tree::{OutputNode, TearingMode, Transform, VrrMode, calculate_logical_size}, utils::{ cell_ext::CellExt, clonecell::CloneCell, copyhashmap::CopyHashMap, ordered_float::F64, - rc_eq::rc_eq, transform_ext::TransformExt, + rc_eq::rc_eq, }, wire::{WlOutputId, WpColorManagementOutputV1Id, ZxdgOutputV1Id, wl_output::*}, }, ahash::AHashMap, - jay_config::video::Transform, linearize::Linearize, std::{ cell::{Cell, RefCell}, diff --git a/src/ifs/wl_surface.rs b/src/ifs/wl_surface.rs index 4477d61c..9cc4bb3d 100644 --- a/src/ifs/wl_surface.rs +++ b/src/ifs/wl_surface.rs @@ -79,13 +79,13 @@ use { tree::{ BeforeLatchListener, BeforeLatchResult, ContainerNode, FindTreeResult, FoundNode, LatchListener, Node, NodeId, NodeLayerLink, NodeLocation, NodeVisitor, NodeVisitorBase, - OutputNode, PlaceholderNode, PresentationListener, ToplevelNode, VblankListener, + OutputNode, PlaceholderNode, PresentationListener, ToplevelNode, Transform, + VblankListener, }, utils::{ cell_ext::CellExt, clonecell::CloneCell, copyhashmap::CopyHashMap, double_buffered::DoubleBuffered, errorfmt::ErrorFmt, event_listener::EventListener, linkedlist::LinkedList, numcell::NumCell, smallmap::SmallMap, - transform_ext::TransformExt, }, video::{ dmabuf::DMA_BUF_SYNC_READ, @@ -99,7 +99,6 @@ use { }, ahash::AHashMap, isnt::std_1::{primitive::IsntSliceExt, vec::IsntVecExt}, - jay_config::video::Transform, std::{ cell::{Cell, RefCell}, collections::hash_map::{Entry, OccupiedEntry}, diff --git a/src/ifs/wlr_output_manager/zwlr_output_configuration_head.rs b/src/ifs/wlr_output_manager/zwlr_output_configuration_head.rs index 9e1d32e2..13398c3d 100644 --- a/src/ifs/wlr_output_manager/zwlr_output_configuration_head.rs +++ b/src/ifs/wlr_output_manager/zwlr_output_configuration_head.rs @@ -9,11 +9,9 @@ use { leaks::Tracker, object::{Object, Version}, scale::Scale, - tree::VrrMode, - utils::transform_ext::TransformExt, + tree::{Transform, VrrMode}, wire::{ZwlrOutputConfigurationHeadV1Id, zwlr_output_configuration_head_v1::*}, }, - jay_config::video::Transform, std::{cell::RefCell, rc::Rc}, thiserror::Error, }; diff --git a/src/ifs/wlr_output_manager/zwlr_output_head_v1.rs b/src/ifs/wlr_output_manager/zwlr_output_head_v1.rs index 21d773a6..9debdccf 100644 --- a/src/ifs/wlr_output_manager/zwlr_output_head_v1.rs +++ b/src/ifs/wlr_output_manager/zwlr_output_head_v1.rs @@ -11,12 +11,10 @@ use { object::{Object, Version}, scale, state::OutputData, - tree::VrrMode, - utils::transform_ext::TransformExt, + tree::{self, VrrMode}, wire::{ZwlrOutputHeadV1Id, zwlr_output_head_v1::*}, }, ahash::AHashMap, - jay_config::video, std::rc::Rc, thiserror::Error, }; @@ -111,7 +109,7 @@ impl ZwlrOutputHeadV1 { }); } - pub fn send_transform(&self, transform: video::Transform) { + pub fn send_transform(&self, transform: tree::Transform) { self.client.event(Transform { self_id: self.id, transform: transform.to_wl(), @@ -173,7 +171,7 @@ impl ZwlrOutputHeadV1 { } } - pub fn hande_transform_change(&self, transform: video::Transform) { + pub fn hande_transform_change(&self, transform: tree::Transform) { self.send_transform(transform); self.manager.schedule_done(); } diff --git a/src/renderer/renderer_base.rs b/src/renderer/renderer_base.rs index ab84c6a9..7963f79b 100644 --- a/src/renderer/renderer_base.rs +++ b/src/renderer/renderer_base.rs @@ -8,9 +8,8 @@ use { rect::Rect, scale::Scale, theme::Color, - utils::transform_ext::TransformExt, + tree::Transform, }, - jay_config::video::Transform, std::rc::Rc, }; diff --git a/src/screenshoter.rs b/src/screenshoter.rs index 0585f098..732aa9f5 100644 --- a/src/screenshoter.rs +++ b/src/screenshoter.rs @@ -5,10 +5,10 @@ use { gfx_api::{AcquireSync, GfxError, ReleaseSync, needs_render_usage}, scale::Scale, state::State, + tree::Transform, video::drm::DrmError, }, indexmap::IndexMap, - jay_config::video::Transform, std::{ops::Deref, rc::Rc}, thiserror::Error, uapi::OwnedFd, diff --git a/src/state.rs b/src/state.rs index 7e277113..c7a52da6 100644 --- a/src/state.rs +++ b/src/state.rs @@ -96,8 +96,8 @@ use { tree::{ ContainerNode, ContainerSplit, Direction, DisplayNode, FindTreeUsecase, FloatNode, FoundNode, LatchListener, Node, NodeIds, NodeVisitorBase, OutputNode, PlaceholderNode, - TearingMode, TileState, ToplevelData, ToplevelNode, ToplevelNodeBase, VrrMode, - WorkspaceNode, WsMoveConfig, generic_node_visitor, move_ws_to_output, + TearingMode, TileState, ToplevelData, ToplevelNode, ToplevelNodeBase, Transform, + VrrMode, WorkspaceNode, WsMoveConfig, generic_node_visitor, move_ws_to_output, }, udmabuf::UdmabufHolder, utils::{ @@ -135,7 +135,7 @@ use { }, ahash::AHashMap, bstr::ByteSlice, - jay_config::{PciId, video::Transform, workspace::WorkspaceDisplayOrder}, + jay_config::{PciId, workspace::WorkspaceDisplayOrder}, std::{ cell::{Cell, RefCell}, fmt::{Debug, Formatter}, diff --git a/src/tasks/connector.rs b/src/tasks/connector.rs index fdb789a1..bd4afc00 100644 --- a/src/tasks/connector.rs +++ b/src/tasks/connector.rs @@ -13,12 +13,11 @@ use { }, output_schedule::OutputSchedule, state::{ConnectorData, OutputData, State}, - tree::{OutputNode, WsMoveConfig, move_ws_to_output}, + tree::{OutputNode, Transform, WsMoveConfig, move_ws_to_output}, utils::{ asyncevent::AsyncEvent, clonecell::CloneCell, hash_map_ext::HashMapExt, rc_eq::RcEq, }, }, - jay_config::video::Transform, std::{ cell::{Cell, RefCell}, collections::VecDeque, diff --git a/src/tree.rs b/src/tree.rs index 36636d6c..14d46773 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -4,6 +4,10 @@ use { client::{Client, ClientId}, fixed::Fixed, ifs::{ + wl_output::{ + TF_90, TF_180, TF_270, TF_FLIPPED, TF_FLIPPED_90, TF_FLIPPED_180, TF_FLIPPED_270, + TF_NORMAL, + }, wl_seat::{ Dnd, NodeSeatState, WlSeatGlobal, tablet::{ @@ -23,7 +27,10 @@ use { renderer::Renderer, utils::{linkedlist::NodeRef, numcell::NumCell}, }, - jay_config::{Direction as JayDirection, window::TileState as ConfigTileState}, + jay_config::{ + Direction as JayDirection, video::Transform as ConfigTransform, + window::TileState as ConfigTileState, + }, linearize::{Linearize, LinearizeExt}, std::{ fmt::{Debug, Display}, @@ -46,6 +53,109 @@ mod toplevel; mod walker; mod workspace; +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Default, Linearize)] +pub enum Transform { + #[default] + None, + Rotate90, + Rotate180, + Rotate270, + Flip, + FlipRotate90, + FlipRotate180, + FlipRotate270, +} + +impl From for Transform { + fn from(value: ConfigTransform) -> Self { + match value { + ConfigTransform::None => Transform::None, + ConfigTransform::Rotate90 => Transform::Rotate90, + ConfigTransform::Rotate180 => Transform::Rotate180, + ConfigTransform::Rotate270 => Transform::Rotate270, + ConfigTransform::Flip => Transform::Flip, + ConfigTransform::FlipRotate90 => Transform::FlipRotate90, + ConfigTransform::FlipRotate180 => Transform::FlipRotate180, + ConfigTransform::FlipRotate270 => Transform::FlipRotate270, + } + } +} + +impl Into for Transform { + fn into(self) -> ConfigTransform { + match self { + Transform::None => ConfigTransform::None, + Transform::Rotate90 => ConfigTransform::Rotate90, + Transform::Rotate180 => ConfigTransform::Rotate180, + Transform::Rotate270 => ConfigTransform::Rotate270, + Transform::Flip => ConfigTransform::Flip, + Transform::FlipRotate90 => ConfigTransform::FlipRotate90, + Transform::FlipRotate180 => ConfigTransform::FlipRotate180, + Transform::FlipRotate270 => ConfigTransform::FlipRotate270, + } + } +} + +impl Transform { + pub fn maybe_swap(self, (left, right): (T, T)) -> (T, T) { + match self { + Self::None | Self::Rotate180 | Self::Flip | Self::FlipRotate180 => (left, right), + Self::Rotate90 | Self::Rotate270 | Self::FlipRotate90 | Self::FlipRotate270 => { + (right, left) + } + } + } + + pub fn to_wl(self) -> i32 { + match self { + Self::None => TF_NORMAL, + Self::Rotate90 => TF_90, + Self::Rotate180 => TF_180, + Self::Rotate270 => TF_270, + Self::Flip => TF_FLIPPED, + Self::FlipRotate90 => TF_FLIPPED_90, + Self::FlipRotate180 => TF_FLIPPED_180, + Self::FlipRotate270 => TF_FLIPPED_270, + } + } + + pub fn from_wl(wl: i32) -> Option { + let tf = match wl { + TF_NORMAL => Self::None, + TF_90 => Self::Rotate90, + TF_180 => Self::Rotate180, + TF_270 => Self::Rotate270, + TF_FLIPPED => Self::Flip, + TF_FLIPPED_90 => Self::FlipRotate90, + TF_FLIPPED_180 => Self::FlipRotate180, + TF_FLIPPED_270 => Self::FlipRotate270, + _ => return None, + }; + Some(tf) + } + + pub fn apply_point(self, width: i32, height: i32, (x, y): (i32, i32)) -> (i32, i32) { + match self { + Self::None => (x, y), + Self::Rotate90 => (y, height - x), + Self::Rotate180 => (width - x, height - y), + Self::Rotate270 => (width - y, x), + Self::Flip => (width - x, y), + Self::FlipRotate90 => (y, x), + Self::FlipRotate180 => (x, height - y), + Self::FlipRotate270 => (width - y, height - x), + } + } + + pub fn inverse(self) -> Self { + match self { + Self::Rotate90 => Self::Rotate270, + Self::Rotate270 => Self::Rotate90, + _ => self, + } + } +} + #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Linearize)] pub enum TileState { Tiled, diff --git a/src/tree/output.rs b/src/tree/output.rs index ff4baad8..a1476001 100644 --- a/src/tree/output.rs +++ b/src/tree/output.rs @@ -46,7 +46,7 @@ use { theme::BarPosition, tree::{ Direction, FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, NodeLayerLink, - NodeLocation, PinnedNode, StackedNode, TddType, TileDragDestination, + NodeLocation, PinnedNode, StackedNode, TddType, TileDragDestination, Transform, WorkspaceDragDestination, WorkspaceNode, WorkspaceNodeId, walker::NodeVisitor, }, utils::{ @@ -60,7 +60,6 @@ use { linkedlist::{LinkedList, NodeRef}, on_drop_event::OnDropEvent, scroller::Scroller, - transform_ext::TransformExt, }, wire::{ ExtImageCopyCaptureSessionV1Id, JayOutputId, JayScreencastId, ZwlrScreencopyFrameV1Id, @@ -68,7 +67,7 @@ use { }, ahash::AHashMap, jay_config::{ - video::{TearingMode as ConfigTearingMode, Transform, VrrMode as ConfigVrrMode}, + video::{TearingMode as ConfigTearingMode, VrrMode as ConfigVrrMode}, workspace::WorkspaceDisplayOrder, }, smallvec::SmallVec, diff --git a/src/utils.rs b/src/utils.rs index 55e1df56..109bb822 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -58,7 +58,6 @@ pub mod syncqueue; pub mod threshold_counter; pub mod timer; pub mod toplevel_identifier; -pub mod transform_ext; pub mod tri; pub mod unlink_on_drop; pub mod vec_ext; diff --git a/src/utils/transform_ext.rs b/src/utils/transform_ext.rs deleted file mode 100644 index 0506bf42..00000000 --- a/src/utils/transform_ext.rs +++ /dev/null @@ -1,81 +0,0 @@ -use { - crate::ifs::wl_output::{ - TF_90, TF_180, TF_270, TF_FLIPPED, TF_FLIPPED_90, TF_FLIPPED_180, TF_FLIPPED_270, TF_NORMAL, - }, - jay_config::video::{ - Transform, - Transform::{ - Flip, FlipRotate90, FlipRotate180, FlipRotate270, None, Rotate90, Rotate180, Rotate270, - }, - }, -}; - -pub trait TransformExt: Sized { - fn maybe_swap(self, args: (T, T)) -> (T, T); - - fn to_wl(self) -> i32; - - fn from_wl(wl: i32) -> Option; - - fn apply_point(self, width: i32, height: i32, point: (i32, i32)) -> (i32, i32); - - fn inverse(self) -> Self; -} - -impl TransformExt for Transform { - fn maybe_swap(self, (left, right): (T, T)) -> (T, T) { - match self { - None | Rotate180 | Flip | FlipRotate180 => (left, right), - Rotate90 | Rotate270 | FlipRotate90 | FlipRotate270 => (right, left), - } - } - - fn to_wl(self) -> i32 { - match self { - None => TF_NORMAL, - Rotate90 => TF_90, - Rotate180 => TF_180, - Rotate270 => TF_270, - Flip => TF_FLIPPED, - FlipRotate90 => TF_FLIPPED_90, - FlipRotate180 => TF_FLIPPED_180, - FlipRotate270 => TF_FLIPPED_270, - } - } - - fn from_wl(wl: i32) -> Option { - let tf = match wl { - TF_NORMAL => None, - TF_90 => Rotate90, - TF_180 => Rotate180, - TF_270 => Rotate270, - TF_FLIPPED => Flip, - TF_FLIPPED_90 => FlipRotate90, - TF_FLIPPED_180 => FlipRotate180, - TF_FLIPPED_270 => FlipRotate270, - _ => return Option::None, - }; - Some(tf) - } - - fn apply_point(self, width: i32, height: i32, (x, y): (i32, i32)) -> (i32, i32) { - match self { - None => (x, y), - Rotate90 => (y, height - x), - Rotate180 => (width - x, height - y), - Rotate270 => (width - y, x), - Flip => (width - x, y), - FlipRotate90 => (y, x), - FlipRotate180 => (x, height - y), - FlipRotate270 => (width - y, height - x), - } - } - - fn inverse(self) -> Self { - match self { - Rotate90 => Rotate270, - Rotate270 => Rotate90, - _ => self, - } - } -} From 1677d481f928f4e7f706d112a012e65f0b002080 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Tue, 24 Feb 2026 20:26:57 +0100 Subject: [PATCH 6/6] tree: add WorkspaceDisplayOrder --- src/compositor.rs | 9 +++++---- src/config/handler.rs | 2 +- src/state.rs | 5 +++-- src/tree.rs | 26 ++++++++++++++++++++++++++ src/tree/output.rs | 8 +++----- src/tree/workspace.rs | 5 ++--- 6 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/compositor.rs b/src/compositor.rs index 0328260a..a6fe9454 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -57,9 +57,10 @@ use { tasks::{self, handle_const_40hz_latch, idle}, tracy::enable_profiler, tree::{ - DisplayNode, NodeIds, OutputNode, TearingMode, Transform, VrrMode, WorkspaceNode, - container_layout, container_render_positions, container_render_titles, float_layout, - float_titles, output_render_data, placeholder_render_textures, + DisplayNode, NodeIds, OutputNode, TearingMode, Transform, VrrMode, + WorkspaceDisplayOrder, WorkspaceNode, container_layout, container_render_positions, + container_render_titles, float_layout, float_titles, output_render_data, + placeholder_render_textures, }, user_session::import_environment, utils::{ @@ -82,7 +83,7 @@ use { }, ahash::AHashSet, forker::ForkerProxy, - jay_config::{_private::DEFAULT_SEAT_NAME, workspace::WorkspaceDisplayOrder}, + jay_config::_private::DEFAULT_SEAT_NAME, std::{ cell::{Cell, RefCell}, env, diff --git a/src/config/handler.rs b/src/config/handler.rs index 89c74bf3..a82088c5 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -1465,7 +1465,7 @@ impl ConfigProxyHandler { } fn handle_set_workspace_display_order(&self, order: WorkspaceDisplayOrder) { - self.state.workspace_display_order.set(order); + self.state.workspace_display_order.set(order.into()); for output in self.state.root.outputs.lock().values() { output.handle_workspace_display_order_update(); } diff --git a/src/state.rs b/src/state.rs index c7a52da6..b9908d62 100644 --- a/src/state.rs +++ b/src/state.rs @@ -97,7 +97,8 @@ use { ContainerNode, ContainerSplit, Direction, DisplayNode, FindTreeUsecase, FloatNode, FoundNode, LatchListener, Node, NodeIds, NodeVisitorBase, OutputNode, PlaceholderNode, TearingMode, TileState, ToplevelData, ToplevelNode, ToplevelNodeBase, Transform, - VrrMode, WorkspaceNode, WsMoveConfig, generic_node_visitor, move_ws_to_output, + VrrMode, WorkspaceDisplayOrder, WorkspaceNode, WsMoveConfig, generic_node_visitor, + move_ws_to_output, }, udmabuf::UdmabufHolder, utils::{ @@ -135,7 +136,7 @@ use { }, ahash::AHashMap, bstr::ByteSlice, - jay_config::{PciId, workspace::WorkspaceDisplayOrder}, + jay_config::PciId, std::{ cell::{Cell, RefCell}, fmt::{Debug, Formatter}, diff --git a/src/tree.rs b/src/tree.rs index 14d46773..50a9624b 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -30,6 +30,7 @@ use { jay_config::{ Direction as JayDirection, video::Transform as ConfigTransform, window::TileState as ConfigTileState, + workspace::WorkspaceDisplayOrder as ConfigWorkspaceDisplayOrder, }, linearize::{Linearize, LinearizeExt}, std::{ @@ -53,6 +54,31 @@ mod toplevel; mod walker; mod workspace; +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Default, Linearize)] +pub enum WorkspaceDisplayOrder { + #[default] + Manual, + Sorted, +} + +impl From for WorkspaceDisplayOrder { + fn from(value: ConfigWorkspaceDisplayOrder) -> Self { + match value { + ConfigWorkspaceDisplayOrder::Manual => WorkspaceDisplayOrder::Manual, + ConfigWorkspaceDisplayOrder::Sorted => WorkspaceDisplayOrder::Sorted, + } + } +} + +impl Into for WorkspaceDisplayOrder { + fn into(self) -> ConfigWorkspaceDisplayOrder { + match self { + WorkspaceDisplayOrder::Manual => ConfigWorkspaceDisplayOrder::Manual, + WorkspaceDisplayOrder::Sorted => ConfigWorkspaceDisplayOrder::Sorted, + } + } +} + #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Default, Linearize)] pub enum Transform { #[default] diff --git a/src/tree/output.rs b/src/tree/output.rs index a1476001..3c416a00 100644 --- a/src/tree/output.rs +++ b/src/tree/output.rs @@ -47,7 +47,8 @@ use { tree::{ Direction, FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, NodeLayerLink, NodeLocation, PinnedNode, StackedNode, TddType, TileDragDestination, Transform, - WorkspaceDragDestination, WorkspaceNode, WorkspaceNodeId, walker::NodeVisitor, + WorkspaceDisplayOrder, WorkspaceDragDestination, WorkspaceNode, WorkspaceNodeId, + walker::NodeVisitor, }, utils::{ asyncevent::AsyncEvent, @@ -66,10 +67,7 @@ use { }, }, ahash::AHashMap, - jay_config::{ - video::{TearingMode as ConfigTearingMode, VrrMode as ConfigVrrMode}, - workspace::WorkspaceDisplayOrder, - }, + jay_config::video::{TearingMode as ConfigTearingMode, VrrMode as ConfigVrrMode}, smallvec::SmallVec, std::{ cell::{Cell, RefCell}, diff --git a/src/tree/workspace.rs b/src/tree/workspace.rs index eb308c08..f60354a4 100644 --- a/src/tree/workspace.rs +++ b/src/tree/workspace.rs @@ -22,8 +22,8 @@ use { tree::{ ContainingNode, Direction, FindTreeResult, FindTreeUsecase, FloatNode, FoundNode, Node, NodeId, NodeLayerLink, NodeLocation, NodeVisitorBase, OutputNode, OutputNodeId, - PlaceholderNode, StackedNode, ToplevelNode, container::ContainerNode, - walker::NodeVisitor, + PlaceholderNode, StackedNode, ToplevelNode, WorkspaceDisplayOrder, + container::ContainerNode, walker::NodeVisitor, }, utils::{ clonecell::CloneCell, @@ -35,7 +35,6 @@ use { }, wire::JayWorkspaceId, }, - jay_config::workspace::WorkspaceDisplayOrder, std::{ cell::{Cell, RefCell}, fmt::Debug,