Skip to content

Commit 17ed881

Browse files
authored
Start moving global state into a State struct, starting with Cursors (#39)
* move state into State struct TODO fix drop for Cur * clippy fix * fix segfault by restoring cur_free * use drw on Cur, moving back toward Drop * go back to Drop, segfault is fixed * delete CURSOR comment * handle clippy
1 parent 5ad1456 commit 17ed881

File tree

8 files changed

+170
-150
lines changed

8 files changed

+170
-150
lines changed

src/config/key.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
use std::{collections::HashMap, ffi::c_uint, sync::LazyLock};
22

33
use fig::{FigError, Value};
4-
use rwm::Arg;
4+
use rwm::{Arg, State};
55
use x11::xlib::KeySym;
66

77
#[repr(C)]
88
#[derive(Clone)]
99
pub struct Key {
1010
pub mod_: c_uint,
1111
pub keysym: KeySym,
12-
pub func: Option<fn(*const Arg)>,
12+
pub func: Option<fn(&State, *const Arg)>,
1313
pub arg: Arg,
1414
}
1515

1616
impl Key {
1717
pub const fn new(
1818
mod_: c_uint,
1919
keysym: u32,
20-
func: fn(*const Arg),
20+
func: fn(&State, *const Arg),
2121
arg: Arg,
2222
) -> Self {
2323
Self { mod_, keysym: keysym as KeySym, func: Some(func), arg }
@@ -34,10 +34,10 @@ pub(crate) fn conv<T: Clone>(opt: Option<&T>) -> Result<T, FigError> {
3434
}
3535
}
3636

37-
type FnMap = HashMap<&'static str, fn(*const Arg)>;
37+
type FnMap = HashMap<&'static str, fn(&State, *const Arg)>;
3838
pub(super) static FUNC_MAP: LazyLock<FnMap> = LazyLock::new(|| {
3939
use crate::key_handlers::*;
40-
type FN = fn(*const Arg);
40+
type FN = fn(&State, *const Arg);
4141
HashMap::from([
4242
("focusmon", focusmon as FN),
4343
("focusstack", focusstack as FN),

src/drw.rs

+33-30
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![allow(clippy::missing_safety_doc)]
2+
13
use std::ffi::{c_char, c_int, c_long, c_uchar, c_uint, CStr, CString};
24
use std::mem::MaybeUninit;
35
use std::ptr::null_mut;
@@ -13,12 +15,12 @@ use x11::xlib::{
1315
self, CapButt, Display, Drawable, False, JoinMiter, LineSolid, GC,
1416
};
1517

16-
use crate::die;
1718
use crate::enums::Col;
19+
use crate::util::die;
1820
use crate::util::{between, ecalloc};
1921
use crate::Clr;
20-
use rwm::Cursor as Cur;
21-
use rwm::Window;
22+
use crate::Cursor as Cur;
23+
use crate::Window;
2224

2325
// defined in drw.c
2426
const UTF_SIZ: usize = 4;
@@ -113,7 +115,8 @@ fn utf8decode(c: *const i8, u: *mut c_long, clen: usize) -> usize {
113115
}
114116
}
115117

116-
pub(crate) fn create(
118+
/// # Safety
119+
pub unsafe fn create(
117120
dpy: *mut Display,
118121
screen: c_int,
119122
root: Window,
@@ -147,7 +150,8 @@ pub(crate) fn create(
147150
}
148151
}
149152

150-
pub(crate) fn free(drw: *mut Drw) {
153+
/// # Safety
154+
pub unsafe fn free(drw: *mut Drw) {
151155
unsafe {
152156
xlib::XFreePixmap((*drw).dpy, (*drw).drawable);
153157
xlib::XFreeGC((*drw).dpy, (*drw).gc);
@@ -156,7 +160,8 @@ pub(crate) fn free(drw: *mut Drw) {
156160
}
157161
}
158162

159-
pub(crate) fn rect(
163+
/// # Safety
164+
pub unsafe fn rect(
160165
drw: *mut Drw,
161166
x: c_int,
162167
y: c_int,
@@ -202,40 +207,37 @@ pub(crate) fn rect(
202207
}
203208
}
204209

205-
pub(crate) fn cur_create(drw: *mut Drw, shape: c_int) -> *mut Cur {
206-
if drw.is_null() {
207-
return std::ptr::null_mut();
208-
}
210+
/// # Safety
211+
pub unsafe fn cur_create(drw: *mut Drw, shape: c_int) -> Cur {
212+
assert!(!drw.is_null());
209213
unsafe {
210-
let cur: *mut Cur = crate::util::ecalloc(1, size_of::<Cur>()).cast();
211-
if cur.is_null() {
212-
return std::ptr::null_mut();
214+
Cur {
215+
cursor: xlib::XCreateFontCursor((*drw).dpy, shape as c_uint),
216+
drw,
213217
}
214-
(*cur).cursor = xlib::XCreateFontCursor((*drw).dpy, shape as c_uint);
215-
cur
216218
}
217219
}
218220

219-
pub(crate) fn cur_free(drw: *mut Drw, cursor: *mut Cur) {
220-
if cursor.is_null() {
221-
return;
222-
}
223-
224-
unsafe {
225-
xlib::XFreeCursor((*drw).dpy, (*cursor).cursor);
226-
libc::free(cursor.cast());
221+
impl Drop for Cur {
222+
fn drop(&mut self) {
223+
unsafe {
224+
log::trace!("dropping cur: {}", self.cursor);
225+
xlib::XFreeCursor((*self.drw).dpy, self.cursor);
226+
}
227227
}
228228
}
229229

230-
pub(crate) fn setscheme(drw: *mut Drw, scm: *mut Clr) {
230+
/// # Safety
231+
pub unsafe fn setscheme(drw: *mut Drw, scm: *mut Clr) {
231232
if !drw.is_null() {
232233
unsafe {
233234
(*drw).scheme = scm;
234235
}
235236
}
236237
}
237238

238-
pub(crate) fn fontset_create(drw: *mut Drw, fonts: &[CString]) -> *mut Fnt {
239+
/// # Safety
240+
pub unsafe fn fontset_create(drw: *mut Drw, fonts: &[CString]) -> *mut Fnt {
239241
log::trace!("fontset_create");
240242
unsafe {
241243
let mut ret: *mut Fnt = null_mut();
@@ -365,7 +367,7 @@ fn clr_create(drw: *mut Drw, dest: *mut Clr, clrname: *const c_char) {
365367
}
366368
}
367369

368-
pub(crate) fn scm_create(
370+
pub fn scm_create(
369371
drw: *mut Drw,
370372
clrnames: &[CString],
371373
clrcount: usize,
@@ -385,7 +387,8 @@ pub(crate) fn scm_create(
385387
ret
386388
}
387389

388-
pub(crate) fn fontset_getwidth(drw: *mut Drw, text: *const c_char) -> c_uint {
390+
/// # Safety
391+
pub unsafe fn fontset_getwidth(drw: *mut Drw, text: *const c_char) -> c_uint {
389392
unsafe {
390393
if drw.is_null() || (*drw).fonts.is_null() || text.is_null() {
391394
return 0;
@@ -395,7 +398,7 @@ pub(crate) fn fontset_getwidth(drw: *mut Drw, text: *const c_char) -> c_uint {
395398
}
396399

397400
#[allow(clippy::too_many_arguments)]
398-
pub(crate) fn text(
401+
pub unsafe fn text(
399402
drw: *mut Drw,
400403
mut x: c_int,
401404
y: c_int,
@@ -733,7 +736,7 @@ fn font_getexts(
733736
}
734737
}
735738

736-
pub(crate) fn map(
739+
pub unsafe fn map(
737740
drw: *mut Drw,
738741
win: Window,
739742
x: c_int,
@@ -761,7 +764,7 @@ pub(crate) fn map(
761764
}
762765
}
763766

764-
pub(crate) fn resize(drw: *mut Drw, w: c_uint, h: c_uint) {
767+
pub unsafe fn resize(drw: *mut Drw, w: c_uint, h: c_uint) {
765768
unsafe {
766769
if drw.is_null() {
767770
return;

src/handlers.rs

+22-21
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,23 @@ use x11::xlib::{
1515
};
1616

1717
use rwm::{
18+
drw,
1819
enums::{Col, Scheme, XEmbed},
19-
Arg, Client, Monitor, Window,
20+
util::ecalloc,
21+
Arg, Client, Monitor, State, Window,
2022
};
2123

2224
use crate::{
2325
arrange, cleanmask,
2426
config::CONFIG,
25-
configure, drawbar, drawbars, drw,
27+
configure, drawbar, drawbars,
2628
enums::{Clk, Net},
2729
focus, get_scheme_color, getsystraywidth, grabkeys, height, is_visible,
2830
manage, recttomon, removesystrayicon, resizebarwin, resizeclient, restack,
2931
sendevent, setclientstate, setfocus, setfullscreen, seturgent,
3032
swallowingclient, textw, unfocus, unmanage, updatebars, updategeom,
3133
updatesizehints, updatestatus, updatesystray, updatesystrayicongeom,
3234
updatesystrayiconstate, updatetitle, updatewindowtype, updatewmhints,
33-
util::ecalloc,
3435
width, wintoclient, wintomon, wintosystrayicon,
3536
xembed::{
3637
SYSTEM_TRAY_REQUEST_DOCK, XEMBED_EMBEDDED_NOTIFY,
@@ -41,7 +42,7 @@ use crate::{
4142
SW, SYSTRAY, WITHDRAWN_STATE,
4243
};
4344

44-
pub(crate) fn buttonpress(e: *mut XEvent) {
45+
pub(crate) fn buttonpress(state: &State, e: *mut XEvent) {
4546
unsafe {
4647
let mut arg = Arg::I(0);
4748
let ev = &(*e).button;
@@ -104,13 +105,13 @@ pub(crate) fn buttonpress(e: *mut XEvent) {
104105
} else {
105106
&button.arg
106107
};
107-
f(a)
108+
f(state, a)
108109
}
109110
}
110111
}
111112
}
112113

113-
pub(crate) fn clientmessage(e: *mut XEvent) {
114+
pub(crate) fn clientmessage(_state: &State, e: *mut XEvent) {
114115
unsafe {
115116
let cme = &(*e).client_message;
116117
let mut c = wintoclient(cme.window);
@@ -273,7 +274,7 @@ pub(crate) fn clientmessage(e: *mut XEvent) {
273274
}
274275
}
275276

276-
pub(crate) fn configurerequest(e: *mut XEvent) {
277+
pub(crate) fn configurerequest(_state: &State, e: *mut XEvent) {
277278
unsafe {
278279
let ev = &(*e).configure_request;
279280
let c = wintoclient(ev.window);
@@ -351,7 +352,7 @@ pub(crate) fn configurerequest(e: *mut XEvent) {
351352
}
352353
}
353354

354-
pub(crate) fn configurenotify(e: *mut XEvent) {
355+
pub(crate) fn configurenotify(state: &State, e: *mut XEvent) {
355356
unsafe {
356357
let ev = &mut (*e).configure;
357358
/* TODO: updategeom handling sucks, needs to be simplified */
@@ -361,7 +362,7 @@ pub(crate) fn configurenotify(e: *mut XEvent) {
361362
SH = ev.height;
362363
if updategeom() != 0 || dirty {
363364
drw::resize(DRW, SW as c_uint, BH as c_uint);
364-
updatebars();
365+
updatebars(state);
365366
let mut m = MONS;
366367
while !m.is_null() {
367368
let mut c = (*m).clients;
@@ -381,7 +382,7 @@ pub(crate) fn configurenotify(e: *mut XEvent) {
381382
}
382383
}
383384

384-
pub(crate) fn destroynotify(e: *mut XEvent) {
385+
pub(crate) fn destroynotify(_state: &State, e: *mut XEvent) {
385386
unsafe {
386387
let ev = &(*e).destroy_window;
387388
let mut c = wintoclient(ev.window);
@@ -403,7 +404,7 @@ pub(crate) fn destroynotify(e: *mut XEvent) {
403404
}
404405
}
405406

406-
pub(crate) fn enternotify(e: *mut XEvent) {
407+
pub(crate) fn enternotify(_state: &State, e: *mut XEvent) {
407408
log::trace!("enternotify");
408409
unsafe {
409410
let ev = &mut (*e).crossing;
@@ -424,7 +425,7 @@ pub(crate) fn enternotify(e: *mut XEvent) {
424425
}
425426
}
426427

427-
pub(crate) fn expose(e: *mut XEvent) {
428+
pub(crate) fn expose(_state: &State, e: *mut XEvent) {
428429
unsafe {
429430
let ev = &(*e).expose;
430431
if ev.count == 0 {
@@ -440,7 +441,7 @@ pub(crate) fn expose(e: *mut XEvent) {
440441
}
441442

442443
/* there are some broken focus acquiring clients needing extra handling */
443-
pub(crate) fn focusin(e: *mut XEvent) {
444+
pub(crate) fn focusin(_state: &State, e: *mut XEvent) {
444445
unsafe {
445446
let ev = &(*e).focus_change;
446447
if !(*SELMON).sel.is_null() && ev.window != (*(*SELMON).sel).win {
@@ -449,7 +450,7 @@ pub(crate) fn focusin(e: *mut XEvent) {
449450
}
450451
}
451452

452-
pub(crate) fn keypress(e: *mut XEvent) {
453+
pub(crate) fn keypress(state: &State, e: *mut XEvent) {
453454
unsafe {
454455
let ev = &mut (*e).key;
455456
let keysym = xlib::XKeycodeToKeysym(DPY, ev.keycode as KeyCode, 0);
@@ -458,13 +459,13 @@ pub(crate) fn keypress(e: *mut XEvent) {
458459
&& cleanmask(key.mod_) == cleanmask(ev.state)
459460
&& key.func.is_some()
460461
{
461-
key.func.unwrap()(&(key.arg));
462+
key.func.unwrap()(state, &(key.arg));
462463
}
463464
}
464465
}
465466
}
466467

467-
pub(crate) fn mappingnotify(e: *mut XEvent) {
468+
pub(crate) fn mappingnotify(_state: &State, e: *mut XEvent) {
468469
unsafe {
469470
let ev = &mut (*e).mapping;
470471
xlib::XRefreshKeyboardMapping(ev);
@@ -474,7 +475,7 @@ pub(crate) fn mappingnotify(e: *mut XEvent) {
474475
}
475476
}
476477

477-
pub(crate) fn maprequest(e: *mut XEvent) {
478+
pub(crate) fn maprequest(_state: &State, e: *mut XEvent) {
478479
static mut WA: XWindowAttributes = XWindowAttributes {
479480
x: 0,
480481
y: 0,
@@ -534,7 +535,7 @@ pub(crate) fn maprequest(e: *mut XEvent) {
534535
}
535536
}
536537

537-
pub(crate) fn motionnotify(e: *mut XEvent) {
538+
pub(crate) fn motionnotify(_state: &State, e: *mut XEvent) {
538539
log::trace!("motionnotify");
539540
static mut MON: *mut Monitor = null_mut();
540541
unsafe {
@@ -552,7 +553,7 @@ pub(crate) fn motionnotify(e: *mut XEvent) {
552553
}
553554
}
554555

555-
pub(crate) fn propertynotify(e: *mut XEvent) {
556+
pub(crate) fn propertynotify(_state: &State, e: *mut XEvent) {
556557
log::trace!("propertynotify");
557558
unsafe {
558559
let mut trans: Window = 0;
@@ -615,7 +616,7 @@ pub(crate) fn propertynotify(e: *mut XEvent) {
615616
}
616617
}
617618

618-
pub(crate) fn unmapnotify(e: *mut XEvent) {
619+
pub(crate) fn unmapnotify(_state: &State, e: *mut XEvent) {
619620
log::trace!("unmapnotify");
620621
unsafe {
621622
let ev = &(*e).unmap;
@@ -639,7 +640,7 @@ pub(crate) fn unmapnotify(e: *mut XEvent) {
639640
}
640641
}
641642

642-
pub(crate) fn resizerequest(e: *mut XEvent) {
643+
pub(crate) fn resizerequest(_state: &State, e: *mut XEvent) {
643644
log::trace!("resizerequest");
644645
unsafe {
645646
let ev = &(*e).resize_request;

0 commit comments

Comments
 (0)