commit 2ff313b6dbe6a91375ce0c8879bd04bd81f680f0
parent 3dadec096115d65484b82aa8cab329c4da17f108
Author: deurzen <m.deurzen@tum.de>
Date: Sat, 13 Mar 2021 15:30:27 +0100
implements client decoration handling
Diffstat:
4 files changed, 208 insertions(+), 166 deletions(-)
diff --git a/src/core/client.rs b/src/core/client.rs
@@ -1,6 +1,8 @@
use crate::common::Ident;
use crate::common::Identify;
use crate::common::NO_EXTENTS;
+use crate::zone::Decoration;
+use crate::zone::Frame;
use winsys::common::Extents;
use winsys::common::Hex32;
use winsys::common::Pid;
@@ -26,7 +28,7 @@ pub struct Client {
inner_region: Region,
free_region: Region,
tile_region: Region,
- frame_extents: Option<Extents>,
+ decoration: Decoration,
size_hints: Option<SizeHints>,
warp_pos: Option<Pos>,
parent: Option<Window>,
@@ -80,12 +82,12 @@ impl Client {
context: 0,
workspace: 0,
window_type,
- active_region: Region::default(),
- previous_region: Region::default(),
- inner_region: Region::default(),
- free_region: Region::default(),
- tile_region: Region::default(),
- frame_extents: None,
+ active_region: Default::default(),
+ previous_region: Default::default(),
+ inner_region: Default::default(),
+ free_region: Default::default(),
+ tile_region: Default::default(),
+ decoration: Default::default(),
size_hints: None,
warp_pos: None,
parent: None,
@@ -229,16 +231,17 @@ impl Client {
&mut self,
active_region: &Region,
) {
- self.inner_region = if let Some(frame_extents) = self.frame_extents {
- let mut inner_region = *active_region - frame_extents;
+ self.inner_region = if let Some(frame) = self.decoration.frame {
+ let extents = frame.extents;
+ let mut inner_region = *active_region - extents;
- inner_region.pos.x = frame_extents.left as i32;
- inner_region.pos.y = frame_extents.top as i32;
+ inner_region.pos.x = extents.left as i32;
+ inner_region.pos.y = extents.top as i32;
inner_region.dim.w =
- active_region.dim.w - frame_extents.left - frame_extents.right;
+ active_region.dim.w - extents.left - extents.right;
inner_region.dim.h =
- active_region.dim.h - frame_extents.top - frame_extents.bottom;
+ active_region.dim.h - extents.top - extents.bottom;
inner_region
} else {
@@ -292,25 +295,21 @@ impl Client {
}
#[inline]
- pub fn frame_extents_unchecked(&self) -> Extents {
- if let Some(frame_extents) = self.frame_extents {
- frame_extents
- } else {
- NO_EXTENTS
- }
+ pub fn decoration(&self) -> &Decoration {
+ &self.decoration
}
#[inline]
- pub fn frame_extents(&self) -> &Option<Extents> {
- &self.frame_extents
+ pub fn frame_extents(&self) -> Extents {
+ NO_EXTENTS + self.decoration
}
#[inline]
- pub fn set_frame_extents(
+ pub fn set_decoration(
&mut self,
- frame_extents: Option<Extents>,
+ decoration: Decoration,
) {
- self.frame_extents = frame_extents;
+ self.decoration = decoration;
}
#[inline]
@@ -684,7 +683,7 @@ impl std::fmt::Debug for Client {
.field("inner_region", &self.inner_region)
.field("free_region", &self.free_region)
.field("tile_region", &self.tile_region)
- .field("frame_extents", &self.frame_extents)
+ .field("decoration", &self.decoration)
.field("size_hints", &self.size_hints)
.field("warp_pos", &self.warp_pos)
.field("parent", &self.parent.map(|parent| Hex32(parent)))
diff --git a/src/core/common.rs b/src/core/common.rs
@@ -11,14 +11,6 @@ macro_rules! WM_NAME (
() => { "wzrd" };
);
-pub const FOCUSED_FRAME_COLOR: Color = 0xD7005F;
-pub const URGENT_FRAME_COLOR: Color = 0xD08928;
-pub const REGULAR_DISOWNED_FRAME_COLOR: Color = 0x707070;
-pub const FOCUSED_DISOWNED_FRAME_COLOR: Color = 0x00AA80;
-pub const REGULAR_STICKY_FRAME_COLOR: Color = 0x6C9EF8;
-pub const FOCUSED_STICKY_FRAME_COLOR: Color = 0xB77FDB;
-pub const REGULAR_FRAME_COLOR: Color = 0x191A2A;
-
pub const MIN_WINDOW_DIM: Dim = Dim {
w: 75,
h: 50,
diff --git a/src/core/model.rs b/src/core/model.rs
@@ -4,13 +4,8 @@ use crate::client::Client;
use crate::common::Change;
use crate::common::Direction;
use crate::common::Index;
-use crate::common::FOCUSED_FRAME_COLOR;
-use crate::common::FOCUSED_STICKY_FRAME_COLOR;
use crate::common::FREE_EXTENTS;
use crate::common::MIN_WINDOW_DIM;
-use crate::common::REGULAR_FRAME_COLOR;
-use crate::common::REGULAR_STICKY_FRAME_COLOR;
-use crate::common::URGENT_FRAME_COLOR;
use crate::consume::get_spawner_pid;
use crate::cycle::Cycle;
use crate::cycle::InsertPos;
@@ -1066,27 +1061,53 @@ impl<'a> Model<'a> {
self.sync_focus();
}
- fn refresh_client(
+ fn redraw_client(
&self,
window: Window,
) {
if let Some(client) = self.client(window) {
- self.conn.set_window_background_color(
- client.frame(),
- if client.is_focused() {
- if client.is_sticky() {
- FOCUSED_STICKY_FRAME_COLOR
+ let decoration = client.decoration();
+
+ if let Some(border) = decoration.border {
+ self.conn
+ .set_window_border_width(client.frame(), border.width);
+
+ self.conn.set_window_border_color(
+ client.frame(),
+ if client.is_focused() {
+ if client.is_sticky() {
+ border.colors.fsticky
+ } else {
+ border.colors.focused
+ }
+ } else if client.is_urgent() {
+ border.colors.urgent
+ } else if client.is_sticky() {
+ border.colors.rsticky
} else {
- FOCUSED_FRAME_COLOR
- }
- } else if client.is_urgent() {
- URGENT_FRAME_COLOR
- } else if client.is_sticky() {
- REGULAR_STICKY_FRAME_COLOR
- } else {
- REGULAR_FRAME_COLOR
- },
- );
+ border.colors.regular
+ },
+ );
+ }
+
+ if let Some(frame) = decoration.frame {
+ self.conn.set_window_background_color(
+ client.frame(),
+ if client.is_focused() {
+ if client.is_sticky() {
+ frame.colors.fsticky
+ } else {
+ frame.colors.focused
+ }
+ } else if client.is_urgent() {
+ frame.colors.urgent
+ } else if client.is_sticky() {
+ frame.colors.rsticky
+ } else {
+ frame.colors.regular
+ },
+ );
+ }
}
}
@@ -1099,9 +1120,7 @@ impl<'a> Model<'a> {
let client = self.client_mut(window).unwrap();
let region = &placement.region.unwrap();
- client.set_frame_extents(
- placement.decoration.frame.map(|f| f.extents),
- );
+ client.set_decoration(placement.decoration);
match placement.method {
PlacementMethod::Free => client.set_free_region(region),
@@ -1130,7 +1149,7 @@ impl<'a> Model<'a> {
PlacementMethod::Tile => &client.tile_region(),
});
- self.refresh_client(window);
+ self.redraw_client(window);
self.conn.update_window_offset(window, frame);
}
@@ -1145,7 +1164,7 @@ impl<'a> Model<'a> {
info!("mapping client with window {:#0x}", window);
self.conn.map_window(window);
self.conn.map_window(frame);
- self.refresh_client(window);
+ self.redraw_client(window);
let client = self.client_mut(window).unwrap();
client.set_mapped(true);
@@ -1855,7 +1874,7 @@ impl<'a> Model<'a> {
}
self.focus = Some(window);
- self.refresh_client(window);
+ self.redraw_client(window);
self.apply_stack(client_workspace_index);
}
}
@@ -1869,16 +1888,14 @@ impl<'a> Model<'a> {
let (window, frame) = client.windows();
let current_pos = self.conn.get_pointer_position();
- self.conn
- .set_window_background_color(frame, REGULAR_FRAME_COLOR);
- self.conn.regrab_buttons(frame);
-
info!("unfocusing client with window {:#0x}", window);
+ self.conn.regrab_buttons(frame);
+
let client = self.client_mut(window).unwrap();
client.set_warp_pos(current_pos);
client.set_focused(false);
- self.refresh_client(window);
+ self.redraw_client(window);
}
}
@@ -2144,7 +2161,7 @@ impl<'a> Model<'a> {
}
}
- self.refresh_client(window);
+ self.redraw_client(window);
}
fn unstick(
@@ -2180,7 +2197,7 @@ impl<'a> Model<'a> {
}
}
- self.refresh_client(window);
+ self.redraw_client(window);
}
pub fn iconify_focus(&mut self) {
@@ -2316,28 +2333,15 @@ impl<'a> Model<'a> {
},
}
- let id = self.zone_manager.client_zone(window);
- let extents = *client.frame_extents();
- let decoration = Decoration {
- border: None,
- frame: extents.map(|e| Frame {
- extents: e,
- colors: Default::default(),
- }),
- };
-
let placement = Placement {
method: PlacementMethod::Free,
kind: PlacementKind::Client(window),
- zone: id,
+ zone: self.zone_manager.client_zone(window),
region: Some(region),
- // TODO: zone change: should be proper frame
- decoration,
+ decoration: *client.decoration(),
};
- // TODO: zone change
self.update_client_placement(&placement);
- // TODO: zone change
self.place_client(window, placement.method);
}
}
@@ -2376,22 +2380,12 @@ impl<'a> Model<'a> {
Edge::Bottom => region.pos.y += step,
}
- let id = self.zone_manager.client_zone(window);
- let extents = *client.frame_extents();
-
let placement = Placement {
method: PlacementMethod::Free,
kind: PlacementKind::Client(window),
- zone: id,
+ zone: self.zone_manager.client_zone(window),
region: Some(region),
- // TODO: zone change: should be proper frame
- decoration: Decoration {
- border: None,
- frame: extents.map(|e| Frame {
- extents: e,
- colors: Default::default(),
- }),
- },
+ decoration: *client.decoration(),
};
self.update_client_placement(&placement);
@@ -2407,7 +2401,7 @@ impl<'a> Model<'a> {
) {
if let Some(client) = self.client(window) {
if self.is_free(client) {
- let frame_extents = client.frame_extents_unchecked();
+ let frame_extents = client.frame_extents();
let original_region = *client.free_region();
let region = original_region;
let window = client.window();
@@ -2453,22 +2447,12 @@ impl<'a> Model<'a> {
region.pos.x -= width_shift;
region.pos.y -= height_shift;
- let id = self.zone_manager.client_zone(window);
- let extents = *client.frame_extents();
-
let placement = Placement {
method: PlacementMethod::Free,
kind: PlacementKind::Client(window),
- zone: id,
+ zone: self.zone_manager.client_zone(window),
region: Some(region),
- // TODO: zone change: should be proper frame
- decoration: Decoration {
- border: None,
- frame: extents.map(|e| Frame {
- extents: e,
- colors: Default::default(),
- }),
- },
+ decoration: *client.decoration(),
};
self.update_client_placement(&placement);
@@ -2495,7 +2479,7 @@ impl<'a> Model<'a> {
) {
if let Some(client) = self.client(window) {
if self.is_free(client) {
- let frame_extents = client.frame_extents_unchecked();
+ let frame_extents = client.frame_extents();
let window = client.window();
let mut region =
(*client.free_region()).without_extents(&frame_extents);
@@ -2563,23 +2547,14 @@ impl<'a> Model<'a> {
}
let window = client.window();
- let id = self.zone_manager.client_zone(window);
let region = region.with_extents(&frame_extents);
- let extents = *client.frame_extents();
let placement = Placement {
method: PlacementMethod::Free,
kind: PlacementKind::Client(window),
- zone: id,
+ zone: self.zone_manager.client_zone(window),
region: Some(region),
- // TODO: zone change: should be proper frame
- decoration: Decoration {
- border: None,
- frame: extents.map(|e| Frame {
- extents: e,
- colors: Default::default(),
- }),
- },
+ decoration: *client.decoration(),
};
self.update_client_placement(&placement);
@@ -2628,8 +2603,6 @@ impl<'a> Model<'a> {
self.move_buffer.window_region()
{
let window = client.window();
- let id = self.zone_manager.client_zone(window);
- let extents = *client.frame_extents();
let region = Region {
pos: window_region.pos + grip_pos.dist(*pos),
dim: client.free_region().dim,
@@ -2638,16 +2611,9 @@ impl<'a> Model<'a> {
let placement = Placement {
method: PlacementMethod::Free,
kind: PlacementKind::Client(window),
- zone: id,
+ zone: self.zone_manager.client_zone(window),
region: Some(region),
- // TODO: zone change: should be proper frame
- decoration: Decoration {
- border: None,
- frame: extents.map(|e| Frame {
- extents: e,
- colors: Default::default(),
- }),
- },
+ decoration: *client.decoration(),
};
self.update_client_placement(&placement);
@@ -2702,7 +2668,7 @@ impl<'a> Model<'a> {
let current_pos = *pos;
let previous_region = *client.previous_region();
- let frame_extents = client.frame_extents_unchecked();
+ let frame_extents = client.frame_extents();
let (pos, mut dim) = client
.free_region()
.without_extents(&frame_extents)
@@ -3164,7 +3130,7 @@ impl<'a> Model<'a> {
if let Some(client) = self.client_any_mut(window) {
client.set_urgent(true);
- self.refresh_client(window);
+ self.redraw_client(window);
}
},
_ => {},
@@ -3184,7 +3150,7 @@ impl<'a> Model<'a> {
if let Some(client) = self.client_any_mut(window) {
client.set_urgent(false);
- self.refresh_client(window);
+ self.redraw_client(window);
}
},
_ => {},
@@ -3261,7 +3227,7 @@ impl<'a> Model<'a> {
if let Some(client) = self.client(window) {
if self.is_free(client) {
let window = client.window();
- let frame_extents = client.frame_extents_unchecked();
+ let frame_extents = client.frame_extents();
let region = if event_window == window {
Some(Region {
@@ -3315,22 +3281,12 @@ impl<'a> Model<'a> {
});
if let Some(region) = region {
- let id = self.zone_manager.client_zone(window);
- let extents = *client.frame_extents();
-
let placement = Placement {
method: PlacementMethod::Free,
kind: PlacementKind::Client(window),
- zone: id,
+ zone: self.zone_manager.client_zone(window),
region: Some(region),
- // TODO: zone change: should be proper frame
- decoration: Decoration {
- border: None,
- frame: extents.map(|e| Frame {
- extents: e,
- colors: Default::default(),
- }),
- },
+ decoration: *client.decoration(),
};
self.update_client_placement(&placement);
@@ -3446,7 +3402,7 @@ impl<'a> Model<'a> {
return;
}
- let frame_extents = client.frame_extents_unchecked();
+ let frame_extents = client.frame_extents();
let mut geometry = geometry.unwrap();
let (_, size_hints) =
self.conn.get_icccm_window_size_hints(
@@ -3501,7 +3457,7 @@ impl<'a> Model<'a> {
self.conn.set_window_frame_extents(
window,
if let Some(client) = self.client_any(window) {
- client.frame_extents_unchecked()
+ client.frame_extents()
} else {
if self.conn.must_manage_window(window) {
FREE_EXTENTS
diff --git a/src/core/zone.rs b/src/core/zone.rs
@@ -16,6 +16,7 @@ use strum_macros::EnumIter;
use strum_macros::ToString;
use std::collections::HashMap;
+use std::ops::Add;
use std::string::ToString;
use std::sync::atomic;
use std::vec::Vec;
@@ -68,12 +69,44 @@ pub struct Border {
pub colors: ColorScheme,
}
+impl Add<Border> for Padding {
+ type Output = Self;
+
+ fn add(
+ self,
+ border: Border,
+ ) -> Self::Output {
+ Self::Output {
+ left: self.left + 1,
+ right: self.right + 1,
+ top: self.top + 1,
+ bottom: self.bottom + 1,
+ }
+ }
+}
+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct Frame {
pub extents: Extents,
pub colors: ColorScheme,
}
+impl Add<Frame> for Padding {
+ type Output = Self;
+
+ fn add(
+ self,
+ frame: Frame,
+ ) -> Self::Output {
+ Self::Output {
+ left: self.left + frame.extents.left,
+ right: self.right + frame.extents.right,
+ top: self.top + frame.extents.top,
+ bottom: self.bottom + frame.extents.bottom,
+ }
+ }
+}
+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct Decoration {
pub border: Option<Border>,
@@ -89,6 +122,25 @@ impl Default for Decoration {
}
}
+impl Add<Decoration> for Padding {
+ type Output = Self;
+
+ fn add(
+ mut self,
+ decoration: Decoration,
+ ) -> Self::Output {
+ if let Some(border) = decoration.border {
+ self = self + border;
+ }
+
+ if let Some(frame) = decoration.frame {
+ self = self + frame;
+ }
+
+ self
+ }
+}
+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum Disposition {
Unchanged,
@@ -179,6 +231,8 @@ pub enum LayoutKind {
Paper = b'/',
SStack = b'+',
Stack = b'S',
+ Horz = b'H',
+ Vert = b'V',
}
#[inline]
@@ -308,6 +362,46 @@ impl LayoutKind {
single: false,
wraps: true,
},
+ LayoutKind::Horz => LayoutConfig {
+ method: PlacementMethod::Tile,
+ decoration: Decoration {
+ frame: Some(Frame {
+ extents: Extents {
+ left: 0,
+ right: 0,
+ top: 3,
+ bottom: 0,
+ },
+ colors: Default::default(),
+ }),
+ border: None,
+ },
+ root_only: false,
+ gap: true,
+ persistent: false,
+ single: false,
+ wraps: true,
+ },
+ LayoutKind::Vert => LayoutConfig {
+ method: PlacementMethod::Tile,
+ decoration: Decoration {
+ frame: Some(Frame {
+ extents: Extents {
+ left: 0,
+ right: 0,
+ top: 3,
+ bottom: 0,
+ },
+ colors: Default::default(),
+ }),
+ border: None,
+ },
+ root_only: false,
+ gap: true,
+ persistent: false,
+ single: false,
+ wraps: true,
+ },
#[allow(unreachable_patterns)]
_ => unimplemented!(
@@ -319,20 +413,27 @@ impl LayoutKind {
fn default_data(&self) -> LayoutData {
match *self {
- // TODO
- LayoutKind::Float => LayoutData::default(),
- LayoutKind::SingleFloat => LayoutData::default(),
+ LayoutKind::Float => Default::default(),
+ LayoutKind::SingleFloat => Default::default(),
LayoutKind::Center => LayoutData {
- margin: None,
- gap_size: 0,
-
main_count: 5u32,
main_factor: 0.40f32,
+ ..Default::default()
+ },
+ LayoutKind::Monocle => Default::default(),
+ LayoutKind::Paper => Default::default(),
+ LayoutKind::SStack => LayoutData {
+ main_count: 1u32,
+ main_factor: 0.50f32,
+ ..Default::default()
},
- LayoutKind::Monocle => LayoutData::default(),
- LayoutKind::Paper => LayoutData::default(),
- LayoutKind::SStack => LayoutData::default(),
- LayoutKind::Stack => LayoutData::default(),
+ LayoutKind::Stack => LayoutData {
+ main_count: 1u32,
+ main_factor: 0.50f32,
+ ..Default::default()
+ },
+ LayoutKind::Horz => Default::default(),
+ LayoutKind::Vert => Default::default(),
#[allow(unreachable_patterns)]
_ => unimplemented!(
@@ -487,7 +588,6 @@ impl LayoutKind {
)];
}
-
let cw = (dim.w as f32
* if data.main_factor > min_w_ratio {
data.main_factor
@@ -526,12 +626,7 @@ impl LayoutKind {
(
Disposition::Changed(
- Region::new(
- x,
- pos.y,
- w as u32,
- dim.h,
- ),
+ Region::new(x, pos.y, w as u32, dim.h),
config.decoration,
),
true,
@@ -920,7 +1015,7 @@ impl ZoneManager {
let mut zone_changes: Vec<(ZoneId, ZoneChange)> = Vec::new();
- let mut placements = match &content {
+ let placements = match &content {
ZoneContent::Client(window) => {
return vec![Placement {
method,