Skip to content

Commit

Permalink
Add scratchpad patch (#25)
Browse files Browse the repository at this point in the history
* work on scratchpad

* finish scratchpad

* fix width -> height

* try another found approach

currently it always spawns a new scratchpad instead of toggling
  • Loading branch information
ntBre committed Sep 1, 2024
1 parent 8ffa27a commit 52a3fe1
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 6 deletions.
25 changes: 21 additions & 4 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ use fig::{Fig, FigError, Value};
use key::{get_arg, FUNC_MAP};
use libc::c_char;
use x11::keysym::{
XK_Return, XK_Tab, XK_b, XK_c, XK_comma, XK_d, XK_f, XK_h, XK_i, XK_j,
XK_k, XK_l, XK_m, XK_p, XK_period, XK_q, XK_space, XK_t, XK_0, XK_1, XK_2,
XK_3, XK_4, XK_5, XK_6, XK_7, XK_8, XK_9,
XK_Return, XK_Tab, XK_b, XK_c, XK_comma, XK_d, XK_f, XK_grave, XK_h, XK_i,
XK_j, XK_k, XK_l, XK_m, XK_p, XK_period, XK_q, XK_space, XK_t, XK_0, XK_1,
XK_2, XK_3, XK_4, XK_5, XK_6, XK_7, XK_8, XK_9,
};

use x11::xlib::{Button1, Button2, Button3, ControlMask, Mod4Mask, ShiftMask};
Expand Down Expand Up @@ -474,10 +474,27 @@ static DMENUCMD: LazyLock<Vec<String>> = LazyLock::new(|| {
});
static TERMCMD: LazyLock<Vec<String>> = LazyLock::new(|| vec!["st".into()]);

fn default_keys() -> [Key; 60] {
pub const SCRATCHPADNAME: &str = "scratchpad";
pub static SCRATCHPADCMD: LazyLock<Vec<String>> = LazyLock::new(|| {
vec![
"st".into(),
"-t".into(),
SCRATCHPADNAME.into(),
"-g".into(),
"120x34".into(),
]
});

fn default_keys() -> [Key; 61] {
[
Key::new(MODKEY, XK_p, spawn, Arg::V(DMENUCMD.clone())),
Key::new(S_MOD, XK_Return, spawn, Arg::V(TERMCMD.to_vec())),
Key::new(
MODKEY,
XK_grave,
togglescratch,
Arg::V(SCRATCHPADCMD.to_vec()),
),
Key::new(MODKEY, XK_b, togglebar, Arg::I(0)),
Key::new(MODKEY, XK_j, focusstack, Arg::I(1)),
Key::new(MODKEY, XK_k, focusstack, Arg::I(-1)),
Expand Down
35 changes: 34 additions & 1 deletion src/key_handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::{
getrootptr, height, is_visible, nexttiled, pop, recttomon, resize,
resizebarwin, restack, sendevent, setfullscreen, unfocus, updatebarpos,
width, xerror, xerrordummy, BH, CURSOR, DPY, HANDLER, MONS, MOUSEMASK,
ROOT, SELMON, SYSTRAY, TAGMASK, WMATOM, XNONE,
ROOT, SCRATCHTAG, SELMON, SYSTRAY, TAGMASK, WMATOM, XNONE,
};
use rwm::{Arg, Client, Monitor};

Expand Down Expand Up @@ -634,6 +634,8 @@ pub(crate) fn spawn(arg: *const Arg) {
argv.push((*SELMON).num.to_string());
}

(*SELMON).tagset[(*SELMON).seltags as usize] &= !*SCRATCHTAG;

let mut cmd = Command::new(argv[0].clone());
let cmd = if argv.len() > 1 { cmd.args(&argv[1..]) } else { &mut cmd };

Expand Down Expand Up @@ -670,3 +672,34 @@ pub(crate) fn fullscreen(_: *const Arg) {
setfullscreen((*SELMON).sel, !(*(*SELMON).sel).isfullscreen)
}
}

pub(crate) fn togglescratch(arg: *const Arg) {
unsafe {
let mut c: *mut Client;
let mut found = false;
cfor!((
c = (*SELMON).clients;
!c.is_null();
c = (*c).next) {
found = ((*c).tags & *SCRATCHTAG) != 0;
if found {
break;
}
});
if found {
let newtagset =
(*SELMON).tagset[(*SELMON).seltags as usize] ^ *SCRATCHTAG;
if newtagset != 0 {
(*SELMON).tagset[(*SELMON).seltags as usize] = newtagset;
focus(null_mut());
arrange(SELMON);
}
if is_visible(c) {
focus(c);
restack(SELMON);
}
} else {
spawn(arg);
}
}
}
24 changes: 23 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! tiling window manager based on dwm
use std::cmp::max;
use std::ffi::{c_char, c_int, c_uint, c_ulong, CStr};
use std::ffi::{c_char, c_int, c_uint, c_ulong, CStr, CString};
use std::io::Read;
use std::mem::size_of_val;
use std::mem::{size_of, MaybeUninit};
Expand Down Expand Up @@ -2412,6 +2412,26 @@ fn manage(w: Window, wa: *mut xlib::XWindowAttributes) {
(*c).y = max((*c).y, (*(*c).mon).wy as i32);
(*c).bw = CONFIG.borderpx as i32;

// TODO pretty sure this doesn't work with pertags, which explains some
// behavior I saw before in dwm. probably need to operate on
// selmon.pertag.tags[selmon.pertag.curtag].
//
// TODO I'm also pretty sure this is _not_ the right way to be handling
// this. checking the name of the window and applying these rules seems
// like something meant to be handled by RULES
(*SELMON).tagset[(*SELMON).seltags as usize] &= !*SCRATCHTAG;
let scratchname = match CString::new(config::SCRATCHPADNAME) {
Ok(s) => s.as_ptr(),
Err(_) => null_mut(),
};
if libc::strcmp((*c).name.as_ptr(), scratchname) == 0 {
(*c).tags = *SCRATCHTAG;
(*(*c).mon).tagset[(*(*c).mon).seltags as usize] |= (*c).tags;
(*c).isfloating = true;
(*c).x = (*(*c).mon).wx + (*(*c).mon).ww / 2 - width(c) / 2;
(*c).y = (*(*c).mon).wy + (*(*c).mon).wh / 2 - height(c) / 2;
}

log::trace!("manage: XWindowChanges");
let mut wc = xlib::XWindowChanges {
x: 0,
Expand Down Expand Up @@ -2749,6 +2769,8 @@ static TAGMASK: LazyLock<u32> = LazyLock::new(|| (1 << CONFIG.tags.len()) - 1);
const BUTTONMASK: i64 = ButtonPressMask | ButtonReleaseMask;
const MOUSEMASK: i64 = BUTTONMASK | PointerMotionMask;

static SCRATCHTAG: LazyLock<u32> = LazyLock::new(|| 1 << CONFIG.tags.len());

fn updatetitle(c: *mut Client) {
log::trace!("updatetitle");
unsafe {
Expand Down

0 comments on commit 52a3fe1

Please sign in to comment.