Skip to content

Commit f9bf8a4

Browse files
authored
released at 0.0.3
1 parent 265a5cb commit f9bf8a4

File tree

6 files changed

+151
-59
lines changed

6 files changed

+151
-59
lines changed

CHANGELOG

+9-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010

1111
## [0.0.2] - 2020-11-07
1212
## Added
13-
- Close window command (default: Win+q)
13+
- Close window command (default: Win+q).
1414

1515
### Fixed
1616
- Resize crash in root window.
17+
18+
## [0.0.3] - 2020-11-08
19+
## Added
20+
- Examples in the config.h file.
21+
- New window height and width parameters.
22+
23+
## Removed
24+
- <string.h> library dependency.

README

+18-9
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,16 @@ patched, configured or expanded to meet the users preference.
2020
COMMANDS
2121
========
2222

23-
Implemented commands:
24-
Win+Button1+[drag] interactive window move
25-
Win+Button3+[drag] interactive window resize
26-
Win+Space run launcher menu (default: dmenu_run)
27-
Win+Enter create new terminal window (default: st)
28-
Win+q kill focused window
29-
Win+Shift+q quit window manager
23+
The following aliased commands have been implemented (although most of the
24+
default behaviors can be customized via the config.h file):
25+
26+
Win+Button1+[drag] interactive window move
27+
Win+Button3+[drag] interactive window resize
28+
Win+Space run launcher menu (default: dmenu_run)
29+
Win+Enter create new terminal window (default: st)
30+
Win+b create new browser window (default: surf)
31+
Win+q kill focused window
32+
Win+Shift+q quit window manager
3033

3134
INSTALL
3235
=======
@@ -57,8 +60,14 @@ Using xsetroot to set a solid background color:
5760
Using imagemagick and a shell script to set a wallpaper:
5861
curl -L -o bud https://bit.ly/38aAmDt
5962
chmod +x bud
60-
install bud /usr/bin/
61-
bud ~/path/to/wallpaper/directory/
63+
sudo install bud /usr/bin/
64+
bud ~/wallpaper/directory/
65+
echo "bud ~/wallpaper/directory/ & exec xwm" > ~./xinitrc
66+
67+
CREDIT
68+
======
69+
70+
Special thanks to the developers of dwm, sowm, lainwm, bluem and tinywm.
6271

6372
CONTACT
6473
=======

TODO

+2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1+
* Add borders to indicate window focus
2+
* Add workspaces
13
* Add minimum window size
24
* Use library call instead of execvp()

config.h

+44-12
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,50 @@
1-
/* default xwm super keys*/
2-
#define MOD1 XCB_MOD_MASK_4 /* mod key 1=Alt, 4=Start */
3-
#define MOD2 XCB_MOD_MASK_SHIFT /* shift key */
1+
/* DEFAULT KEYS
2+
* The following are the possible mask definitions. Note
3+
* that these definitions may vary between X implementations
4+
* and keyboard models.
5+
* XCB_MOD_MASK_1 -> Alt_L Alt_R Meta_L
6+
* XCB_MOD_MASK_2 -> Num_Lock
7+
* XCB_MOD_MASK_3 -> ISO_Level3_Shift
8+
* XCB_MOD_MASK_4 -> Super_L Super_R SuperL Hyper_L
9+
* XCB_MOD_MASK_5 -> ISO_Level5_Shifta
10+
* XCB_MOD_MASK_SHIFT
11+
* XCB_MOD_MASK_CONTROL
12+
* XCB_MOD_MASK_LOCK
13+
* XCB_MOD_MASK_ANY
14+
*/
15+
16+
#define MOD1 XCB_MOD_MASK_4
17+
#define MOD2 XCB_MOD_MASK_SHIFT
18+
19+
/* DEFAULT WINDOW PROPERTIES
20+
* The following parameters can be used to change window and new
21+
* window behavior
22+
*/
23+
24+
#define WINDOW_WIDTH 600
25+
#define WINDOW_HEIGHT 400
26+
27+
/* ALIASED COMMANDS
28+
* Each space delimited argument should be passed as an additional
29+
* value to the character pointer array. For example, to run
30+
* "foo -a bar", the array would be "{ "foo", "-a", "bar", NULL }".
31+
* Since execvp() is a variadic functions, each argument pointer must
32+
* be terminated by a NULL pointer.
33+
*/
434

