Skip to content

Commit 4b69602

Browse files
committed
own systray
1 parent 6f56804 commit 4b69602

File tree

4 files changed

+47
-43
lines changed

4 files changed

+47
-43
lines changed

src/handlers.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ pub(crate) fn clientmessage(state: &mut State, e: *mut XEvent) {
121121
let mut c = wintoclient(state, cme.window);
122122

123123
if CONFIG.showsystray
124-
&& cme.window == (*state.systray).win
124+
&& cme.window == state.systray().win
125125
&& cme.message_type == state.netatom[Net::SystemTrayOP as usize]
126126
{
127127
// add systray icons
@@ -134,8 +134,9 @@ pub(crate) fn clientmessage(state: &mut State, e: *mut XEvent) {
134134
return;
135135
}
136136
(*c).mon = state.selmon;
137-
(*c).next = (*state.systray).icons;
138-
(*state.systray).icons = c;
137+
(*c).next = state.systray().icons;
138+
let place = &mut state.systray_mut().icons;
139+
*place = c;
139140
let mut wa = MaybeUninit::uninit();
140141
if XGetWindowAttributes(state.dpy, (*c).win, wa.as_mut_ptr()) == 0 {
141142
// use sane defaults
@@ -173,7 +174,7 @@ pub(crate) fn clientmessage(state: &mut State, e: *mut XEvent) {
173174
c.win,
174175
StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask,
175176
);
176-
XReparentWindow(state.dpy, c.win, (*state.systray).win, 0, 0);
177+
XReparentWindow(state.dpy, c.win, state.systray().win, 0, 0);
177178
// use parent's background color
178179
let mut swa = XSetWindowAttributes {
179180
background_pixmap: 0,
@@ -206,7 +207,7 @@ pub(crate) fn clientmessage(state: &mut State, e: *mut XEvent) {
206207
CurrentTime as i64,
207208
XEMBED_EMBEDDED_NOTIFY as i64,
208209
0,
209-
(*state.systray).win as i64,
210+
state.systray().win as i64,
210211
XEMBED_EMBEDDED_VERSION as i64,
211212
);
212213

@@ -220,7 +221,7 @@ pub(crate) fn clientmessage(state: &mut State, e: *mut XEvent) {
220221
CurrentTime as i64,
221222
XEMBED_FOCUS_IN as i64,
222223
0,
223-
(*state.systray).win as i64,
224+
state.systray().win as i64,
224225
XEMBED_EMBEDDED_VERSION as i64,
225226
);
226227
sendevent(
@@ -231,7 +232,7 @@ pub(crate) fn clientmessage(state: &mut State, e: *mut XEvent) {
231232
CurrentTime as i64,
232233
XEMBED_WINDOW_ACTIVATE as i64,
233234
0,
234-
(*state.systray).win as i64,
235+
state.systray().win as i64,
235236
XEMBED_EMBEDDED_VERSION as i64,
236237
);
237238
sendevent(
@@ -242,7 +243,7 @@ pub(crate) fn clientmessage(state: &mut State, e: *mut XEvent) {
242243
CurrentTime as i64,
243244
XEMBED_MODALITY_ON as i64,
244245
0,
245-
(*state.systray).win as i64,
246+
state.systray().win as i64,
246247
XEMBED_EMBEDDED_VERSION as i64,
247248
);
248249
XSync(state.dpy, False);
@@ -540,7 +541,7 @@ pub(crate) fn maprequest(state: &mut State, e: *mut XEvent) {
540541
CurrentTime as i64,
541542
XEMBED_WINDOW_ACTIVATE as i64,
542543
0,
543-
(*state.systray).win as i64,
544+
state.systray().win as i64,
544545
XEMBED_EMBEDDED_VERSION as i64,
545546
);
546547
resizebarwin(state, state.selmon);

src/key_handlers.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub(crate) fn togglebar(state: &mut State, _arg: *const Arg) {
5252
}
5353
XConfigureWindow(
5454
state.dpy,
55-
(*state.systray).win,
55+
state.systray().win,
5656
CWY as u32,
5757
&mut wc,
5858
);

src/main.rs

+25-32
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ fn setup(dpy: *mut Display) -> State {
263263
),
264264
numlockmask: 0,
265265
running: true,
266-
systray: null_mut(),
266+
systray: None,
267267
xcon: null_mut(),
268268
};
269269

@@ -1198,7 +1198,7 @@ fn updatesystrayiconstate(
11981198
CurrentTime as i64,
11991199
code as i64,
12001200
0,
1201-
(*state.systray).win as i64,
1201+
state.systray().win as i64,
12021202
XEMBED_EMBEDDED_VERSION as i64,
12031203
);
12041204
}
@@ -1241,10 +1241,9 @@ fn updatesystray(state: &mut State) {
12411241
if CONFIG.systrayonleft {
12421242
x -= sw + state.lrpad / 2;
12431243
}
1244-
if state.systray.is_null() {
1244+
if state.systray.is_none() {
12451245
// init systray
1246-
state.systray = ecalloc(1, size_of::<Systray>()).cast();
1247-
(*state.systray).win = XCreateSimpleWindow(
1246+
let win = XCreateSimpleWindow(
12481247
state.dpy,
12491248
state.root,
12501249
x,
@@ -1258,14 +1257,10 @@ fn updatesystray(state: &mut State) {
12581257
wa.event_mask = ButtonPressMask | ExposureMask;
12591258
wa.override_redirect = True;
12601259
wa.background_pixel = state.scheme[(Scheme::Norm, Col::Bg)].pixel;
1261-
XSelectInput(
1262-
state.dpy,
1263-
(*state.systray).win,
1264-
SubstructureNotifyMask,
1265-
);
1260+
XSelectInput(state.dpy, win, SubstructureNotifyMask);
12661261
XChangeProperty(
12671262
state.dpy,
1268-
(*state.systray).win,
1263+
win,
12691264
state.netatom[Net::SystemTrayOrientation as usize],
12701265
XA_CARDINAL,
12711266
32,
@@ -1276,21 +1271,21 @@ fn updatesystray(state: &mut State) {
12761271
);
12771272
XChangeWindowAttributes(
12781273
state.dpy,
1279-
(*state.systray).win,
1274+
win,
12801275
CWEventMask | CWOverrideRedirect | CWBackPixel,
12811276
&mut wa,
12821277
);
1283-
XMapRaised(state.dpy, (*state.systray).win);
1278+
XMapRaised(state.dpy, win);
12841279
XSetSelectionOwner(
12851280
state.dpy,
12861281
state.netatom[Net::SystemTray as usize],
1287-
(*state.systray).win,
1282+
win,
12881283
CurrentTime,
12891284
);
12901285
if XGetSelectionOwner(
12911286
state.dpy,
12921287
state.netatom[Net::SystemTray as usize],
1293-
) == (*state.systray).win
1288+
) == win
12941289
{
12951290
sendevent(
12961291
state,
@@ -1299,19 +1294,18 @@ fn updatesystray(state: &mut State) {
12991294
StructureNotifyMask as i32,
13001295
CurrentTime as i64,
13011296
state.netatom[Net::SystemTray as usize] as i64,
1302-
(*state.systray).win as i64,
1297+
win as i64,
13031298
0_i64,
13041299
0_i64,
13051300
);
13061301
XSync(state.dpy, False);
1302+
state.systray = Some(Systray { win, icons: null_mut() });
13071303
} else {
13081304
log::error!("unable to obtain system tray");
1309-
libc::free(state.systray.cast());
1310-
state.systray = null_mut();
13111305
return;
13121306
}
13131307
} // end if !SYSTRAY
1314-
cfor!(((w, i) = (0, (*state.systray).icons);
1308+
cfor!(((w, i) = (0, state.systray().icons);
13151309
!i.is_null();
13161310
i = (*i).next) {
13171311
// make sure the background color stays the same
@@ -1330,7 +1324,7 @@ fn updatesystray(state: &mut State) {
13301324
x -= w as i32;
13311325
XMoveResizeWindow(
13321326
state.dpy,
1333-
(*state.systray).win,
1327+
state.systray().win,
13341328
x,
13351329
(*m).by,
13361330
w,
@@ -1347,12 +1341,12 @@ fn updatesystray(state: &mut State) {
13471341
};
13481342
XConfigureWindow(
13491343
state.dpy,
1350-
(*state.systray).win,
1344+
state.systray().win,
13511345
(CWX | CWY | CWWidth | CWHeight | CWSibling | CWStackMode) as u32,
13521346
&mut wc,
13531347
);
1354-
XMapWindow(state.dpy, (*state.systray).win);
1355-
XMapSubwindows(state.dpy, (*state.systray).win);
1348+
XMapWindow(state.dpy, state.systray().win);
1349+
XMapSubwindows(state.dpy, state.systray().win);
13561350
// redraw background
13571351
XSetForeground(
13581352
state.dpy,
@@ -1361,7 +1355,7 @@ fn updatesystray(state: &mut State) {
13611355
);
13621356
XFillRectangle(
13631357
state.dpy,
1364-
(*state.systray).win,
1358+
state.systray().win,
13651359
state.drw.gc,
13661360
0,
13671361
0,
@@ -1378,7 +1372,7 @@ fn wintosystrayicon(state: &State, w: Window) -> *mut Client {
13781372
if !CONFIG.showsystray || w == 0 {
13791373
return i;
13801374
}
1381-
cfor!((i = (*state.systray).icons; !i.is_null() && (*i).win != w;
1375+
cfor!((i = state.systray().icons; !i.is_null() && (*i).win != w;
13821376
i = (*i).next) {});
13831377

13841378
i
@@ -1703,7 +1697,7 @@ fn updatebars(state: &mut State) {
17031697
state.cursors.normal.cursor,
17041698
);
17051699
if CONFIG.showsystray && m == systraytomon(state, m) {
1706-
xlib::XMapRaised(state.dpy, (*state.systray).win);
1700+
xlib::XMapRaised(state.dpy, state.systray().win);
17071701
}
17081702
xlib::XMapRaised(state.dpy, (*m).barwin);
17091703
xlib::XSetClassHint(state.dpy, (*m).barwin, &mut ch);
@@ -1919,14 +1913,14 @@ fn recttomon(
19191913
}
19201914
}
19211915

1922-
fn removesystrayicon(state: &State, i: *mut Client) {
1916+
fn removesystrayicon(state: &mut State, i: *mut Client) {
19231917
unsafe {
19241918
if !CONFIG.showsystray || i.is_null() {
19251919
return;
19261920
}
19271921
let mut ii: *mut *mut Client;
19281922
cfor!((
1929-
ii = &mut (*state.systray).icons as *mut _;
1923+
ii = &mut state.systray_mut().icons as *mut _;
19301924
!ii.is_null() && *ii != i;
19311925
ii = &mut (*(*ii)).next) {});
19321926
if !ii.is_null() {
@@ -2106,9 +2100,8 @@ fn cleanup(mut state: State) {
21062100
}
21072101

21082102
if CONFIG.showsystray {
2109-
XUnmapWindow(state.dpy, (*state.systray).win);
2110-
XDestroyWindow(state.dpy, (*state.systray).win);
2111-
libc::free(state.systray.cast());
2103+
XUnmapWindow(state.dpy, state.systray().win);
2104+
XDestroyWindow(state.dpy, state.systray().win);
21122105
}
21132106

21142107
xlib::XDestroyWindow(state.dpy, state.wmcheckwin);
@@ -2772,7 +2765,7 @@ fn getsystraywidth(state: &State) -> c_uint {
27722765
let mut i;
27732766
if CONFIG.showsystray {
27742767
cfor!((
2775-
i = (*state.systray).icons;
2768+
i = state.systray().icons;
27762769
!i.is_null();
27772770
(w, i) = (w + (*i).w + config::CONFIG.systrayspacing as i32, (*i).next))
27782771
{});

src/state.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ pub struct State {
6161
pub root: Window,
6262
/// sum of left and right padding for text
6363
pub lrpad: c_int,
64-
pub systray: *mut Systray,
64+
pub systray: Option<Systray>,
6565
/// Supporting window for NetWMCheck
6666
pub wmcheckwin: Window,
6767
pub running: bool,
@@ -71,6 +71,16 @@ pub struct State {
7171
pub xcon: *mut Connection,
7272
}
7373

74+
impl State {
75+
pub fn systray(&self) -> &Systray {
76+
self.systray.as_ref().unwrap()
77+
}
78+
79+
pub fn systray_mut(&mut self) -> &mut Systray {
80+
self.systray.as_mut().unwrap()
81+
}
82+
}
83+
7484
impl Drop for State {
7585
fn drop(&mut self) {
7686
unsafe {

0 commit comments

Comments
 (0)