128 Commits
Author SHA1 Message Date
Dylan Araps f4cb48d7af update 2020-10-21 15:36:42 +03:00
dylan ccb96521c1 Merge pull request #101 from venam/master
Refresh keyboard mapping uppon MappingNotify event
2020-10-02 13:35:12 +03:00
Patrick Louis 5663175d57 Refresh keyboard mapping uppon MappingNotify event
When dynamically switching between layout the keys that are grabbed need
to also be refreshed. This is a fix similar to venam/2bwm@148d832

fixes dylanaraps#100
2020-10-02 11:35:03 +03:00
dylan 95596f43aa Merge pull request #93 from Yul3n/master
Added links to the window managers in the thanks
2020-07-08 12:53:20 +03:00
yul3n e595bfb365 Added links to the window managers in the thanks 2020-07-08 10:12:36 +02:00
dylan d327a0978a Merge pull request #89 from zsugabubus/makefile
sowm: fix Makefile dependencies
2020-06-16 12:24:10 +03:00
zsugabubus 0964d47d07 sowm: fix Makefile dependencies
So the binary no longer need to be deleted for a recompilation.
2020-06-16 10:30:13 +02:00
Dylan Araps 6ca1ff91a4 docs: update 2020-05-03 22:14:12 +03:00
Dylan Araps dabe77272b sowm: revert normal kill 2020-04-25 10:47:50 +03:00
Dylan Araps ea47780ab0 sowm: Fix normal kill 2020-04-23 08:40:08 +03:00
Dylan Araps 0ed080b99c sowm: small fixes 2020-04-23 08:27:13 +03:00
dylan 7e4466e38e Merge pull request #60 from dylanaraps/kill
sowm: normal window close
2020-04-23 08:21:27 +03:00
Dylan Araps 56bdacaa84 docs: update. Closes #66 and #67 2020-03-30 08:56:41 +03:00
Dylan Araps e22087856b sowm: Compress window events after compressing all events. 2020-03-11 22:21:41 +02:00
Dylan Araps f201a467ea sowm: Fix linker errors. Closes #61 2020-02-21 18:08:47 +02:00
Dylan Araps 7821aac0d2 sowm: Fix Makefile 2020-02-20 18:41:45 +02:00
Dylan Araps a1c80d9b23 sowm: Fix Makefile 2020-02-20 18:40:29 +02:00
Dylan Araps 0df345e1da sowm: Fix compiler warning 2020-02-20 18:37:19 +02:00
Dylan Araps b5087acaac docs: update 2020-02-20 18:34:57 +02:00
Dylan Araps 3ed647f467 sowm: simpler kill 2020-02-20 18:02:11 +02:00
Dylan Araps e491a637fe sowm: Changes for easier patching 2020-02-20 16:08:47 +02:00
Dylan Araps 21a35be863 Merge branch 'master' of github.com:dylanaraps/sowm 2020-02-20 16:00:23 +02:00
Dylan Araps 5547cc3a51 sowm: Set minimum resize amount. 2020-02-20 15:59:48 +02:00
dylan 67d323458c Merge pull request #56 from noxgeek/patch-1
Add uninstall to Makefile
2020-02-16 20:02:40 +02:00
noxgeek 0004ff3e18 Add uninstall to Makefile 2020-02-16 18:39:15 +01:00
Dylan Araps 5cc5d25823 Makefile: GNUisms 2020-02-16 13:38:57 +02:00
Dylan Araps 0e8cc9fe86 sowm: Fix errors. Closes #51 2020-01-24 06:40:37 +02:00
Dylan Araps 2c3c353d74 docs: update 2020-01-23 17:03:56 +02:00
Dylan Araps 69f2c71fb7 sowm: proper prototypes 2020-01-23 17:00:26 +02:00
Dylan Araps a31091472a docs: update 2020-01-23 16:14:22 +02:00
Dylan Araps 1d249a96ef sowm: Add header file 2020-01-23 02:54:13 +02:00
Dylan Araps f558535e19 docs: update 2020-01-23 02:40:13 +02:00
Dylan Araps 243cab5deb docs: update 2020-01-23 02:39:13 +02:00
Dylan Araps 4f18161758 docs: update 2020-01-23 02:37:32 +02:00
dylan 087e276736 Merge pull request #49 from SeungheonOh/master
Patch: Wheel resize update
2020-01-22 10:57:24 +02:00
Seungheon Oh c1b252bc6d Patch: Wheel resize update 2020-01-21 15:17:58 -06:00
dylan 4aa7d1a4d6 Merge pull request #48 from SeungheonOh/master
Patch: 2bswm-style fixed
2020-01-21 02:31:16 +02:00
Seungheon Oh facbfcf061 Patch: 2bswm-style fixed 2020-01-20 13:11:42 -06:00
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
Dylan Araps e4965417f7 patches: rebase kill patch 2019-10-28 21:55:17 +00:00
Dylan Araps bc9a9b14a5 patches: rebase rounded corners 2019-10-28 21:52:28 +00:00
Dylan Araps 421f79c47b sowm: rebase rounded corners 2019-10-25 22:42:26 +03:00
Dylan Araps cb03ac9664 sowm: revert ungrab key change 2019-10-25 22:37:47 +03:00
Dylan Araps 5b012c10be sowm: attempt to fix key issue 2019-10-25 02:23:19 +03:00
Dylan Araps 35b12c7969 sowm: swap to new keycode to keysym func 2019-10-24 23:33:41 +03:00
Dylan Araps e9df9ac570 docs: update 2019-10-20 23:39:12 +03:00
Dylan Araps f14acc3b68 Merge branch 'master' of github.com:dylanaraps/sowm 2019-10-20 23:39:05 +03:00
Dylan Araps 117b04d4a6 sowm: fix workspace issue 2019-10-20 23:34:29 +03:00
dylan 0d4af0e4fa Merge pull request #14 from tjtf2/master
patches: added tj's tags patch
2019-10-20 14:09:17 +00:00
Timothy Joseph 43c7194066 patches: added tj's patch 2019-10-20 15:18:46 +03:00
Dylan Araps 144c153844 sowm: check mod first. 2019-10-19 23:29:21 +03:00
Dylan Araps 2d1e5c2654 sowm: clean up 2019-10-19 17:23:26 +03:00
Dylan Araps d70ecee07d sowm: clean up 2019-10-19 13:40:28 +03:00
Dylan Araps fa3c276ce6 sowm: remove now pointless checks 2019-10-19 13:24:17 +03:00
Dylan Araps 7316c149b8 sowm: use Window for window and not int 2019-10-19 10:55:21 +03:00
Dylan Araps 589bb768d9 sowm: fix current 2019-10-19 10:27:18 +03:00
Dylan Araps 84119dd331 sowm: simpler button release 2019-10-19 08:17:17 +03:00
Dylan Araps 5c075a359a sowm: simpler center 2019-10-19 08:14:03 +03:00
Dylan Araps b48c9b6add sowm: remove root global 2019-10-19 07:49:26 +03:00
Dylan Araps a4293a63a7 sowm: send client to focus func directly 2019-10-19 00:54:06 +03:00
Dylan Araps e60a3bcb30 docs: update 2019-10-19 00:31:21 +03:00
Dylan Araps 4ed0c0919f sowm: track current window 2019-10-19 00:30:59 +03:00
Dylan Araps d6b7a98586 docs: update 2019-10-19 00:18:27 +03:00
Dylan Araps 3f66256197 sowm: simpler alt tab 2019-10-19 00:18:03 +03:00
Dylan Araps 7fe47aefc1 sowm: swap to circular doubly linked list 2019-10-19 00:16:19 +03:00
Dylan Araps 0fa485eb7b docs: update 2019-10-18 20:12:59 +03:00
Dylan Araps d1e8ee5e67 sowm: more broken (for now) 2019-10-18 19:55:26 +03:00
Dylan Araps ef61316b5f sowm: we circular now (we also a little broken too) 2019-10-18 17:40:04 +03:00
Dylan Araps 116ebcfc74 docs: update 2019-10-18 13:55:50 +03:00
Dylan Araps 493302d38b sowm: simpler window add 2019-10-18 13:45:02 +03:00
Dylan Araps f10cec8509 sowm: formatting 2019-10-18 13:05:25 +03:00
Dylan Araps 02b10e8585 sowm: track current client to simplify linked list implementation. 2019-10-18 12:43:09 +03:00
Dylan Araps 8917b6ddb2 sowm: revert oops 2019-10-18 12:32:36 +03:00
Dylan Araps 522defba1e sowm: simpler del 2019-10-18 12:05:13 +03:00
Dylan Araps e0bd38091a sowm: fix crashes with cur 2019-10-18 11:42:57 +03:00
Dylan Araps 68257b329d sowm: track current window 2019-10-18 11:31:28 +03:00
Dylan Araps 009f1cd017 sowm: clean up 2019-10-17 21:12:41 +03:00
7 changed files with 221 additions and 327 deletions