5-
/* shortcut commands */
635
static char * termcmd[] = { "st", NULL };
736
static char * menucmd[] = { "dmenu_run", NULL };
8-
static char * browcmd[] = { "surf", NULL };
37+
static char * browcmd[] = { "surf", "http://www.google.com", NULL };
38+
39+
/* KEY ALIASES
40+
* In general, one shortcut key should exist per alias. For more key
41+
* definitions, refer to the keysymdef.h and XF86keysym.h headers.
42+
*/
943

10-
/* shortcut keys */
1144
static Key keys[] = {
12-
{ MOD1, 0x0062, spawn, browcmd },
13-
{ MOD1, 0xff0d, spawn, termcmd },
14-
{ MOD1, 0x0020, spawn, menucmd },
15-
{ MOD1, 0x0071, killclient, NULL },
16-
{ MOD1|MOD2, 0x0071, closewm, NULL }
45+
{ MOD1, 0x0062, spawn, browcmd }, /* 0x0062 = XK_b */
46+
{ MOD1, 0xff0d, spawn, termcmd }, /* 0xff0d = XK_Enter */
47+
{ MOD1, 0x0020, spawn, menucmd }, /* 0x0020 = XK_space */
48+
{ MOD1, 0x0071, killclient, NULL }, /* 0x0071 = XK_q */
49+
{ MOD1|MOD2, 0x0071, closewm, NULL } /* 0x0071 = XK_q */
1750
};
18-

xwm.c

+60-24
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
/* See LICENSE file for license details. */
22
#include <stdarg.h>
3-
#include <string.h>
43
#include <unistd.h>
54
#include <xcb/xcb.h>
65
#include <xcb/xcb_keysyms.h>
@@ -33,7 +32,7 @@ static void spawn(char **com) {
3332
}
3433
}
3534

