52 Commits
1.0 ... 1.1

Author SHA1 Message Date
Dylan Araps
e0d0415d06 Fix keybinds issue. Closes #15.
This is rather verbose and I personally find it disgusting but
it's required to make key bindings behave.

A big thank you to DWM and other window managers for saving me
a crippling headache.

This increases the code an amount doesn't it?
2020-01-20 01:45:57 +02:00
Dylan Araps
ec79ff991a docs: update 2020-01-17 15:05:24 +02:00
dylan
5675787b03 Merge pull request #46 from SeungheonOh/master
Patch: init windows
2020-01-17 11:23:59 +02:00
Seungheon Oh
e3306e109b Patch: init windows 2020-01-16 15:21:11 -06:00
dylan
893b45b2de Merge pull request #43 from SeungheonOh/master
Fix: issue #42: Workspaces(Shiftmask) + Scary warnings
2020-01-15 10:01:37 +02:00
Seungheon Oh
1cce61e186 Fix: disabled 'missing-prototypes' warning 2020-01-14 15:28:19 -06:00
Seungheon Oh
66336521ed Fix: Shift mask now being recognized 2020-01-14 15:16:06 -06:00
dylan
85ee7ec48e Merge pull request #41 from SeungheonOh/master
New Patch: 2bswm style
2020-01-13 06:05:15 +00:00
Seungheon Oh
307001f472 2bswm style 2020-01-12 16:47:23 -06:00
dylan
d9b0c72fc9 Merge pull request #39 from Leon-Plickat/master
Fix #31
2019-12-25 08:53:22 +00:00
Leon Plickat
a199d34a45 Fix #31 2019-12-25 04:57:26 +01:00
dylan
13f874ead7 Merge pull request #38 from AnusReaper/fix-patches
Updated patches to conform with new changes
2019-12-18 12:05:47 +00:00
Dylan Araps
09a514cd5e sowm: Enable missing prototypes warning and define win_prev. 2019-12-18 11:41:21 +00:00
Dylan Araps
8ee3294adf Merge branch 'master' of github.com:dylanaraps/sowm 2019-12-18 11:30:21 +00:00
AnusReaper
bac7f781b6 Updated patches 2019-12-18 10:26:45 +00:00
dylan
623f4d8bc1 Merge pull request #36 from kiedtl/patch-1
add win_prev() function for focusing previous window
2019-12-16 09:49:36 +00:00
Kiëd Llaentenn
dcaf873fec add win_prev() 2019-12-15 18:53:52 -05:00
dylan
aaabcb8049 Merge pull request #34 from SeungheonOh/master
README.md: Instruction for applying multiple patches/Patch: Wheel for window resizing.
2019-12-15 09:26:46 +00:00
Seungheon Oh
3efaa6decc Patch: Bug fix 2019-12-14 23:16:33 -06:00
Seungheon Oh
1d37651391 Patch: Wheel for resizing window 2019-12-14 22:41:15 -06:00
Seungheon Oh
62959ded52 README.md: Instruction for applying multiple patches 2019-12-14 21:58:12 -06:00
dylan
5423c9172b Merge pull request #32 from SeungheonOh/master
New Patch: Rectangular style window launcher/mover + README.md
2019-12-14 09:32:37 +00:00
Seungheon Oh
8acd15de63 README.md: Installation 4th step for applying patch 2019-12-14 02:00:37 -06:00
Seungheon Oh
f7fd37e326 Patch: Rectangle style window launcher/mover 2019-12-14 01:56:48 -06:00
dylan
6d6889e3cf Merge pull request #30 from Leon-Plickat/master
Add handlebar patch
2019-11-28 02:17:01 +02:00
Leon Plickat
8ff3eee874 Style 2019-11-28 00:47:39 +01:00
Leon Plickat
0b7a277b22 Add handlebar patch 2019-11-27 13:53:12 +01:00
Dylan Araps
124ec67579 Merge branch 'master' of github.com:dylanaraps/sowm 2019-11-25 23:12:21 +00:00
Dylan Araps
93135664c2 sowm: Another possible fix for key bug 2019-11-25 23:12:05 +00:00
dylan
3e4010a0ca Merge pull request #28 from Leon-Plickat/master
Add patch which provides primitive multimonitor functionality
2019-11-25 19:01:50 +02:00
Leon Plickat
6b12178131 Double bug fix
Fixes bug where loop would continue even after window is configured.
Fixes bug where the window origins instead of window center is the
relevant coordinates for determining on which monitor a window is
displayed.
2019-11-25 17:54:27 +01:00
Leon Plickat
9a634e6134 Style 2019-11-25 17:20:49 +01:00
Dylan Araps
275488384a sowm: Run CI on pull requests 2019-11-25 14:50:51 +00:00
Dylan Araps
9a206d6c9d sowm: Test patches in CI. 2019-11-25 14:36:48 +00:00
Dylan Araps
51a96547ef sowm: Test patches in CI. 2019-11-25 14:35:50 +00:00
Dylan Araps
1fb75817aa sowm: prevent fullscreen windows from being moved or resized. 2019-11-25 14:30:34 +00:00
Dylan Araps
df34385548 sowm: revert key change 2019-11-25 14:30:00 +00:00
Leon Plickat
c6ff8d06a0 Simplify multimonitor_center_fs() 2019-11-25 13:52:55 +01:00
Leon Plickat
4dd50e6f4f Remove coords_in_box() 2019-11-25 13:47:20 +01:00
Leon Plickat
4867928d57 Monitor iterating now in its own function 2019-11-25 13:37:04 +01:00
Leon Plickat
afa8b1871f Make number_of_monitors global 2019-11-25 13:22:44 +01:00
Leon Plickat
216e462841 Simply coords_in_box() 2019-11-25 13:12:06 +01:00
Leon Plickat
425ae0f698 Style
Whitespace
2019-11-25 13:02:21 +01:00
Leon Plickat
8f1b7c28df Remove dependency on stdbool.h 2019-11-25 09:50:53 +01:00
Leon Plickat
818480983f Check center of window instead of origin.
Checking on what monitor the center of a window is, is more intuitive.
2019-11-25 04:58:46 +01:00
Leon Plickat
b7b08941d5 Add patch which provides primitive multimonitor functionality
With this patch, center and fullscreen will work as expected when using
multiple outputs.
2019-11-24 22:39:47 +01:00
Dylan Araps
d37d04ef32 Merge branch 'master' of github.com:dylanaraps/sowm 2019-11-24 14:24:28 +00:00
Dylan Araps
2292f86d7f sowm: potential fix for key bug 2019-11-24 14:24:13 +00:00
dylan
31bf57b69a Merge pull request #24 from eti0/patch-1
fix EWMH typo
2019-11-14 17:45:28 +02:00
eti
d79361b13e fix EWMH typo 2019-11-14 16:11:30 +01:00
dylan
7921a93eef Merge pull request #23 from tjtf2/master
update tj's tags patch
2019-11-09 22:51:43 +02:00
Timothy Joseph
a5853ab69a update tj's patch 2019-11-09 22:45:52 +02:00
14 changed files with 774 additions and 25 deletions