No files matched your search

+13 -10
View File
@@ -1,21 +1,24 @@
CFLAGS+= -std=c99 -Wall -Wextra -pedantic -Wno-deprecated-declarations CFLAGS += -std=c99 -Wall -Wextra -pedantic -Wold-style-declaration
LDADD+= -lX11 CFLAGS += -Wmissing-prototypes -Wno-unused-parameter
LDFLAGS= PREFIX ?= /usr
PREFIX?= /usr BINDIR ?= $(PREFIX)/bin
BINDIR?= $(PREFIX)/bin
CC ?= gcc CC ?= gcc
all: config.h sowm all: sowm
config.h: config.h:
cp config.def.h config.h cp config.def.h config.h
sowm: sowm.o sowm: sowm.c sowm.h config.h Makefile
$(CC) $(LDFLAGS) -O3 -o $@ $+ $(LDADD) $(CC) -O3 $(CFLAGS) -o $@ $< -lX11 $(LDFLAGS)
install: all install: all
install -Dm 755 sowm $(DESTDIR)$(BINDIR)/sowm install -Dm755 sowm $(DESTDIR)$(BINDIR)/sowm
uninstall:
rm -f $(DESTDIR)$(BINDIR)/sowm
clean: clean:
rm -f sowm *.o rm -f sowm *.o
.PHONY: all install uninstall clean
+33 -17
View File
@@ -1,15 +1,16 @@
# sowm # sowm (*~~Simple~~ Shitty 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> <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>
An itsy bitsy floating window manager (*240~ sloc / 24kb compiled!*). An itsy bitsy floating window manager (*220~ sloc!*).
- Floating only. - Floating only.
- Fullscreen toggle. - Fullscreen toggle.
- Window centering. - Window centering.
- Mix of mouse and keyboard workflow. - Mix of mouse and keyboard workflow.
- Focus with cursor. - Focus with cursor.
- Rounded corners (*[through patch](https://github.com/dylanaraps/sowm/blob/master/patches/sowm-rounded-corners.patch)*) - Rounded corners (*[through patch](https://github.com/dylanaraps/sowm/pull/58)*)
- Titlebars (*[through patch](https://github.com/dylanaraps/sowm/pull/57)*)
<a href="https://user-images.githubusercontent.com/6799467/66687814-8cd9f800-ec73-11e9-97b8-6ae77876bd1b.jpg"><img src="https://user-images.githubusercontent.com/6799467/66687814-8cd9f800-ec73-11e9-97b8-6ae77876bd1b.jpg" width="43%" align="right"></a> <a href="https://user-images.githubusercontent.com/6799467/66687814-8cd9f800-ec73-11e9-97b8-6ae77876bd1b.jpg"><img src="https://user-images.githubusercontent.com/6799467/66687814-8cd9f800-ec73-11e9-97b8-6ae77876bd1b.jpg" width="43%" align="right"></a>
@@ -17,12 +18,14 @@ An itsy bitsy floating window manager (*240~ sloc / 24kb compiled!*).
- All windows die on exit. - All windows die on exit.
- No window borders. - No window borders.
- [No ICCCM](https://web.archive.org/web/20190617214524/https://raw.githubusercontent.com/kfish/xsel/1a1c5edf0dc129055f7764c666da2dd468df6016/rant.txt). - [No ICCCM](https://web.archive.org/web/20190617214524/https://raw.githubusercontent.com/kfish/xsel/1a1c5edf0dc129055f7764c666da2dd468df6016/rant.txt).
- No EMWH. - No EWMH.
- etc etc etc - etc etc etc
<br> <br>
Patches available here: https://github.com/dylanaraps/sowm/pulls
## Default Keybindings ## Default Keybindings
**Window Management** **Window Management**
@@ -35,8 +38,8 @@ An itsy bitsy floating window manager (*240~ sloc / 24kb compiled!*).
| `MOD4` + `f` | maximize toggle | | `MOD4` + `f` | maximize toggle |
| `MOD4` + `c` | center window | | `MOD4` + `c` | center window |
| `MOD4` + `q` | kill window | | `MOD4` + `q` | kill window |
| `MOD4` + `1-9` | desktop swap | | `MOD4` + `1-6` | desktop swap |
| `MOD4` + `Shift` +`1-9` | send window to desktop | | `MOD4` + `Shift` +`1-6` | send window to desktop |
| `MOD1` + `TAB` (*alt-tab*) | focus cycle | | `MOD1` + `TAB` (*alt-tab*) | focus cycle |
**Programs** **Programs**
@@ -65,18 +68,31 @@ An itsy bitsy floating window manager (*240~ sloc / 24kb compiled!*).
2) Run `make` to build `sowm`. 2) Run `make` to build `sowm`.
3) Copy it to your path or run `make install`. 3) Copy it to your path or run `make install`.
- `DESTDIR` and `PREFIX` are supported. - `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**.
If you are using GDM, save the following to `/usr/share/xsessions/sowm.desktop`. It is still recommended to start `sowm` from `.xinitrc` or through
[your own xinit implementation](https://github.com/dylanaraps/bin/blob/dfd9a9ff4555efb1cc966f8473339f37d13698ba/x).
```
[Desktop Entry]
Name=sowm
Comment=This session runs sowm as desktop manager
Exec=sowm
Type=Application
```
## Thanks ## Thanks
- 2bwm - [2bwm](https://github.com/venam/2bwm)
- SmallWM - [SmallWM](https://github.com/adamnew123456/SmallWM)
- berry - [berry](https://github.com/JLErvin/berry)
- catwm - [catwm](https://github.com/pyknite/catwm)
- dminiwm - [dminiwm](https://github.com/moetunes/dminiwm)
- dwm - [dwm](https://dwm.suckless.org)
- monsterwm - [monsterwm](https://github.com/c00kiemon5ter/monsterwm)
- openbox - [openbox](https://github.com/danakj/openbox)
- possumwm - [possum-wm](https://github.com/duckinator/possum-wm)
- swm - [swm](https://github.com/dcat/swm)
- tinywm - [tinywm](http://incise.org/tinywm.html)
+3 -1
View File
@@ -15,9 +15,11 @@ const char* colors[] = {"bud", "/home/goldie/Pictures/Wallpapers", 0};
static struct key keys[] = { static struct key keys[] = {
{MOD, XK_q, win_kill, {0}}, {MOD, XK_q, win_kill, {0}},
{MOD, XK_c, win_center, {.w = 0}}, {MOD, XK_c, win_center, {0}},
{MOD, XK_f, win_fs, {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_d, run, {.com = menu}},
{MOD, XK_w, run, {.com = colors}}, {MOD, XK_w, run, {.com = colors}},
-51
View File
@@ -1,51 +0,0 @@
diff --git a/patches/sowm-normal-kill.patch b/patches/sowm-normal-kill.patch
index 4b11cd4..e69de29 100644
--- a/patches/sowm-normal-kill.patch
+++ b/patches/sowm-normal-kill.patch
@@ -1,23 +0,0 @@
-diff --git a/sowm.c b/sowm.c
-index 0d74d4b..ff70968 100644
---- a/sowm.c
-+++ b/sowm.c
-@@ -326,7 +326,17 @@ void win_del(Window w) {
- "Shoot first and don't ask questions later?.."
- */
- void win_kill() {
-- if (win_current() != root) XKillClient(d, cur);
-+ if (win_current() == root) return;
-+
-+ XEvent ev = { .type = ClientMessage };
-+
-+ ev.xclient.window = cur;
-+ ev.xclient.format = 32;
-+ ev.xclient.message_type = XInternAtom(d, "WM_PROTOCOLS", True);
-+ ev.xclient.data.l[0] = XInternAtom(d, "WM_DELETE_WINDOW", True);
-+ ev.xclient.data.l[1] = CurrentTime;
-+
-+ XSendEvent(d, cur, False, NoEventMask, &ev);
- }
-
- /*
diff --git a/sowm.c b/sowm.c
index 126aca0..cd8af6f 100644
--- a/sowm.c
+++ b/sowm.c
@@ -180,7 +180,17 @@ void win_del(Window w) {
}
void win_kill() {
- if (win_current() ^ root) XKillClient(d, cur);
+ if (win_current() == root) return;
+
+ XEvent ev = { .type = ClientMessage };
+
+ ev.xclient.window = cur;
+ ev.xclient.format = 32;
+ ev.xclient.message_type = XInternAtom(d, "WM_PROTOCOLS", True);
+ ev.xclient.data.l[0] = XInternAtom(d, "WM_DELETE_WINDOW", True);
+ ev.xclient.data.l[1] = CurrentTime;
+
+ XSendEvent(d, cur, False, NoEventMask, &ev);
}
void win_center(const Arg arg) {
-106
View File
@@ -1,106 +0,0 @@
diff --git a/Makefile b/Makefile
index 3154a2f..243b744 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
CFLAGS+= -std=c99 -Wall -Wextra -pedantic -Wno-deprecated-declarations
-LDADD+= -lX11
+LDADD+= -lX11 -lXext
LDFLAGS=
PREFIX?= /usr
BINDIR?= $(PREFIX)/bin
diff --git a/config.def.h b/config.def.h
index 3cef34b..e7f1518 100644
--- a/config.def.h
+++ b/config.def.h
@@ -2,6 +2,7 @@
#define CONFIG_H
#define MOD Mod4Mask
+#define ROUND_CORNERS 20
const char* menu[] = {"dmenu_run", 0};
const char* term[] = {"st", 0};
diff --git a/sowm.c b/sowm.c
index 126aca0..5c99c5c 100644
--- a/sowm.c
+++ b/sowm.c
@@ -3,6 +3,7 @@
#include <X11/Xlib.h>
#include <X11/XF86keysym.h>
#include <X11/keysym.h>
+#include <X11/extensions/shape.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
@@ -41,6 +42,7 @@ static void win_del(Window w);
static void win_fs();
static void win_kill();
static void win_next();
+static void win_round_corners(Window w, int rad);
static void win_to_ws(const Arg arg);
static void ws_go(const Arg arg);
static int xerror() { return 0;}
@@ -105,6 +107,9 @@ 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.button == 3)
+ win_round_corners(mouse.subwindow, ROUND_CORNERS);
}
void key_press(XEvent *e) {
@@ -201,9 +206,44 @@ void win_fs() {
} else
XMoveResizeWindow(d, cur, c->wx, c->wy, c->ww, c->wh);
+
+ win_round_corners(cur, c->f ? 0 : ROUND_CORNERS);
}
}
+void win_round_corners(Window w, int rad) {
+ unsigned int ww, wh, dia = 2 * rad;
+
+ win_size(w, &(int){1}, &(int){1}, &ww, &wh);
+
+ if (ww < dia || wh < dia) return;
+
+ Pixmap mask = XCreatePixmap(d, w, ww, wh, 1);
+
+ if (!mask) return;
+
+ XGCValues xgcv;
+ GC shape_gc = XCreateGC(d, mask, 0, &xgcv);
+
+ if (!shape_gc) {
+ XFreePixmap(d, mask);
+ return;
+ }
+
+ XSetForeground(d, shape_gc, 0);
+ XFillRectangle(d, mask, shape_gc, 0, 0, ww, wh);
+ XSetForeground(d, shape_gc, 1);
+ XFillArc(d, mask, shape_gc, 0, 0, dia, dia, 0, 23040);
+ XFillArc(d, mask, shape_gc, ww-dia-1, 0, dia, dia, 0, 23040);
+ XFillArc(d, mask, shape_gc, 0, wh-dia-1, dia, dia, 0, 23040);
+ XFillArc(d, mask, shape_gc, ww-dia-1, wh-dia-1, dia, dia, 0, 23040);
+ XFillRectangle(d, mask, shape_gc, rad, 0, ww-dia, wh);
+ XFillRectangle(d, mask, shape_gc, 0, rad, ww, wh-dia);
+ XShapeCombineMask(d, w, ShapeBounding, 0, 0, mask, ShapeSet);
+ XFreePixmap(d, mask);
+ XFreeGC(d, shape_gc);
+}
+
void win_to_ws(const Arg arg) {
int tmp = ws;
win_current();
@@ -275,6 +315,7 @@ void map_request(XEvent *e) {
if (wx == 0 && wy == 0) win_center((Arg){.i = w});
XMapWindow(d, w);
+ win_round_corners(w, ROUND_CORNERS);
win_focus(w);
win_add(w);
}
+114 -142
View File
@@ -3,55 +3,20 @@
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/XF86keysym.h> #include <X11/XF86keysym.h>
#include <X11/keysym.h> #include <X11/keysym.h>
#include <X11/XKBlib.h>
#include <stdlib.h> #include <stdlib.h>
#include <signal.h> #include <signal.h>
#include <unistd.h> #include <unistd.h>
typedef union { #include "sowm.h"
const char** com;
const int i;
const Window w;
} Arg;
struct key { static client *list = {0}, *ws_list[10] = {0}, *cur;
unsigned int mod; static int ws = 1, sw, sh, wx, wy, numlock = 0;
KeySym keysym;
void (*function)(const Arg arg);
const Arg arg;
};
typedef struct client {
struct client *next, *prev;
int f, wx, wy;
unsigned int w, ww, wh;
} client;
static void button_press(XEvent *e);
static void button_release();
static void configure_request(XEvent *e);
static void key_press(XEvent *e);
static void map_request(XEvent *e);
static void notify_destroy(XEvent *e);
static void notify_enter(XEvent *e);
static void notify_motion(XEvent *e);
static void run(const Arg arg);
static void win_add(Window w);
static void win_center(const Arg arg);
static void win_del(Window w);
static void win_fs();
static void win_kill();
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};
static int ws = 1, sw, sh, wx, wy;
static unsigned int ww, wh; static unsigned int ww, wh;
static Display *d; static Display *d;
static Window root, cur;
static XButtonEvent mouse; static XButtonEvent mouse;
static Window root;
static void (*events[LASTEvent])(XEvent *e) = { static void (*events[LASTEvent])(XEvent *e) = {
[ButtonPress] = button_press, [ButtonPress] = button_press,
@@ -59,6 +24,7 @@ static void (*events[LASTEvent])(XEvent *e) = {
[ConfigureRequest] = configure_request, [ConfigureRequest] = configure_request,
[KeyPress] = key_press, [KeyPress] = key_press,
[MapRequest] = map_request, [MapRequest] = map_request,
[MappingNotify] = mapping_notify,
[DestroyNotify] = notify_destroy, [DestroyNotify] = notify_destroy,
[EnterNotify] = notify_enter, [EnterNotify] = notify_enter,
[MotionNotify] = notify_motion [MotionNotify] = notify_motion
@@ -66,172 +32,148 @@ static void (*events[LASTEvent])(XEvent *e) = {
#include "config.h" #include "config.h"
#define win (client *c=list;c;c=c->next) void win_focus(client *c) {
#define win_focus(W) XSetInputFocus(d, W, RevertToParent, CurrentTime) cur = c;
#define ws_save(W) ws_list[W] = list XSetInputFocus(d, cur->w, RevertToParent, CurrentTime);
#define ws_sel(W) list = ws_list[ws = W]
#define win_size(W, gx, gy, gw, gh) \
XGetGeometry(d, W, &(Window){0}, gx, gy, gw, gh, \
&(unsigned int){0}, &(unsigned int){0})
Window win_current() {
XGetInputFocus(d, &cur, (int[]){1});
return cur;
} }
void notify_destroy(XEvent *e) { void notify_destroy(XEvent *e) {
win_del(e->xdestroywindow.window); win_del(e->xdestroywindow.window);
if (list) win_focus(win_current() == root ? list->w : cur); if (list) win_focus(list->prev);
} }
void notify_enter(XEvent *e) { void notify_enter(XEvent *e) {
while(XCheckTypedEvent(d, EnterNotify, e)); while(XCheckTypedEvent(d, EnterNotify, e));
win_focus(e->xcrossing.window); for win if (c->w == e->xcrossing.window) win_focus(c);
} }
void notify_motion(XEvent *e) { void notify_motion(XEvent *e) {
if (mouse.subwindow == 0) return; if (!mouse.subwindow || cur->f) return;
while(XCheckTypedEvent(d, MotionNotify, e));
int xd = e->xbutton.x_root - mouse.x_root; int xd = e->xbutton.x_root - mouse.x_root;
int yd = e->xbutton.y_root - mouse.y_root; int yd = e->xbutton.y_root - mouse.y_root;
while(XCheckTypedEvent(d, MotionNotify, e));
XMoveResizeWindow(d, mouse.subwindow, XMoveResizeWindow(d, mouse.subwindow,
wx + (mouse.button == 1 ? xd : 0), wx + (mouse.button == 1 ? xd : 0),
wy + (mouse.button == 1 ? yd : 0), wy + (mouse.button == 1 ? yd : 0),
ww + (mouse.button == 3 ? xd : 0), MAX(1, ww + (mouse.button == 3 ? xd : 0)),
wh + (mouse.button == 3 ? yd : 0)); MAX(1, wh + (mouse.button == 3 ? yd : 0)));
} }
void key_press(XEvent *e) { void key_press(XEvent *e) {
KeySym keysym = XKeycodeToKeysym(d, e->xkey.keycode, 0); KeySym keysym = XkbKeycodeToKeysym(d, e->xkey.keycode, 0, 0);
for (unsigned int i=0; i < sizeof(keys)/sizeof(*keys); ++i) for (unsigned int i=0; i < sizeof(keys)/sizeof(*keys); ++i)
if (keys[i].keysym == keysym && keys[i].mod == e->xkey.state) if (keys[i].keysym == keysym &&
mod_clean(keys[i].mod) == mod_clean(e->xkey.state))
keys[i].function(keys[i].arg); keys[i].function(keys[i].arg);
} }
void button_press(XEvent *e) { void button_press(XEvent *e) {
if (e->xbutton.subwindow == 0) return; if (!e->xbutton.subwindow) return;
win_size(e->xbutton.subwindow, &wx, &wy, &ww, &wh); win_size(e->xbutton.subwindow, &wx, &wy, &ww, &wh);
XRaiseWindow(d, e->xbutton.subwindow); XRaiseWindow(d, e->xbutton.subwindow);
mouse = e->xbutton; mouse = e->xbutton;
} }
void button_release() { void button_release(XEvent *e) {
for win if (c->w == mouse.subwindow) c->f = 0;
mouse.subwindow = 0; mouse.subwindow = 0;
} }
void win_add(Window w) { void win_add(Window w) {
client *c, *t; client *c;
if (!(c = (client *)calloc(1, sizeof(client)))) if (!(c = (client *) calloc(1, sizeof(client))))
exit(1); exit(1);
if (!list) {
c->next = c->prev = 0;
c->w = w; c->w = w;
list = c;
if (list) {
list->prev->next = c;
c->prev = list->prev;
list->prev = c;
c->next = list;
} else { } else {
for (t=list;t->next;t=t->next); list = c;
list->prev = list->next = list;
c->next = 0;
c->prev = t;
c->w = w;
t->next = c;
} }
ws_save(ws); ws_save(ws);
} }
void win_del(Window w) { void win_del(Window w) {
for win if (c->w == w) { client *x = 0;
if (!c->prev && !c->next) {
free(list); for win if (c->w == w) x = c;
list = 0;
if (!list || !x) return;
if (x->prev == x) list = 0;
if (list == x) list = x->next;
if (x->next) x->next->prev = x->prev;
if (x->prev) x->prev->next = x->next;
free(x);
ws_save(ws); ws_save(ws);
return;
}
if (!c->prev) {
list = c->next;
c->next->prev = 0;
} else if (!c->next) {
c->prev->next = 0;
} else {
c->prev->next = c->next;
c->next->prev = c->prev;
}
free(c);
ws_save(ws);
return;
}
} }
void win_kill() { void win_kill(const Arg arg) {
if (win_current() ^ root) XKillClient(d, cur); if (cur) XKillClient(d, cur->w);
} }
void win_center(const Arg arg) { void win_center(const Arg arg) {
Window w = arg.w ? arg.w : win_current(); if (!cur) return;
win_size(w, &(int){0}, &(int){0}, &ww, &wh); win_size(cur->w, &(int){0}, &(int){0}, &ww, &wh);
XMoveWindow(d, cur->w, (sw - ww) / 2, (sh - wh) / 2);
XMoveWindow(d, w, (sw - ww) / 2, (sh - wh) / 2);
} }
void win_fs() { void win_fs(const Arg arg) {
win_current(); if (!cur) return;
for win if (c->w == cur) { if ((cur->f = cur->f ? 0 : 1)) {
if ((c->f = c->f == 0 ? 1 : 0)) { win_size(cur->w, &cur->wx, &cur->wy, &cur->ww, &cur->wh);
win_size(cur, &c->wx, &c->wy, &c->ww, &c->wh); XMoveResizeWindow(d, cur->w, 0, 0, sw, sh);
XMoveResizeWindow(d, cur, 0, 0, sw, sh);
} else } else {
XMoveResizeWindow(d, cur, c->wx, c->wy, c->ww, c->wh); XMoveResizeWindow(d, cur->w, cur->wx, cur->wy, cur->ww, cur->wh);
} }
} }
void win_to_ws(const Arg arg) { void win_to_ws(const Arg arg) {
int tmp = ws; int tmp = ws;
win_current();
if (arg.i == tmp) return; if (arg.i == tmp) return;
ws_sel(arg.i); ws_sel(arg.i);
win_add(cur); win_add(cur->w);
ws_save(arg.i); ws_save(arg.i);
ws_sel(tmp); ws_sel(tmp);
win_del(cur); win_del(cur->w);
XUnmapWindow(d, cur); XUnmapWindow(d, cur->w);
ws_save(tmp); ws_save(tmp);
if (list) win_focus(list->w); if (list) win_focus(list);
} }
void win_next() { void win_prev(const Arg arg) {
win_current(); if (!cur) return;
for win if (c->w == cur) { XRaiseWindow(d, cur->prev->w);
c = c->next ? c->next : list; win_focus(cur->prev);
}
win_focus(c->w); void win_next(const Arg arg) {
XRaiseWindow(d, c->w); if (!cur) return;
return;
} XRaiseWindow(d, cur->next->w);
win_focus(cur->next);
} }
void ws_go(const Arg arg) { void ws_go(const Arg arg) {
@@ -242,15 +184,15 @@ void ws_go(const Arg arg) {
ws_save(ws); ws_save(ws);
ws_sel(arg.i); ws_sel(arg.i);
if (list) for win XMapWindow(d, c->w); for win XMapWindow(d, c->w);
ws_sel(tmp); ws_sel(tmp);
if (list) for win XUnmapWindow(d, c->w); for win XUnmapWindow(d, c->w);
ws_sel(arg.i); ws_sel(arg.i);
if (list) win_focus(list->w); if (list) win_focus(list); else cur = 0;
} }
void configure_request(XEvent *e) { void configure_request(XEvent *e) {
@@ -271,12 +213,22 @@ void map_request(XEvent *e) {
XSelectInput(d, w, StructureNotifyMask|EnterWindowMask); XSelectInput(d, w, StructureNotifyMask|EnterWindowMask);
win_size(w, &wx, &wy, &ww, &wh); win_size(w, &wx, &wy, &ww, &wh);
win_add(w);
cur = list->prev;
if (wx == 0 && wy == 0) win_center((Arg){.i = w}); if (wx + wy == 0) win_center((Arg){0});
XMapWindow(d, w); XMapWindow(d, w);
win_focus(w); win_focus(list->prev);
win_add(w); }
void mapping_notify(XEvent *e) {
XMappingEvent *ev = &e->xmapping;
if (ev->request == MappingKeyboard || ev->request == MappingModifier) {
XRefreshKeyboardMapping(ev);
input_grab(root);
}
} }
void run(const Arg arg) { void run(const Arg arg) {
@@ -287,6 +239,34 @@ void run(const Arg arg) {
execvp((char*)arg.com[0], (char**)arg.com); 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 (int k = 0; k < modmap->max_keypermod; k++)
if (modmap->modifiermap[i * modmap->max_keypermod + k]
== XKeysymToKeycode(d, 0xff7f))
numlock = (1 << i);
XUngrabKey(d, AnyKey, AnyModifier, root);
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) { int main(void) {
XEvent ev; XEvent ev;
@@ -302,16 +282,8 @@ int main(void) {
XSelectInput(d, root, SubstructureRedirectMask); XSelectInput(d, root, SubstructureRedirectMask);
XDefineCursor(d, root, XCreateFontCursor(d, 68)); XDefineCursor(d, root, XCreateFontCursor(d, 68));
input_grab(root);
for (unsigned int i=0; i < sizeof(keys)/sizeof(*keys); ++i) while (1 && !XNextEvent(d, &ev)) // 1 && will forever be here.
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);
while (1 && !XNextEvent(d, &ev))
if (events[ev.type]) events[ev.type](&ev); if (events[ev.type]) events[ev.type](&ev);
} }
+58
View File
@@ -0,0 +1,58 @@
#include <X11/Xlib.h>
#define win (client *t=0, *c=list; c && t!=list->prev; t=c, c=c->next)
#define ws_save(W) ws_list[W] = list
#define ws_sel(W) list = ws_list[ws = W]
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define win_size(W, gx, gy, gw, gh) \
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))
typedef struct {
const char** com;
const int i;
const Window w;
} Arg;
struct key {
unsigned int mod;
KeySym keysym;
void (*function)(const Arg arg);
const Arg arg;
};
typedef struct client {
struct client *next, *prev;
int f, wx, wy;
unsigned int ww, wh;
Window w;
} client;
void button_press(XEvent *e);
void button_release(XEvent *e);
void configure_request(XEvent *e);
void input_grab(Window root);
void key_press(XEvent *e);
void map_request(XEvent *e);
void mapping_notify(XEvent *e);
void notify_destroy(XEvent *e);
void notify_enter(XEvent *e);
void notify_motion(XEvent *e);
void run(const Arg arg);
void win_add(Window w);
void win_center(const Arg arg);
void win_del(Window w);
void win_fs(const Arg arg);
void win_focus(client *c);
void win_kill(const Arg arg);
void win_prev(const Arg arg);
void win_next(const Arg arg);
void win_to_ws(const Arg arg);
void ws_go(const Arg arg);
static int xerror() { return 0; }