36-
static void eventHandlerButtonPress(xcb_generic_event_t * ev) {
35+
static void handleButtonPress(xcb_generic_event_t * ev) {
3736
xcb_button_press_event_t * e = (xcb_button_press_event_t *) ev;
3837
win = e->child;
3938
values[0] = XCB_STACK_MODE_ABOVE;
@@ -53,7 +52,7 @@ static void eventHandlerButtonPress(xcb_generic_event_t * ev) {
5352
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, root, XCB_NONE, XCB_CURRENT_TIME);
5453
}
5554

56-
static void eventHandlerMotionNotify(xcb_generic_event_t * ev) {
55+
static void handleMotionNotify(xcb_generic_event_t * ev) {
5756
xcb_query_pointer_cookie_t coord = xcb_query_pointer(dpy, root);
5857
xcb_query_pointer_reply_t * poin = xcb_query_pointer_reply(dpy, coord, 0);
5958
uint32_t val[2] = {1, 3};
@@ -80,28 +79,27 @@ static void eventHandlerMotionNotify(xcb_generic_event_t * ev) {
8079
static xcb_keycode_t * xcb_get_keycodes(xcb_keysym_t keysym) {
8180
xcb_key_symbols_t * keysyms = xcb_key_symbols_alloc(dpy);
8281
xcb_keycode_t * keycode;
83-
if (!(keysyms)) {
84-
keycode = NULL;
85-
} else {
86-
keycode = xcb_key_symbols_get_keycode(keysyms, keysym);
87-
}
82+
keycode = (!(keysyms) ? NULL : xcb_key_symbols_get_keycode(keysyms, keysym));
8883
xcb_key_symbols_free(keysyms);
8984
return keycode;
9085
}
9186

9287
static xcb_keysym_t xcb_get_keysym(xcb_keycode_t keycode) {
9388
xcb_key_symbols_t * keysyms = xcb_key_symbols_alloc(dpy);
9489
xcb_keysym_t keysym;
95-
if (!(keysyms)) {
96-
keysym = 0;
97-
} else {
98-
keysym = xcb_key_symbols_get_keysym(keysyms, keycode, 0);
99-
}
90+
keysym = (!(keysyms) ? 0 : xcb_key_symbols_get_keysym(keysyms, keycode, 0));
10091
xcb_key_symbols_free(keysyms);
10192
return keysym;
10293
}
10394

104-
static void eventHandlerKeyPress(xcb_generic_event_t * ev) {
95+
static void setFocus(xcb_drawable_t window) {
96+
if ((window != 0) && (window != root)) {
97+
xcb_set_input_focus(dpy, XCB_INPUT_FOCUS_POINTER_ROOT, window,
98+
XCB_CURRENT_TIME);
99+
}
100+
}
101+
102+
static void handleKeyPress(xcb_generic_event_t * ev) {
105103
xcb_key_press_event_t * e = ( xcb_key_press_event_t *) ev;
106104
xcb_keysym_t keysym = xcb_get_keysym(e->detail);
107105
win = e->child;
@@ -113,24 +111,41 @@ static void eventHandlerKeyPress(xcb_generic_event_t * ev) {
113111
}
114112
}
115113

116-
static void eventHandlerEnterNotify(xcb_generic_event_t * ev) {
114+
static void handleEnterNotify(xcb_generic_event_t * ev) {
117115
xcb_enter_notify_event_t * e = ( xcb_enter_notify_event_t *) ev;
118-
xcb_drawable_t win_e = e->event;
119-
if ((win_e != 0) && (win_e != root)) {
120-
xcb_set_input_focus(dpy, XCB_INPUT_FOCUS_POINTER_ROOT, win_e,
121-
XCB_CURRENT_TIME);
122-
}
116+
setFocus(e->event);
123117
}
124118

125-
static void eventHandlerButtonRelease(xcb_generic_event_t * ev) {
119+
static void handleButtonRelease(xcb_generic_event_t * ev) {
126120
xcb_ungrab_pointer(dpy, XCB_CURRENT_TIME);
127121
}
128122

129-
static void eventHandlerDestroyNotify(xcb_generic_event_t * ev) {
123+
static void handleKeyRelease(xcb_generic_event_t * ev) {
124+
/* nothing to see here, carry on */
125+
}
126+
127+
static void handleDestroyNotify(xcb_generic_event_t * ev) {
130128
xcb_destroy_notify_event_t * e = (xcb_destroy_notify_event_t *) ev;
131129
xcb_kill_client(dpy, e->window);
132130
}
133131

132+
static void handleMapRequest(xcb_generic_event_t * ev) {
133+
xcb_map_request_event_t * e = (xcb_map_request_event_t *) ev;
134+
xcb_map_window(dpy, e->window);
135+
if ((scre->root != e->window) && (0 != e->window)) {
136+
uint32_t vals[2];
137+
vals[0] = WINDOW_WIDTH;
138+
vals[1] = WINDOW_HEIGHT;
139+
xcb_configure_window(dpy, e->window, XCB_CONFIG_WINDOW_WIDTH |
140+
XCB_CONFIG_WINDOW_HEIGHT, vals);
141+
xcb_flush(dpy);
142+
}
143+
values[0] = XCB_EVENT_MASK_ENTER_WINDOW;
144+
xcb_change_window_attributes_checked(dpy, e->window,
145+
XCB_CW_EVENT_MASK, values);
146+
setFocus(e->window);
147+
}
148+
134149
static int eventHandler(void) {
135150
int ret = xcb_connection_has_error(dpy);
136151
if (ret == 0) {
@@ -145,6 +160,15 @@ static int eventHandler(void) {
145160
return ret;
146161
}
147162

163+
static void subscribeToEvents(void) {
164+
values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT
165+
| XCB_EVENT_MASK_STRUCTURE_NOTIFY
166+
| XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY
167+
| XCB_EVENT_MASK_PROPERTY_CHANGE;
168+
xcb_change_window_attributes_checked(dpy, root,
169+
XCB_CW_EVENT_MASK, values);
170+
}
171+
148172
static void grabKeys(void) {
149173
xcb_ungrab_key(dpy, XCB_GRAB_ANY, root, XCB_MOD_MASK_ANY);
150174
int key_table_size = sizeof(keys) / sizeof(*keys);
@@ -178,10 +202,21 @@ static int die(char * errstr) {
178202
return 1;
179203
}
180204

205+
static int strcmp_c(char * str1, char * str2) {
206+
char * c1 = str1;
207+
char * c2 = str2;
208+
while ((* c1) && ((* c1) == (* c2))) {
209+
++c1;
210+
++c2;
211+
}
212+
int n = (* c1) - (* c2);
213+
return n;
214+
}
215+
181216
int main(int argc, char * argv[]) {
182217
int ret = 0;
183-
if ((argc == 2) && (strcmp("-v", argv[1]) == 0)) {
184-
ret = die("xwm-0.0.2, © 2020 Michael Czigler, see LICENSE for details\n");
218+
if ((argc == 2) && (strcmp_c("-v", argv[1]) == 0)) {
219+
ret = die("xwm-0.0.3, © 2020 Michael Czigler, see LICENSE for details\n");
185220
}
186221
if ((ret == 0) && (argc != 1)) {
187222
ret = die("usage: xwm [-v]\n");
@@ -196,6 +231,7 @@ int main(int argc, char * argv[]) {
196231
if (ret == 0) {
197232
scre = xcb_setup_roots_iterator(xcb_get_setup(dpy)).data;
198233
root = scre->root;
234+
subscribeToEvents();
199235
grabKeys();
200236
grabButtons();
201237
}

xwm.h

+18-13
Original file line numberDiff line numberDiff line change
@@ -24,26 +24,31 @@ static void closewm(char ** com);
2424

2525
/* event hander actions */
2626
static int eventHandler(void);
27-
static void eventHandlerMotionNotify(xcb_generic_event_t * ev);
28-
static void eventHandlerEnterNotify(xcb_generic_event_t * ev);
29-
static void eventHandlerButtonPress(xcb_generic_event_t * ev);
30-
static void eventHandlerButtonRelease(xcb_generic_event_t * ev);
31-
static void eventHandlerKeyPress(xcb_generic_event_t * ev);
32-
static void eventHandlerDestroyNotify(xcb_generic_event_t * ev);
27+
static void handleMotionNotify(xcb_generic_event_t * ev);
28+
static void handleEnterNotify(xcb_generic_event_t * ev);
29+
static void handleDestroyNotify(xcb_generic_event_t * ev);
30+
static void handleButtonPress(xcb_generic_event_t * ev);
31+
static void handleButtonRelease(xcb_generic_event_t * ev);
32+
static void handleKeyPress(xcb_generic_event_t * ev);
33+
static void handleKeyRelease(xcb_generic_event_t * ev);
34+
static void handleMapRequest(xcb_generic_event_t * ev);
3335
static handler_func_t handler_funs[] = {
34-
{ XCB_MOTION_NOTIFY, eventHandlerMotionNotify },
35-
{ XCB_ENTER_NOTIFY, eventHandlerEnterNotify },
36-
{ XCB_BUTTON_PRESS, eventHandlerButtonPress },
37-
{ XCB_BUTTON_RELEASE, eventHandlerButtonRelease },
38-
{ XCB_KEY_PRESS, eventHandlerKeyPress },
39-
{ XCB_DESTROY_NOTIFY, eventHandlerDestroyNotify },
36+
{ XCB_MOTION_NOTIFY, handleMotionNotify },
37+
{ XCB_ENTER_NOTIFY, handleEnterNotify },
38+
{ XCB_DESTROY_NOTIFY, handleDestroyNotify },
39+
{ XCB_BUTTON_PRESS, handleButtonPress },
40+
{ XCB_BUTTON_RELEASE, handleButtonRelease },
41+
{ XCB_KEY_PRESS, handleKeyPress },
42+
{ XCB_KEY_RELEASE, handleKeyRelease },
43+
{ XCB_MAP_REQUEST, handleMapRequest },
4044
{ XCB_NONE, NULL }
4145
};
4246

4347
/* intialize */
4448
static void grabKeys(void);
4549
static void grabButtons(void);
4650

47-
/* error handling */
51+
/* error handling & misc. */
4852
static int die(char * errstr);
53+
static int strcmp_c(char * str1, char * str2);
4954

0 commit comments

Comments
 (0)