9
.github/workflows/main.yml vendored Normal file
View File

@@ -0,0 +1,9 @@
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Apply patches.
run: make test

View File

@@ -19,3 +19,6 @@ install: all
clean:
rm -f sowm *.o
test:
for patch in patches/*.patch; do patch --dry-run -p1 < "$$patch"; done

View File

@@ -1,4 +1,4 @@
# sowm
# sowm (*Simple Opinionated Window Manager*)
<a href="https://user-images.githubusercontent.com/6799467/66687576-9747c200-ec72-11e9-947d-5b96753eab03.jpg"><img src="https://user-images.githubusercontent.com/6799467/66687576-9747c200-ec72-11e9-947d-5b96753eab03.jpg" width="43%" align="right"></a>
@@ -17,7 +17,7 @@ An itsy bitsy floating window manager (*220~ sloc / 24kb compiled!*).
- All windows die on exit.
- No window borders.
- [No ICCCM](https://web.archive.org/web/20190617214524/https://raw.githubusercontent.com/kfish/xsel/1a1c5edf0dc129055f7764c666da2dd468df6016/rant.txt).
- No EMWH.
- No EWMH.
- etc etc etc
@@ -65,6 +65,8 @@ An itsy bitsy floating window manager (*220~ sloc / 24kb compiled!*).
2) Run `make` to build `sowm`.
3) Copy it to your path or run `make install`.
- `DESTDIR` and `PREFIX` are supported.
4) (Optional) Apply patch with `git apply patches/patch-name`
- In case of applying multiple patches, it has to be done **manually**.
## Thanks

View File

@@ -17,7 +17,9 @@ static struct key keys[] = {
{MOD, XK_q, win_kill, {0}},
{MOD, XK_c, win_center, {0}},
{MOD, XK_f, win_fs, {0}},
{Mod1Mask, XK_Tab, win_next, {0}},
{Mod1Mask, XK_Tab, win_next, {0}},
{Mod1Mask|ShiftMask, XK_Tab, win_prev, {0}},
{MOD, XK_d, run, {.com = menu}},
{MOD, XK_w, run, {.com = colors}},

View File

@@ -0,0 +1,96 @@
diff --git a/config.def.h b/config.def.h
index cae2009..9ad7175 100644
--- a/config.def.h
+++ b/config.def.h
@@ -26,6 +26,26 @@ static struct key keys[] = {
{MOD, XK_p, run, {.com = scrot}},
{MOD, XK_Return, run, {.com = term}},
+ {MOD, XK_h, move, {.com=(char*[]){"move", "left"}, .i=10}},
+ {MOD, XK_j, move, {.com=(char*[]){"move", "down"}, .i=10}},
+ {MOD, XK_k, move, {.com=(char*[]){"move", "up"}, .i=10}},
+ {MOD, XK_l, move, {.com=(char*[]){"move", "right"}, .i=10}},
+ {MOD|ShiftMask, XK_h, move, {.com=(char*[]){"resize", "left"}, .i=10}},
+ {MOD|ShiftMask, XK_j, move, {.com=(char*[]){"resize", "down"}, .i=10}},
+ {MOD|ShiftMask, XK_k, move, {.com=(char*[]){"resize", "up"}, .i=10}},
+ {MOD|ShiftMask, XK_l, move, {.com=(char*[]){"resize", "right"}, .i=10}},
+
+ /*
+ {MOD, XK_h, move_left, {.com = {"move"},.i=10}},
+ {MOD, XK_j, move_down, {.com = {"move"},.i=10}},
+ {MOD, XK_k, move_up, {.com = {"move"},.i=10}},
+ {MOD, XK_l, move_right, {.com = {"move"},.i=10}},
+ {MOD|ShiftMask, XK_h, resize_left, {.com = {"resize"},.i=10}},
+ {MOD|ShiftMask, XK_j, resize_down, {.com = {"resize"},.i=10}},
+ {MOD|ShiftMask, XK_k, resize_up, {.com = {"resize"},.i=10}},
+ {MOD|ShiftMask, XK_l, resize_right, {.com = {"resize"},.i=10}},
+ */
+
{0, XF86XK_AudioLowerVolume, run, {.com = voldown}},
{0, XF86XK_AudioRaiseVolume, run, {.com = volup}},
{0, XF86XK_AudioMute, run, {.com = volmute}},
diff --git a/sowm.c b/sowm.c
index 48222c6..00e2e80 100644
--- a/sowm.c
+++ b/sowm.c
@@ -7,8 +7,9 @@
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
+#include <stdio.h>
-typedef union {
+typedef struct {
const char** com;
const int i;
const Window w;
@@ -46,6 +47,9 @@ static void win_prev();
static void win_next();
static void win_to_ws(const Arg arg);
static void ws_go(const Arg arg);
+static void apply(int x, int y, int w, int h);
+static void move(const Arg arg);
+
static int xerror() { return 0;}
static client *list = {0}, *ws_list[10] = {0}, *cur;
@@ -77,6 +81,31 @@ static void (*events[LASTEvent])(XEvent *e) = {
XGetGeometry(d, W, &(Window){0}, gx, gy, gw, gh, \
&(unsigned int){0}, &(unsigned int){0})
+void apply(int x,int y,int w,int h) {
+ win_size(cur->w, &wx, &wy, &ww, &wh);
+ XMoveResizeWindow(d, cur->w,
+ wx + x,
+ wy + y,
+ ww + w,
+ wh + h);
+ win_size(cur->w, &wx, &wy, &ww, &wh);
+}
+
+void move(const Arg arg) {
+ if(arg.com[1]=="left") {
+ apply((arg.com[0]=="resize")?arg.i:-arg.i, 0, (arg.com[0]=="resize")?-arg.i:0, 0);
+ }
+ else if(arg.com[1]=="right"){
+ apply((arg.com[0]=="resize")?-arg.i:arg.i, 0, (arg.com[0]=="resize")?arg.i:0, 0);
+ }
+ else if(arg.com[1]=="up"){
+ apply(0, (arg.com[0]=="resize")?arg.i:-arg.i, 0, (arg.com[0]=="resize")?-arg.i:0);
+ }
+ else if(arg.com[1]=="down"){
+ apply(0, (arg.com[0]=="resize")?-arg.i:arg.i, 0, (arg.com[0]=="resize")?arg.i:0);
+ }
+}
+
void win_focus(client *c) {
cur = c;
XSetInputFocus(d, cur->w, RevertToParent, CurrentTime);
@@ -130,6 +159,7 @@ void button_press(XEvent *e) {
}
void button_release() {
+ win_size(cur->w, &wx, &wy, &ww, &wh);
mouse.subwindow = 0;
}

View File

@@ -36,7 +36,7 @@ Only in b/: sowm-almost-tags-0.3.diff
diff -up a/sowm.c b/sowm.c
--- a/sowm.c 2019-10-17 19:48:23.000000000 +0300
+++ b/sowm.c 2019-10-18 19:02:41.959290919 +0300
@@ -43,11 +43,14 @@ static void win_kill();
@@ -43,11 +43,14 @@ static void win_prev();
static void win_next();
static void win_to_ws(const Arg arg);
static void ws_go(const Arg arg);
@@ -44,13 +44,13 @@ diff -up a/sowm.c b/sowm.c
+static void ws_toggle_all(const Arg arg);
static int xerror() { return 0;}
static client *list = {0}, *ws_list[10] = {0};
static int ws = 1, sw, sh, wx, wy;
static client *list = {0}, *ws_list[10] = {0}, *cur;
static int ws = 1, sw, sh, wx, wy, numlock;
static unsigned int ww, wh;
+static int is_ws_enabled[10] = {0}; /* +1 the amount of ws */
static Display *d;
static Window root, cur;
static XButtonEvent mouse;
@@ -235,24 +238,68 @@ void win_next() {
}
@@ -64,11 +64,11 @@ diff -up a/sowm.c b/sowm.c
ws_save(ws);
- ws_sel(arg.i);
- if (list) for win XMapWindow(d, c->w);
- for win XMapWindow(d, c->w);
-
- ws_sel(tmp);
-
- if (list) for win XUnmapWindow(d, c->w);
- for win XUnmapWindow(d, c->w);
+ for (i = 1; i <= 9; i++) {
+ if (i != arg.i) {
+ ws_sel(i);
@@ -80,7 +80,7 @@ diff -up a/sowm.c b/sowm.c
ws_sel(arg.i);
+ if (list) for win XMapWindow(d, c->w);
if (list) win_focus(list->w);
if (list) win_focus(list); else cur = 0;
}
+void

View File

@@ -0,0 +1,134 @@
diff -up a/config.def.h b/config.def.h
--- a/config.def.h 2019-10-28 23:55:17.000000000 +0200
+++ b/config.def.h 2019-11-09 22:30:45.057057111 +0200
@@ -32,16 +32,29 @@ static struct key keys[] = {
{MOD, XK_1, ws_go, {.i = 1}},
{MOD|ShiftMask, XK_1, win_to_ws, {.i = 1}},
+ {MOD|ControlMask,XK_1,ws_toggle, {.i = 1}},
+
{MOD, XK_2, ws_go, {.i = 2}},
{MOD|ShiftMask, XK_2, win_to_ws, {.i = 2}},
+ {MOD|ControlMask,XK_2,ws_toggle, {.i = 2}},
+
{MOD, XK_3, ws_go, {.i = 3}},
{MOD|ShiftMask, XK_3, win_to_ws, {.i = 3}},
+ {MOD|ControlMask,XK_3,ws_toggle, {.i = 3}},
+
{MOD, XK_4, ws_go, {.i = 4}},
{MOD|ShiftMask, XK_4, win_to_ws, {.i = 4}},
+ {MOD|ControlMask,XK_4,ws_toggle, {.i = 4}},
+
{MOD, XK_5, ws_go, {.i = 5}},
{MOD|ShiftMask, XK_5, win_to_ws, {.i = 5}},
+ {MOD|ControlMask,XK_5,ws_toggle, {.i = 5}},
+
{MOD, XK_6, ws_go, {.i = 6}},
{MOD|ShiftMask, XK_6, win_to_ws, {.i = 6}},
+ {MOD|ControlMask,XK_6,ws_toggle, {.i = 6}},
+
+ {MOD, XK_0, ws_toggle_all, {.i = 0}},
};
#endif
Only in b/: config.h
Common subdirectories: a/patches and b/patches
Only in b/: sowm
diff -up a/sowm.c b/sowm.c
--- a/sowm.c 2019-10-28 23:55:17.000000000 +0200
+++ b/sowm.c 2019-11-09 22:34:10.660379162 +0200
@@ -45,11 +45,14 @@ static void win_kill();
static void win_next();
static void win_to_ws(const Arg arg);
static void ws_go(const Arg arg);
+static void ws_toggle(const Arg arg);
+static void ws_toggle_all(const Arg arg);
static int xerror() { return 0;}
static client *list = {0}, *ws_list[10] = {0}, *cur;
static int ws = 1, sw, sh, wx, wy, numlock;
static unsigned int ww, wh;
+static int is_ws_enabled[10] = {0}; /* +1 the amount of ws */
static Display *d;
static XButtonEvent mouse;
@@ -212,24 +215,69 @@ void win_next() {
}
void ws_go(const Arg arg) {
- int tmp = ws;
-
- if (arg.i == ws) return;
+ int i;
ws_save(ws);
- ws_sel(arg.i);
- for win XMapWindow(d, c->w);
-
- ws_sel(tmp);
-
- for win XUnmapWindow(d, c->w);
+ for (i = 1; i <= 9; i++) {
+ if (i != arg.i) {
+ ws_sel(i);
+ if (list) for win XUnmapWindow(d, c->w);
+ is_ws_enabled[i] = 0;
+ }
+ }
ws_sel(arg.i);
+ if (list) for win XMapWindow(d, c->w);
if (list) win_focus(list); else cur = 0;
}
+void
+ws_toggle(const Arg arg)
+{
+ int i, tmp = -1;
+
+ if (arg.i == ws) {
+ for (i = 1; i <= 9; i++) {
+ if (is_ws_enabled[i] && i != ws) {
+ tmp = i;
+ break;
+ }
+ }
+
+ if (tmp > 0)
+ ws_sel(tmp);
+ else
+ return;
+ }
+
+ tmp = ws;
+
+ ws_sel(arg.i);
+ if (is_ws_enabled[arg.i]) {
+ is_ws_enabled[arg.i] = 0;
+ if (list) for win XUnmapWindow(d, c->w);
+ } else {
+ is_ws_enabled[arg.i] = 1;
+ if (list) for win XMapWindow(d, c->w);
+ }
+ ws_sel(tmp);
+}
+
+void
+ws_toggle_all(const Arg arg)
+{
+ int i, tmp = ws;
+ for (i = 1; i <= 6; i++) {
+ ws_sel(i);
+ if (list) for win XMapWindow(d, c->w);
+ is_ws_enabled[i] = 1;
+ }
+ ws_sel(tmp);
+}
+
+
void configure_request(XEvent *e) {
XConfigureRequestEvent *ev = &e->xconfigurerequest;
Only in b/: sowm.o

View File

@@ -0,0 +1,184 @@
diff --git a/config.def.h b/config.def.h
index cae2009..7e422a9 100644
--- a/config.def.h
+++ b/config.def.h
@@ -3,6 +3,9 @@
#define MOD Mod4Mask
+const int handle_bar_thickness = 20;
+const char *handlebar_colour = "#ffffff";
+
const char* menu[] = {"dmenu_run", 0};
const char* term[] = {"st", 0};
const char* scrot[] = {"scr", 0};
diff --git a/sowm.c b/sowm.c
index 48222c6..551c8eb 100644
--- a/sowm.c
+++ b/sowm.c
@@ -55,6 +55,10 @@ static unsigned int ww, wh;
static Display *d;
static XButtonEvent mouse;
+static Window hb = 0;
+static XColor hbc;
+static int hba = 0;
+
static void (*events[LASTEvent])(XEvent *e) = {
[ButtonPress] = button_press,
[ButtonRelease] = button_release,
@@ -77,8 +81,37 @@ static void (*events[LASTEvent])(XEvent *e) = {
XGetGeometry(d, W, &(Window){0}, gx, gy, gw, gh, \
&(unsigned int){0}, &(unsigned int){0})
+void configure_hb_for_window(Window w) {
+ XWindowAttributes wa;
+ XGetWindowAttributes(d, w, &wa);
+ if (!hb) {
+ int s = DefaultScreen(d);
+ hb = XCreateSimpleWindow(d, RootWindow(d, s),
+ wa.x, wa.y - handle_bar_thickness,
+ wa.width + 2*wa.border_width, handle_bar_thickness,
+ 0,
+ hbc.pixel, hbc.pixel);
+ XMapWindow(d, hb);
+ XGrabButton(d, AnyButton, AnyModifier, hb, True,
+ ButtonPressMask|ButtonReleaseMask|PointerMotionMask,
+ GrabModeAsync, GrabModeAsync, 0, 0);
+ } else
+ XMoveResizeWindow(d, hb, wa.x, wa.y - handle_bar_thickness,
+ wa.width, handle_bar_thickness);
+ XRaiseWindow(d, hb);
+}
+
+void destroy_hb(void) {
+ if (!hb) return;
+ XUnmapWindow(d, hb);
+ XDestroyWindow(d, hb);
+ hb = 0;
+}
+
void win_focus(client *c) {
+ if (hba) return;
cur = c;
+ configure_hb_for_window(c->w);
XSetInputFocus(d, cur->w, RevertToParent, CurrentTime);
}
@@ -95,7 +128,22 @@ void notify_enter(XEvent *e) {
}
void notify_motion(XEvent *e) {
- if (!mouse.subwindow || cur->f) return;
+ if (e->xmotion.window == hb) {
+ while(XCheckTypedEvent(d, MotionNotify, e));
+
+ int xd = e->xbutton.x_root - mouse.x_root;
+ int yd = e->xbutton.y_root - mouse.y_root;
+
+ XMoveResizeWindow(d, cur->w,
+ wx + (mouse.button == 1 ? xd : 0),
+ wy + (mouse.button == 1 ? yd : 0),
+ ww + (mouse.button == 3 ? xd : 0),
+ wh + (mouse.button == 3 ? yd : 0));
+
+ configure_hb_for_window(cur->w);
+ }
+
+ if (!mouse.subwindow || mouse.subwindow == hb || cur->f) return;
while(XCheckTypedEvent(d, MotionNotify, e));
@@ -107,6 +155,8 @@ void notify_motion(XEvent *e) {
wy + (mouse.button == 1 ? yd : 0),
ww + (mouse.button == 3 ? xd : 0),
wh + (mouse.button == 3 ? yd : 0));
+
+ if (mouse.subwindow == cur->w) configure_hb_for_window(cur->w);
}
void key_press(XEvent *e) {
@@ -122,6 +172,14 @@ void key_press(XEvent *e) {
}
void button_press(XEvent *e) {
+ if (e->xbutton.window == hb) {
+ mouse = e->xbutton;
+ hba = 1;
+ win_size(cur->w, &wx, &wy, &ww, &wh);
+ XRaiseWindow(d, cur->w);
+ return;
+ }
+
if (!e->xbutton.subwindow) return;
win_size(e->xbutton.subwindow, &wx, &wy, &ww, &wh);
@@ -131,6 +189,7 @@ void button_press(XEvent *e) {
void button_release() {
mouse.subwindow = 0;
+ hba = 0;
}
void win_add(Window w) {
@@ -160,6 +219,8 @@ void win_del(Window w) {
for win if (c->w == w) x = c;
+ if (x == cur) destroy_hb();
+
if (!list || !x) return;
if (x->prev == x) list = 0;
if (list == x) list = x->next;
@@ -180,6 +241,8 @@ void win_center() {
win_size(cur->w, &(int){0}, &(int){0}, &ww, &wh);
XMoveWindow(d, cur->w, (sw - ww) / 2, (sh - wh) / 2);
+
+ configure_hb_for_window(cur->w);
}
void win_fs() {
@@ -188,9 +251,11 @@ void win_fs() {
if ((cur->f = cur->f ? 0 : 1)) {
win_size(cur->w, &cur->wx, &cur->wy, &cur->ww, &cur->wh);
XMoveResizeWindow(d, cur->w, 0, 0, sw, sh);
-
- } else
+ destroy_hb();
+ } else {
XMoveResizeWindow(d, cur->w, cur->wx, cur->wy, cur->ww, cur->wh);
+ configure_hb_for_window(cur->w);
+ }
}
void win_to_ws(const Arg arg) {
@@ -207,6 +272,8 @@ void win_to_ws(const Arg arg) {
XUnmapWindow(d, cur->w);
ws_save(tmp);
+ destroy_hb();
+
if (list) win_focus(list);
}
@@ -240,6 +307,8 @@ void ws_go(const Arg arg) {
ws_sel(arg.i);
+ destroy_hb();
+
if (list) win_focus(list); else cur = 0;
}
@@ -303,6 +372,10 @@ int main(void) {
ButtonPressMask|ButtonReleaseMask|PointerMotionMask,
GrabModeAsync, GrabModeAsync, 0, 0);
+ Colormap cm = DefaultColormap(d, s);
+ XParseColor(d, cm, handlebar_colour, &hbc);
+ XAllocColor(d, cm, &hbc);
+
while (1 && !XNextEvent(d, &ev))
if (events[ev.type]) events[ev.type](&ev);
}

40
patches/sowm-init.patch Normal file
View File

@@ -0,0 +1,40 @@
diff --git a/sowm.c b/sowm.c
index 6b9f794..a5bad10 100644
--- a/sowm.c
+++ b/sowm.c
@@ -28,6 +28,7 @@ typedef struct client {
Window w;
} client;
+static void init();
static void button_press(XEvent *e);
static void button_release();
static void configure_request(XEvent *e);
@@ -76,6 +77,18 @@ static void (*events[LASTEvent])(XEvent *e) = {
XGetGeometry(d, W, &(Window){0}, gx, gy, gw, gh, \
&(unsigned int){0}, &(unsigned int){0})
+void init() {
+ Window *child;
+ unsigned int nchild;
+ XQueryTree(d, RootWindow(d, DefaultScreen(d)), &(Window){0},
+ &(Window){0}, &child, &nchild);
+ for(unsigned int i = 0; i < nchild; i++) {
+ XSelectInput(d, child[i], StructureNotifyMask|EnterWindowMask);
+ XMapWindow(d, child[i]);
+ win_add(child[i]);
+ }
+}
+
void win_focus(client *c) {
cur = c;
XSetInputFocus(d, cur->w, RevertToParent, CurrentTime);
@@ -290,6 +303,8 @@ int main(void) {
XSelectInput(d, root, SubstructureRedirectMask);
XDefineCursor(d, root, XCreateFontCursor(d, 68));
+ init();
+
for (unsigned int i=0; i < sizeof(keys)/sizeof(*keys); ++i)
XGrabKey(d, XKeysymToKeycode(d, keys[i].keysym), keys[i].mod,
root, True, GrabModeAsync, GrabModeAsync);

View File

@@ -0,0 +1,88 @@
diff --git a/Makefile b/Makefile
index 8573837..72e9542 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
CFLAGS+= -std=c99 -Wall -Wextra -Wmissing-prototypes -pedantic
-LDADD+= -lX11
+LDADD+= -lX11 -lXinerama
LDFLAGS=
PREFIX?= /usr
BINDIR?= $(PREFIX)/bin
diff --git a/sowm.c b/sowm.c
index 0cc1293..6f858a9 100644
--- a/sowm.c
+++ b/sowm.c
@@ -4,6 +4,7 @@
#include <X11/XF86keysym.h>
#include <X11/keysym.h>
#include <X11/XKBlib.h>
+#include <X11/extensions/Xinerama.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
@@ -48,7 +49,7 @@ static void ws_go(const Arg arg);
static int xerror() { return 0;}
static client *list = {0}, *ws_list[10] = {0}, *cur;
-static int ws = 1, sw, sh, wx, wy, numlock;
+static int ws = 1, sw, sh, wx, wy, numlock, monitors;
static unsigned int ww, wh;
static Display *d;
@@ -108,6 +109,7 @@ void notify_motion(XEvent *e) {
wy + (mouse.button == 1 ? yd : 0),
ww + (mouse.button == 3 ? xd : 0),
wh + (mouse.button == 3 ? yd : 0));
+ win_size(cur->w, &cur->wx, &cur->wy, &cur->ww, &cur->wh);
}
void key_press(XEvent *e) {
@@ -172,12 +174,35 @@ void win_kill() {
if (cur) XKillClient(d, cur->w);
}
+int multimonitor_center_fs (int fs) {
+ if (!XineramaIsActive(d)) return 1;
+ XineramaScreenInfo *screen_info = XineramaQueryScreens(d, &monitors);
+ for (int i = 0; i < monitors; i++) {
+ if ((cur->wx >= screen_info[i].x_org && cur->wx < screen_info[i].x_org + screen_info[i].width)
+ && (cur->wy >= screen_info[i].y_org && cur->wy < screen_info[i].y_org + screen_info[i].height)) {
+ if (fs)
+ XMoveResizeWindow(d, cur->w,
+ screen_info[i].x_org, screen_info[i].y_org,
+ screen_info[i].width, screen_info[i].height);
+ else
+ XMoveWindow(d, cur->w,
+ screen_info[i].x_org + ((screen_info[i].width - ww) / 2),
+ screen_info[i].y_org + ((screen_info[i].height - wh) / 2));
+ break;
+ }
+ }
+ return 0;
+}
+
void win_center() {
if (!cur) return;
win_size(cur->w, &(int){0}, &(int){0}, &ww, &wh);
- XMoveWindow(d, cur->w, (sw - ww) / 2, (sh - wh) / 2);
+ if (multimonitor_center_fs(0))
+ XMoveWindow(d, cur->w, (sw - ww) / 2, (sh - wh) / 2);
+
+ win_size(cur->w, &cur->wx, &cur->wy, &cur->ww, &cur->wh);
}
void win_fs() {
@@ -185,8 +210,8 @@ void win_fs() {
if ((cur->f = cur->f ? 0 : 1)) {
win_size(cur->w, &cur->wx, &cur->wy, &cur->ww, &cur->wh);
- XMoveResizeWindow(d, cur->w, 0, 0, sw, sh);
-
+ if(multimonitor_center_fs(1))
+ XMoveResizeWindow(d, cur->w, 0, 0, sw, sh);
} else
XMoveResizeWindow(d, cur->w, cur->wx, cur->wy, cur->ww, cur->wh);
}

View File

@@ -0,0 +1,117 @@
diff --git a/sowm.c b/sowm.c
index bc14c4e..4ae3a8f 100644
--- a/sowm.c
+++ b/sowm.c
@@ -65,6 +65,9 @@ static void (*events[LASTEvent])(XEvent *e) = {
[MotionNotify] = notify_motion
};
+
+Window WaitingWindow;
+
#include "config.h"
#define win (client *t=0, *c=list; c && t!=list->prev; t=c, c=c->next)
@@ -75,6 +78,23 @@ static void (*events[LASTEvent])(XEvent *e) = {
XGetGeometry(d, W, &(Window){0}, gx, gy, gw, gh, \
&(unsigned int){0}, &(unsigned int){0})
+#define ABS(N) (((N)<0)?-(N):(N))
+
+void draw_outline(int x1, int y1, int x2, int y2) {
+ XClearWindow(d, RootWindow(d, DefaultScreen(d)));
+
+ GC gc = XCreateGC(d, RootWindow(d, DefaultScreen(d)), 0, NULL);
+ if(!gc)return;
+
+ XSetForeground(d, gc, WhitePixel(d, DefaultScreen(d)));
+ XDrawLine(d, RootWindow(d, DefaultScreen(d)), gc, x1, y1, x1, y2);
+ XDrawLine(d, RootWindow(d, DefaultScreen(d)), gc, x1, y1, x2, y1);
+ XDrawLine(d, RootWindow(d, DefaultScreen(d)), gc, x1, y2, x2, y2);
+ XDrawLine(d, RootWindow(d, DefaultScreen(d)), gc, x2, y1, x2, y2);
+ XFreeGC(d, gc);
+ XFlush(d);
+}
+
void win_focus(client *c) {
cur = c;
XSetInputFocus(d, cur->w, RevertToParent, CurrentTime);
@@ -93,7 +113,10 @@ void notify_enter(XEvent *e) {
}
void notify_motion(XEvent *e) {
- if (!mouse.subwindow || cur->f) return;
+ if (!mouse.subwindow || cur->f) {
+ draw_outline(mouse.x_root, mouse.y_root, e->xbutton.x_root, e->xbutton.y_root);
+ return;
+ }
while(XCheckTypedEvent(d, MotionNotify, e));
@@ -116,15 +139,43 @@ void key_press(XEvent *e) {
}
void button_press(XEvent *e) {
- if (!e->xbutton.subwindow) return;
+ mouse = e->xbutton;
+ if (!e->xbutton.subwindow) return;
win_size(e->xbutton.subwindow, &wx, &wy, &ww, &wh);
XRaiseWindow(d, e->xbutton.subwindow);
- mouse = e->xbutton;
}
-void button_release() {
- mouse.subwindow = 0;
+void button_release(XEvent *e) {
+ XClearWindow(d, RootWindow(d, DefaultScreen(d)));
+
+ if(WaitingWindow){
+ XSelectInput(d, WaitingWindow, StructureNotifyMask|EnterWindowMask);
+ win_size(WaitingWindow, &wx, &wy, &ww, &wh);
+ win_add(WaitingWindow);
+ cur = list->prev;
+
+ XMoveResizeWindow(d, cur->w,
+ e->xbutton.x_root > mouse.x_root ? mouse.x_root : e->xbutton.x_root,
+ e->xbutton.y_root > mouse.y_root ? mouse.y_root : e->xbutton.y_root,
+ ABS(mouse.x_root - e->xbutton.x_root),
+ ABS(mouse.y_root - e->xbutton.y_root));
+
+ XMapWindow(d, WaitingWindow);
+ win_focus(list->prev);
+
+ WaitingWindow = 0;
+
+ } else if(!mouse.subwindow && cur) {
+
+ XMoveResizeWindow(d, cur->w,
+ e->xbutton.x_root > mouse.x_root ? mouse.x_root : e->xbutton.x_root,
+ e->xbutton.y_root > mouse.y_root ? mouse.y_root : e->xbutton.y_root,
+ ABS(mouse.x_root - e->xbutton.x_root),
+ ABS(mouse.y_root - e->xbutton.y_root));
+
+ mouse.subwindow = 0;
+ }
}
void win_add(Window w) {
@@ -244,17 +295,7 @@ void configure_request(XEvent *e) {
}
void map_request(XEvent *e) {
- Window w = e->xmaprequest.window;
-
- XSelectInput(d, w, StructureNotifyMask|EnterWindowMask);
- win_size(w, &wx, &wy, &ww, &wh);
- win_add(w);
- cur = list->prev;
-
- if (wx + wy == 0) win_center();
-
- XMapWindow(d, w);
- win_focus(list->prev);
+ WaitingWindow = e->xmaprequest.window;
}
void run(const Arg arg) {

View File

@@ -3,7 +3,7 @@ index 8573837..738af94 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
CFLAGS+= -std=c99 -Wall -Wextra -pedantic
CFLAGS+= -std=c99 -Wall -Wextra -Wmissing-prototypes -pedantic
-LDADD+= -lX11
+LDADD+= -lX11 -lXext
LDFLAGS=
@@ -34,8 +34,8 @@ index d1b4c2a..56bf509 100644
#include <signal.h>
#include <unistd.h>
@@ -43,6 +44,7 @@ static void win_del(Window w);
static void win_fs();
static void win_kill();
static void win_prev();
static void win_next();
+static void win_round_corners(Window w, int rad);
static void win_to_ws(const Arg arg);

View File

@@ -0,0 +1,43 @@
diff --git a/config.def.h b/config.def.h
index aaaf38d..5a95d71 100644
--- a/config.def.h
+++ b/config.def.h
@@ -2,6 +2,7 @@
#define CONFIG_H
#define MOD Mod4Mask
+#define WheelResizeStep 5
const char* menu[] = {"dmenu_run", 0};
const char* term[] = {"st", 0};
diff --git a/sowm.c b/sowm.c
index bc14c4e..3b95c28 100644
--- a/sowm.c
+++ b/sowm.c
@@ -120,6 +120,17 @@ void button_press(XEvent *e) {
win_size(e->xbutton.subwindow, &wx, &wy, &ww, &wh);
XRaiseWindow(d, e->xbutton.subwindow);
+
+ int sd = 0;
+ if(e->xbutton.button == Button4) sd = WheelResizeStep;
+ else if(e->xbutton.button == Button5) sd = -WheelResizeStep;
+
+ XMoveResizeWindow(d, e->xbutton.subwindow,
+ wx - sd,
+ wy - sd,
+ ww + sd*2,
+ wh + sd*2);
+
mouse = e->xbutton;
}
@@ -285,7 +296,7 @@ int main(void) {
XGrabKey(d, XKeysymToKeycode(d, keys[i].keysym), keys[i].mod,
root, True, GrabModeAsync, GrabModeAsync);
- for (int i=1; i<4; i+=2)
+ for (int i=1; i<6; i++)
XGrabButton(d, i, MOD, root, True,
ButtonPressMask|ButtonReleaseMask|PointerMotionMask,
GrabModeAsync, GrabModeAsync, 0, 0);

57
sowm.c
View File

@@ -42,13 +42,14 @@ static void win_center();
static void win_del(Window w);
static void win_fs();
static void win_kill();
static void win_prev();
static void win_next();
static void win_to_ws(const Arg arg);
static void ws_go(const Arg arg);
static int xerror() { return 0;}
static client *list = {0}, *ws_list[10] = {0}, *cur;
static int ws = 1, sw, sh, wx, wy;
static int ws = 1, sw, sh, wx, wy, numlock = 0;
static unsigned int ww, wh;
static Display *d;
@@ -75,6 +76,10 @@ static void (*events[LASTEvent])(XEvent *e) = {
XGetGeometry(d, W, &(Window){0}, gx, gy, gw, gh, \
&(unsigned int){0}, &(unsigned int){0})
// Taken from DWM. Many thanks. https://git.suckless.org/dwm
#define mod_clean(mask) (mask & ~(numlock|LockMask) & \
(ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
void win_focus(client *c) {
cur = c;
XSetInputFocus(d, cur->w, RevertToParent, CurrentTime);
@@ -93,7 +98,7 @@ void notify_enter(XEvent *e) {
}
void notify_motion(XEvent *e) {
if (!mouse.subwindow) return;
if (!mouse.subwindow || cur->f) return;
while(XCheckTypedEvent(d, MotionNotify, e));
@@ -111,7 +116,8 @@ void key_press(XEvent *e) {
KeySym keysym = XkbKeycodeToKeysym(d, e->xkey.keycode, 0, 0);
for (unsigned int i=0; i < sizeof(keys)/sizeof(*keys); ++i)
if (keys[i].mod == e->xkey.state && keys[i].keysym == keysym)
if (keys[i].keysym == keysym &&
mod_clean(keys[i].mod) == mod_clean(e->xkey.state))
keys[i].function(keys[i].arg);
}
@@ -124,7 +130,7 @@ void button_press(XEvent *e) {
}
void button_release() {
cur->f = mouse.subwindow = 0;
mouse.subwindow = 0;
}
void win_add(Window w) {
@@ -204,6 +210,13 @@ void win_to_ws(const Arg arg) {
if (list) win_focus(list);
}
void win_prev() {
if (!cur) return;
XRaiseWindow(d, cur->prev->w);
win_focus(cur->prev);
}
void win_next() {
if (!cur) return;
@@ -265,6 +278,32 @@ void run(const Arg arg) {
execvp((char*)arg.com[0], (char**)arg.com);
}
void input_grab(Window root) {
unsigned int i, j, modifiers[] = {0, LockMask, numlock, numlock|LockMask};
XModifierKeymap *modmap = XGetModifierMapping(d);
KeyCode code;
for (i = 0; i < 8; i++)
for (j=0; j < modmap->max_keypermod; j++)
if (modmap->modifiermap[i * modmap->max_keypermod + j]
== XKeysymToKeycode(d, 0xff7f))
numlock = (1 << i);
for (i = 0; i < sizeof(keys)/sizeof(*keys); i++)
if ((code = XKeysymToKeycode(d, keys[i].keysym)))
for (j = 0; j < sizeof(modifiers)/sizeof(*modifiers); j++)
XGrabKey(d, code, keys[i].mod | modifiers[j], root,
True, GrabModeAsync, GrabModeAsync);
for (i = 1; i < 4; i += 2)
for (j = 0; j < sizeof(modifiers)/sizeof(*modifiers); j++)
XGrabButton(d, i, MOD | modifiers[j], root, True,
ButtonPressMask|ButtonReleaseMask|PointerMotionMask,
GrabModeAsync, GrabModeAsync, 0, 0);
XFreeModifiermap(modmap);
}
int main(void) {
XEvent ev;
@@ -280,15 +319,7 @@ int main(void) {
XSelectInput(d, root, SubstructureRedirectMask);
XDefineCursor(d, root, XCreateFontCursor(d, 68));
for (unsigned int i=0; i < sizeof(keys)/sizeof(*keys); ++i)
XGrabKey(d, XKeysymToKeycode(d, keys[i].keysym), keys[i].mod,
root, True, GrabModeAsync, GrabModeAsync);
for (int i=1; i<4; i+=2)
XGrabButton(d, i, MOD, root, True,
ButtonPressMask|ButtonReleaseMask|PointerMotionMask,
GrabModeAsync, GrabModeAsync, 0, 0);
input_grab(root);
while (1 && !XNextEvent(d, &ev))
if (events[ev.type]) events[ev.type](&ev);