Skip to content

Commit

Permalink
Implement window swallowing (#24)
Browse files Browse the repository at this point in the history
* update Rule struct, add st example

* update Client

* make isfloating bool

* impl swallow, add XCON

* impl unswallow

* progress on swallowing with horrifying process management

* finish swallowing?

* delete unused xcon
  • Loading branch information
ntBre authored Sep 1, 2024
1 parent 8c719b8 commit 92fdd5d
Show file tree
Hide file tree
Showing 5 changed files with 290 additions and 84 deletions.
36 changes: 33 additions & 3 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ use rwm::{Arg, Button, Key, Layout, Rule};
pub const BORDERPX: c_uint = 3;
// Snap pixel
pub const SNAP: c_uint = 32;
/// Swallow floating windows by default
pub const SWALLOWFLOATING: bool = false;

/// 0: sloppy systray follows selected monitor, >0: pin systray to monitor x
pub static SYSTRAYPINNING: c_uint = 0;
Expand Down Expand Up @@ -56,9 +58,37 @@ pub static COLORS: LazyLock<[[&CStr; 3]; 2]> = LazyLock::new(|| {
pub const TAGS: [&CStr; 9] =
[c"1", c"2", c"3", c"4", c"5", c"6", c"7", c"8", c"9"];

pub const RULES: [Rule; 2] = [
Rule::new(c"Gimp", null(), null(), 0, 1, -1),
Rule::new(c"Firefox", null(), null(), 1 << 8, 0, -1),
pub const RULES: [Rule; 3] = [
Rule {
class: c"Gimp".as_ptr(),
instance: null(),
title: null(),
tags: 0,
isfloating: true,
isterminal: false,
noswallow: false,
monitor: -1,
},
Rule {
class: c"Firefox".as_ptr(),
instance: null(),
title: null(),
tags: 1 << 8,
isfloating: false,
isterminal: false,
noswallow: true,
monitor: -1,
},
Rule {
class: c"st-256color".as_ptr(),
instance: null(),
title: null(),
tags: 0,
isfloating: false,
isterminal: true,
noswallow: false,
monitor: -1,
},
];

// layouts
Expand Down
37 changes: 21 additions & 16 deletions src/handlers.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::{
ffi::{c_int, c_long, c_uint},
ffi::{c_long, c_uint},
mem::MaybeUninit,
ptr::{addr_of, addr_of_mut, null_mut},
};
Expand All @@ -26,10 +26,10 @@ use crate::{
enums::{Clk, Net},
focus, get_scheme_color, getsystraywidth, grabkeys, height, is_visible,
manage, recttomon, removesystrayicon, resizebarwin, resizeclient, restack,
sendevent, setclientstate, setfocus, setfullscreen, seturgent, textw,
unfocus, unmanage, updatebars, updategeom, updatesizehints, updatestatus,
updatesystray, updatesystrayicongeom, updatesystrayiconstate, updatetitle,
updatewindowtype, updatewmhints,
sendevent, setclientstate, setfocus, setfullscreen, seturgent,
swallowingclient, textw, unfocus, unmanage, updatebars, updategeom,
updatesizehints, updatestatus, updatesystray, updatesystrayicongeom,
updatesystrayiconstate, updatetitle, updatewindowtype, updatewmhints,
util::ecalloc,
width, wintoclient, wintomon, wintosystrayicon,
xembed::{
Expand Down Expand Up @@ -156,7 +156,7 @@ pub(crate) fn clientmessage(e: *mut XEvent) {

c.oldbw = wa.border_width;
c.bw = 0;
c.isfloating = 1;
c.isfloating = true;

// reuse tags field as mapped status
c.tags = 1;
Expand Down Expand Up @@ -280,7 +280,7 @@ pub(crate) fn configurerequest(e: *mut XEvent) {
if !c.is_null() {
if (ev.value_mask & CWBorderWidth as u64) != 0 {
(*c).bw = ev.border_width;
} else if (*c).isfloating != 0
} else if (*c).isfloating
|| (*(*SELMON).lt[(*SELMON).sellt as usize]).arrange.is_none()
{
let m = (*c).mon;
Expand All @@ -304,10 +304,10 @@ pub(crate) fn configurerequest(e: *mut XEvent) {
assert!(!m.is_null());
let c = &mut *c;
let m = &mut *m;
if (c.x + c.w) > m.mx + m.mw && c.isfloating != 0 {
if (c.x + c.w) > m.mx + m.mw && c.isfloating {
c.x = m.mx + (m.mw / 2 - width(c) / 2); // center x
}
if (c.y + c.h) > m.my + m.mh && c.isfloating != 0 {
if (c.y + c.h) > m.my + m.mh && c.isfloating {
c.y = m.my + (m.mh / 2 - height(c) / 2); // center y
}
if (ev.value_mask & (CWX | CWY) as u64) != 0
Expand Down Expand Up @@ -388,11 +388,16 @@ pub(crate) fn destroynotify(e: *mut XEvent) {
if !c.is_null() {
unmanage(c, 1);
} else {
c = wintosystrayicon(ev.window);
c = swallowingclient(ev.window);
if !c.is_null() {
removesystrayicon(c);
resizebarwin(SELMON);
updatesystray();
unmanage((*c).swallowing, 1);
} else {
c = wintosystrayicon(ev.window);
if !c.is_null() {
removesystrayicon(c);
resizebarwin(SELMON);
updatesystray();
}
}
}
}
Expand Down Expand Up @@ -577,12 +582,12 @@ pub(crate) fn propertynotify(e: *mut XEvent) {
let c = &mut *c;
match ev.atom {
XA_WM_TRANSIENT_FOR => {
if c.isfloating == 0
if !c.isfloating
&& (xlib::XGetTransientForHint(DPY, c.win, &mut trans)
!= 0)
{
c.isfloating = !wintoclient(trans).is_null() as c_int;
if c.isfloating != 0 {
c.isfloating = !wintoclient(trans).is_null();
if c.isfloating {
arrange(c.mon);
}
}
Expand Down
17 changes: 8 additions & 9 deletions src/key_handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ pub(crate) unsafe extern "C" fn zoom(_arg: *const Arg) {
let mut c = (*SELMON).sel;
if (*(*SELMON).lt[(*SELMON).sellt as usize]).arrange.is_none()
|| c.is_null()
|| (*c).isfloating != 0
|| (*c).isfloating
{
return;
}
Expand Down Expand Up @@ -261,10 +261,9 @@ pub(crate) unsafe extern "C" fn togglefloating(_arg: *const Arg) {
// no support for fullscreen windows
return;
}
(*(*SELMON).sel).isfloating = ((*(*SELMON).sel).isfloating == 0
|| (*(*SELMON).sel).isfixed != 0)
as c_int;
if (*(*SELMON).sel).isfloating != 0 {
(*(*SELMON).sel).isfloating =
!(*(*SELMON).sel).isfloating || (*(*SELMON).sel).isfixed != 0;
if (*(*SELMON).sel).isfloating {
let sel = &mut *(*SELMON).sel;
resize(sel, sel.x, sel.y, sel.w, sel.h, 0);
}
Expand Down Expand Up @@ -474,7 +473,7 @@ pub(crate) unsafe extern "C" fn movemouse(_arg: *const Arg) {
{
ny = (*SELMON).wy + (*SELMON).wh - height(c);
}
if c.isfloating == 0
if !c.isfloating
&& (*(*SELMON).lt[(*SELMON).sellt as usize])
.arrange
.is_some()
Expand All @@ -486,7 +485,7 @@ pub(crate) unsafe extern "C" fn movemouse(_arg: *const Arg) {
if (*(*SELMON).lt[(*SELMON).sellt as usize])
.arrange
.is_none()
|| c.isfloating != 0
|| c.isfloating
{
resize(c, nx, ny, c.w, c.h, 1);
}
Expand Down Expand Up @@ -572,7 +571,7 @@ pub(crate) unsafe extern "C" fn resizemouse(_arg: *const Arg) {
&& (*c.mon).wx + nw <= (*SELMON).wx + (*SELMON).ww
&& (*c.mon).wy + nh >= (*SELMON).wy
&& (*c.mon).wy + nh <= (*SELMON).wy + (*SELMON).wh
&& c.isfloating == 0
&& !c.isfloating
&& (*(*SELMON).lt[(*SELMON).sellt as usize])
.arrange
.is_some()
Expand All @@ -584,7 +583,7 @@ pub(crate) unsafe extern "C" fn resizemouse(_arg: *const Arg) {
if (*(*SELMON).lt[(*SELMON).sellt as usize])
.arrange
.is_none()
|| c.isfloating != 0
|| c.isfloating
{
resize(c, c.x, c.y, nw, nh, 1);
}
Expand Down
34 changes: 10 additions & 24 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::ffi::{c_char, c_int, c_uint, c_void, CStr};
use std::ffi::{c_char, c_int, c_uint, c_void};

use x11::xlib::KeySym;

Expand Down Expand Up @@ -74,30 +74,12 @@ pub struct Rule {
pub instance: *const c_char,
pub title: *const c_char,
pub tags: c_uint,
pub isfloating: c_int,
pub isfloating: bool,
pub isterminal: bool,
pub noswallow: bool,
pub monitor: c_int,
}

impl Rule {
pub const fn new(
class: &'static CStr,
instance: *const i8,
title: *const i8,
tags: c_uint,
isfloating: c_int,
monitor: c_int,
) -> Self {
Self {
class: class.as_ptr(),
instance,
title,
tags,
isfloating,
monitor,
}
}
}

pub struct Systray {
pub win: Window,
pub icons: *mut Client,
Expand Down Expand Up @@ -184,13 +166,17 @@ pub struct Client {
pub oldbw: c_int,
pub tags: c_uint,
pub isfixed: c_int,
pub isfloating: c_int,
pub isfloating: bool,
pub isurgent: c_int,
pub neverfocus: c_int,
pub oldstate: c_int,
pub oldstate: bool,
pub isfullscreen: bool,
pub isterminal: bool,
pub noswallow: bool,
pub pid: libc::pid_t,
pub next: *mut Client,
pub snext: *mut Client,
pub swallowing: *mut Client,
pub mon: *mut Monitor,
pub win: Window,
}
Loading

0 comments on commit 92fdd5d

Please sign in to comment.