-
Notifications
You must be signed in to change notification settings - Fork 2
/
client.c
97 lines (96 loc) · 3.15 KB
/
client.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/* jbwm - Minimalist Window Manager for X */
/* Copyright 2008-2020, Alisa Bedard <alisabedard@gmail.com> */
/* Copyright 1999-2015, Ciaran Anscomb <evilwm@6809.org.uk> */
/* See README for license and other details. */
#include "client.h"
#include <stdlib.h>
#include "ewmh.h"
#include "ewmh_state.h"
#include "atom.h"
#include "select.h"
#include "title_bar.h"
#include "util.h"
#include "vdesk.h"
#include "wm_state.h"
#include <X11/Xatom.h>
#include <X11/Xutil.h>
/* Relink c's linked list to exclude c.
* Note: As *c and *i may alias each other, use of 'restrict'
* in relink would be invalid. */
static void relink(const struct JBWMClient * c, struct JBWMClient * i,
struct JBWMClient ** head_client, struct JBWMClient ** current_client)
{
if (*(current_client) == c)
*(current_client) = NULL; // flag as invalid
if (i == c) /* c is head client. */
*(head_client) = c->next; /* removed first client. */
if (i && i->next)
relink(c, (i->next != c) ? i->next : (i->next = c->next),
head_client, current_client);
}
void jbwm_set_client_vdesk(struct JBWMClient * c, uint8_t desktop)
{
Display *d;
if(c){
d=c->screen->xlib->display;
c->vdesk=desktop;
/* Save in an atomic property, useful for restart and deskbars. */
XChangeProperty(d, c->window, jbwm_atoms[JBWM_NET_WM_DESKTOP],
XA_CARDINAL, 8, PropModeReplace, (unsigned char *)&desktop, 1);
if(c->screen->vdesk!=c->vdesk)
jbwm_hide_client(c);
}
}
/* Return the client that has specified window as either window or parent.
* This is the a frequently called function. Show restraint in adding any
* future tests. */
struct JBWMClient * jbwm_find_client(
struct JBWMClient *head, const Window w)
{
return (head && head->parent != w && head->window != w
&& head->tb.win != w) ? jbwm_find_client(head->next, w) : head;
}
void jbwm_toggle_sticky(struct JBWMClient * c,
struct JBWMClient ** current_client)
{
if(c){
c->opt.sticky ^= true; /* toggle */
jbwm_select_client(c, current_client);
jbwm_update_title_bar(c);
{
Display *d;
d=c->screen->xlib->display;
(c->opt.sticky ? jbwm_ewmh_add_state : jbwm_ewmh_remove_state)
(d, c->window,
jbwm_atoms[JBWM_NET_WM_STATE_STICKY]);
}
}
}
/* Free client and destroy its windows and properties. */
void jbwm_client_free(struct JBWMClient * c, struct JBWMClient ** head_client,
struct JBWMClient ** current_client)
{
Display *d;
const Window w = c->window, parent = c->parent;
const union JBWMRectangle * p = &c->size;
d = c->screen->xlib->display;
/* Per ICCCM + wm-spec */
XDeleteProperty(d, w, jbwm_atoms[JBWM_NET_WM_STATE]);
XDeleteProperty(d, w, jbwm_atoms[JBWM_NET_WM_DESKTOP]);
XReparentWindow(d, w, c->screen->xlib->root, p->x, p->y);
XRemoveFromSaveSet(d, w);
if(parent)
XDestroyWindow(d, parent);
relink(c, *head_client, head_client, current_client);
free(c);
}
void jbwm_hide_client(const struct JBWMClient * c)
{
XUnmapWindow(c->screen->xlib->display, c->parent);
jbwm_set_wm_state(c, IconicState);
}
void jbwm_restore_client(const struct JBWMClient * c)
{
XMapWindow(c->screen->xlib->display, c->parent);
jbwm_set_wm_state(c, NormalState);
}