├── .gitattributes ├── .gitignore ├── .indent.pro ├── INSTALL ├── JBWMAtomName.h ├── JBWMClient.h ├── JBWMClientOptions.h ├── JBWMClientTitleBar.h ├── JBWMKeys.h ├── JBWMPixels.h ├── JBWMPoint.h ├── JBWMRectangle.h ├── JBWMScreen.h ├── JBWMSize.h ├── LICENSE ├── Makefile ├── Makefile.clang ├── Makefile.small ├── README.md ├── TODO ├── astylerc ├── atom.c ├── atom.h ├── button_event.c ├── button_event.h ├── client.c ├── client.h ├── command_line.c ├── command_line.h ├── config.h ├── configure ├── dbg ├── debug.mk ├── debug_clang.mk ├── debug_gcc.mk ├── depend.mk ├── display.c ├── display.h ├── drag.c ├── drag.h ├── draw.c ├── draw.h ├── events.c ├── events.h ├── ewmh.c ├── ewmh.h ├── ewmh_client.c ├── ewmh_client.h ├── ewmh_client_list.c ├── ewmh_client_list.h ├── ewmh_state.c ├── ewmh_state.h ├── ewmh_wm_state.c ├── ewmh_wm_state.h ├── exec.c ├── exec.h ├── font.c ├── font.h ├── geometry.c ├── geometry.h ├── gprof.out ├── indent.scr ├── indent.sh ├── jbwm.1 ├── jbwm.c ├── jbwm.h ├── key_combos.h ├── key_event.c ├── key_event.h ├── keys.c ├── keys.h ├── keys.txt ├── log.h ├── macros.h ├── main.c ├── max.c ├── max.h ├── mkdep.sh ├── move_resize.c ├── move_resize.h ├── mwm.c ├── mwm.h ├── mwm.mk ├── mwmproto.h ├── new.c ├── new.h ├── pixel_t.h ├── screenshot.png ├── select.c ├── select.h ├── shape.c ├── shape.h ├── snap.c ├── snap.h ├── snap_algorithm ├── sz ├── title_bar.c ├── title_bar.h ├── util.c ├── util.h ├── vdesk.c ├── vdesk.h ├── vimrc ├── wm_state.c ├── wm_state.h ├── xeph ├── xft.mk └── xosd.mk /.gitattributes: -------------------------------------------------------------------------------- 1 | *.h linguist-language=C 2 | profile linguist-language=Text 3 | 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.o 3 | tags 4 | jbwm 5 | *.dbg 6 | .*.swp 7 | *.log 8 | config.mk 9 | gmon.out 10 | jbwm.size_log 11 | keys 12 | *.bak 13 | .mdep* 14 | -------------------------------------------------------------------------------- /.indent.pro: -------------------------------------------------------------------------------- 1 | -linux 2 | -cp0 3 | -verbose 4 | 5 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | BUILDING jbwm: 2 | 3 | ./configure 4 | make 5 | make install 6 | -------------------------------------------------------------------------------- /JBWMAtomName.h: -------------------------------------------------------------------------------- 1 | #ifndef JBWM_JBWMATOMNAME_H 2 | #define JBWM_JBWMATOMNAME_H 3 | enum JBWMAtomName { 4 | JBWM_NET_SUPPORTED, 5 | JBWM_NET_CURRENT_DESKTOP, 6 | JBWM_NET_NUMBER_OF_DESKTOPS, 7 | JBWM_NET_DESKTOP_VIEWPORT, 8 | JBWM_NET_DESKTOP_GEOMETRY, 9 | JBWM_NET_SUPPORTING_WM_CHECK, 10 | JBWM_NET_ACTIVE_WINDOW, 11 | JBWM_NET_MOVERESIZE_WINDOW, 12 | JBWM_NET_CLOSE_WINDOW, 13 | JBWM_NET_CLIENT_LIST, 14 | JBWM_NET_VIRTUAL_ROOTS, 15 | JBWM_NET_CLIENT_LIST_STACKING, 16 | JBWM_NET_FRAME_EXTENTS, 17 | JBWM_NET_WM_ALLOWED_ACTIONS, 18 | JBWM_NET_WM_NAME, 19 | JBWM_NET_WM_DESKTOP, 20 | JBWM_NET_WM_MOVERESIZE, 21 | JBWM_NET_WM_PID, 22 | JBWM_NET_WM_WINDOW_TYPE, 23 | JBWM_NET_WM_STATE, 24 | JBWM_NET_WM_ACTION_MOVE, 25 | JBWM_NET_WM_ACTION_RESIZE, 26 | JBWM_NET_WM_ACTION_CLOSE, 27 | JBWM_NET_WM_ACTION_SHADE, 28 | JBWM_NET_WM_ACTION_FULLSCREEN, 29 | JBWM_NET_WM_ACTION_CHANGE_DESKTOP, 30 | JBWM_NET_WM_ACTION_ABOVE, 31 | JBWM_NET_WM_ACTION_BELOW, 32 | JBWM_NET_WM_ACTION_MAXIMIZE_HORZ, 33 | JBWM_NET_WM_ACTION_MAXIMIZE_VERT, 34 | JBWM_NET_WM_STATE_STICKY, 35 | JBWM_NET_WM_STATE_MAXIMIZED_VERT, 36 | JBWM_NET_WM_STATE_MAXIMIZED_HORZ, 37 | JBWM_NET_WM_STATE_SHADED, 38 | JBWM_NET_WM_STATE_HIDDEN, 39 | JBWM_NET_WM_STATE_FULLSCREEN, 40 | JBWM_NET_WM_STATE_ABOVE, 41 | JBWM_NET_WM_STATE_BELOW, 42 | JBWM_NET_WM_STATE_FOCUSED, 43 | JBWM_MOTIF_WM_HINTS, 44 | JBWM_ATOM_COUNT 45 | }; 46 | #endif//!JBWM_JBWMATOMNAME_H 47 | -------------------------------------------------------------------------------- /JBWMClient.h: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #ifndef JBWM_CLIENT_STRUCT_H 6 | #define JBWM_CLIENT_STRUCT_H 7 | #include 8 | #include "JBWMClientOptions.h" 9 | #include "JBWMClientTitleBar.h" 10 | #include "JBWMRectangle.h" 11 | #include "JBWMScreen.h" 12 | struct JBWMScreen; 13 | /* Sizes given for x86_64 architecture. */ 14 | struct JBWMClient { 15 | struct JBWMClientTitleBar tb; /* 40 bytes */ 16 | union JBWMRectangle size, old_size, before_fullscreen; 17 | Colormap cmap; 18 | Window window, parent; 19 | struct JBWMClient * next; 20 | struct JBWMScreen * screen; 21 | struct JBWMClientOptions opt; /* 2 bytes */ 22 | uint8_t vdesk; 23 | int8_t ignore_unmap; 24 | }; 25 | #endif /* JBWM_CLIENT_STRUCT_H */ 26 | -------------------------------------------------------------------------------- /JBWMClientOptions.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #ifndef JBWM_JBWMCLIENTOPTIONS_H 3 | #define JBWM_JBWMCLIENTOPTIONS_H 4 | #include 5 | #include 6 | struct JBWMClientOptions { 7 | uint8_t border : 2; 8 | bool fullscreen : 1; 9 | bool max_horz : 1; 10 | bool max_vert : 1; 11 | bool no_close : 1; 12 | bool no_max : 1; 13 | bool no_shade : 1; 14 | bool no_move : 1; 15 | bool no_resize : 1; 16 | bool no_title_bar : 1; 17 | bool remove : 1; 18 | bool shaded : 1; 19 | bool shaped : 1; 20 | bool sticky : 1; 21 | bool tearoff : 1; 22 | }; 23 | #endif//!JBWM_JBWMCLIENTOPTIONS_H 24 | -------------------------------------------------------------------------------- /JBWMClientTitleBar.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #ifndef JBWM_JBWMCLIENTTITLEBAR_H 3 | #define JBWM_JBWMCLIENTTITLEBAR_H 4 | #include 5 | struct JBWMClientTitleBar { 6 | Window win, close, resize, shade, stick; 7 | }; 8 | #endif//!JBWM_JBWMCLIENTTITLEBAR_H 9 | -------------------------------------------------------------------------------- /JBWMKeys.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #ifndef JBWM_JBWMKEYS_H 3 | #define JBWM_JBWMKEYS_H 4 | #include 5 | enum JBWMKeys { 6 | JBWM_KEY_0 = XK_0, 7 | JBWM_KEY_1 = XK_1, 8 | JBWM_KEY_2 = XK_2, 9 | JBWM_KEY_3 = XK_3, 10 | JBWM_KEY_4 = XK_4, 11 | JBWM_KEY_5 = XK_5, 12 | JBWM_KEY_6 = XK_6, 13 | JBWM_KEY_7 = XK_7, 14 | JBWM_KEY_8 = XK_8, 15 | JBWM_KEY_9 = XK_9, 16 | JBWM_KEY_KILL = XK_q, 17 | JBWM_KEY_ALTLOWER = XK_minus, 18 | JBWM_KEY_VDESK_NEXT_ROW = XK_Page_Up, 19 | JBWM_KEY_VDESK_PREV_ROW = XK_Page_Down, 20 | JBWM_KEY_DOWN = XK_j, 21 | JBWM_KEY_DOWN_UP = XK_J, 22 | JBWM_KEY_FS = XK_a, 23 | JBWM_KEY_INFO = XK_F5, 24 | JBWM_KEY_LEFT = XK_h, 25 | JBWM_KEY_LEFT_UP = XK_H, 26 | JBWM_KEY_LOWER = XK_Down, 27 | JBWM_KEY_MAX = XK_space, 28 | JBWM_KEY_MAX_H = XK_x, 29 | JBWM_KEY_MAX_V = XK_z, 30 | JBWM_KEY_MOVE = XK_m, 31 | JBWM_KEY_NEW = XK_Return, 32 | JBWM_KEY_NEXT = XK_Tab, 33 | JBWM_KEY_NEXTDESK = XK_Right, 34 | JBWM_KEY_PREVDESK = XK_Left, 35 | JBWM_KEY_QUIT = XK_Escape, 36 | JBWM_KEY_RAISE = XK_Up, 37 | JBWM_KEY_RIGHT = XK_l, 38 | JBWM_KEY_RIGHT_UP = XK_L, 39 | JBWM_KEY_SHADE = XK_s, 40 | JBWM_KEY_STICK = XK_period, 41 | JBWM_KEY_UP = XK_k, 42 | JBWM_KEY_UP_UP = XK_K, 43 | }; 44 | #include "key_combos.h" 45 | #endif//!JBWM_JBWMKEYS_H 46 | -------------------------------------------------------------------------------- /JBWMPixels.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #ifndef JBWM_JBWMPIXELS_H 3 | #define JBWM_JBWMPIXELS_H 4 | #include "pixel_t.h" 5 | struct JBWMPixels { 6 | jbwm_pixel_t fg, bg, fc, close, resize, shade, stick; 7 | }; 8 | #endif//!JBWM_JBWMPIXELS_H 9 | -------------------------------------------------------------------------------- /JBWMPoint.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #ifndef JBWM_JBWMPOINT_H 3 | #define JBWM_JBWMPOINT_H 4 | #include 5 | union JBWMPoint { 6 | struct{ 7 | int16_t x, y; 8 | }; 9 | int16_t array[2]; 10 | }; 11 | #endif//!JBWM_JBWMPOINT_H 12 | -------------------------------------------------------------------------------- /JBWMRectangle.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #ifndef JBWM_JBWMRECTANGLE_H 3 | #define JBWM_JBWMRECTANGLE_H 4 | #include 5 | union JBWMRectangle { 6 | struct { 7 | int16_t x, y, width, height; 8 | }; 9 | int16_t array[4]; 10 | }; 11 | #endif//!JBWM_JBWMRECTANGLE_H 12 | -------------------------------------------------------------------------------- /JBWMScreen.h: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #ifndef JBWM_JBWMSCREEN_H 6 | #define JBWM_JBWMSCREEN_H 7 | #include "JBWMPixels.h" 8 | #include 9 | #ifdef JBWM_USE_XFT 10 | #include 11 | #endif//JBWM_USE_XFT 12 | struct JBWMClient; 13 | struct JBWMScreen { 14 | Screen * xlib; 15 | #ifdef JBWM_USE_XFT 16 | XftDraw * xft; 17 | XftColor font_color; 18 | #else//!JBWM_USE_XFT 19 | XFontStruct *font; 20 | #endif//JBWM_USE_XFT 21 | Window supporting; 22 | struct JBWMPixels pixels; 23 | GC gc,border_gc; 24 | uint8_t id, vdesk, font_height; 25 | }; 26 | #endif//!JBWM_JBWMSCREEN_H 27 | -------------------------------------------------------------------------------- /JBWMSize.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #ifndef JBWM_JBWMSIZE_H 3 | #define JBWM_JBWMSIZE_H 4 | #include 5 | struct JBWMSize { 6 | uint16_t width, height; 7 | }; 8 | #endif//!JBWM_JBWMSIZE_H 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | LICENSE 2 | 3 | The MIT License (MIT) 4 | 5 | Copyright (c) 2017-2020 Alisa Bedard 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 12 | 13 | 14 | EVILWM LICENSE 15 | 16 | evilwm 1.0 17 | Copyright (C) 1999-2006 Ciaran Anscomb 18 | 19 | This is free software. You can do what you want to it, but if it 20 | breaks something, you get to pay for the counselling. The code was 21 | originally based on aewm, so this is distributed under the same terms, 22 | which follow. 23 | 24 | AEWM LICENCE 25 | 26 | Copyright (c) 1998-2000 Decklin Foster. 27 | 28 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS", WITHOUT ANY EXPRESS 29 | OR IMPLIED WARANTIES OF ANY KIND. IN NO EVENT SHALL THE AUTHOR BE 30 | HELD LIABLE FOR ANY DAMAGES CONNECTED WITH THE USE OF THIS PROGRAM. 31 | 32 | You are granted permission to copy, publish, distribute, and/or sell 33 | copies of this program and any modified versions or derived works, 34 | provided that this copyright and notice are not removed or altered. 35 | 36 | Portions of the code were based on 9wm, which contains this license: 37 | 38 | > 9wm is free software, and is Copyright (c) 1994 by David Hogan. 39 | > Permission is granted to all sentient beings to use this software, 40 | > to make copies of it, and to distribute those copies, provided 41 | > that: 42 | > 43 | > (1) the copyright and licence notices are left intact 44 | > (2) the recipients are aware that it is free software 45 | > (3) any unapproved changes in functionality are either 46 | > (i) only distributed as patches 47 | > or (ii) distributed as a new program which is not called 9wm 48 | > and whose documentation gives credit where it is due 49 | > (4) the author is not held responsible for any defects 50 | > or shortcomings in the software, or damages caused by it. 51 | > 52 | > There is no warranty for this software. Have a nice day. 53 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # jbwm - Minimalist Window Manager for X 2 | # Copyright 2008-2020, Alisa Bedard 3 | # Copyright 1999-2015, Ciaran Anscomb 4 | # See README for license and other details. 5 | version=1.64 6 | # PREFIX may be overridden in config.mk 7 | include config.mk 8 | exe=jbwm 9 | distname=$(exe)-$(version) 10 | #SCHEME=mit-scheme 11 | SCHEME=echo 12 | # Note that $(DESTDIR) is used by the Debian build process. 13 | dest=${DESTDIR}${PREFIX} 14 | jbwm_cflags+=-DVERSION=\"$(version)\" $(DEBIAN) 15 | jbwm_cflags+=-D_XOPEN_SOURCE=700 -std=c99 16 | jbwm_ldflags+=-lX11 -lXext -lpthread 17 | objects+=client.o events.o jbwm.o new.o mwm.o wm_state.o drag.o 18 | objects+=button_event.o keys.o util.o max.o select.o snap.o display.o 19 | objects+=exec.o main.o move_resize.o key_event.o vdesk.o draw.o 20 | objects+=geometry.o command_line.o ewmh.o ewmh_state.o ewmh_client.o 21 | objects+=ewmh_wm_state.o title_bar.o font.o shape.o atom.o ewmh_client_list.o 22 | $(exe): depend.mk $(objects) 23 | $(CC) ${CFLAGS} ${jbwm_cflags} ${jbwm_ldflags} \ 24 | $(LDFLAGS) $(objects) -o $@ 25 | strip $(exe) -o $(exe).tmp 26 | ls -l $(exe).tmp >> sz.log 27 | rm -f $(exe).tmp 28 | tail sz.log 29 | include depend.mk 30 | # Use `` for basename for BSD make compatibility 31 | ${objects}: 32 | ${CC} ${CFLAGS} ${jbwm_cflags} -c `basename $@ .o`.c 33 | strip: 34 | # Leave .plt.got 35 | strip -s \ 36 | -R .jcr \ 37 | -R .eh_frame \ 38 | -R .got \ 39 | -R .note \ 40 | -R .gnu.version \ 41 | -R .note.gnu.build-id \ 42 | -R .note.ABI-tag \ 43 | -R .eh_frame_hdr \ 44 | -R .comment \ 45 | -R .gnu.hash \ 46 | -R .shstrtab \ 47 | $(exe) 48 | INSTALL=install -c 49 | INSTALL_exe=$(INSTALL) 50 | INSTALL_DIR=install -d 51 | install: 52 | ${INSTALL_DIR} ${dest}/bin ${dest}/share/man/man1 \ 53 | ${dest}/share/licenses/${exe} 54 | ${INSTALL_exe} ${exe} ${dest}/bin 55 | ${INSTALL} ${exe}.1 ${dest}/share/man/man1 56 | ${INSTALL} -D -m644 LICENSE "${dest}/share/licenses/${exe}/LICENSE" 57 | clean: 58 | rm -f $(exe) *.o 59 | distclean: clean 60 | rm -f *~ *.out .*.swp .*.swn *.orig .*~ *~~ 61 | archive: distclean 62 | cd ..; tar cJf $(exe)-$(version).tar.xz $(exe) 63 | tags: 64 | ctags * 65 | indent: 66 | indent *.[ch] 67 | sed 's/ \/\//\/\//g' -i'~~' *.[ch] 68 | debug: clean 69 | ./configure -d 70 | make 71 | small: clean 72 | CFLAGS='-flto -Os -march=native' ./configure -estx 73 | make -j4 74 | cp jbwm jbwm.small.dbg 75 | make strip 76 | ls -l jbwm >> small.log 77 | tail small.log 78 | clang: clean 79 | make -f Makefile.clang 80 | depend.mk: *.c *.h 81 | chmod 755 mkdep.sh 82 | ./mkdep.sh 83 | cppcheck: 84 | cppcheck --enable=all -j 4 -DDEBUG --inline-suppr \ 85 | --inconclusive --std=c11 *.c \ 86 | > /dev/null 87 | check: small 88 | strip jbwm 89 | ls -l jbwm 90 | distcheck: archive 91 | ls -l | grep jbwm 92 | #EOF 93 | -------------------------------------------------------------------------------- /Makefile.clang: -------------------------------------------------------------------------------- 1 | # Copyright 2020, Alisa Bedard 2 | CC=clang 3 | include Makefile 4 | -------------------------------------------------------------------------------- /Makefile.small: -------------------------------------------------------------------------------- 1 | jbwm_cflags=-Os 2 | # Compile for current machine 3 | jbwm_cflags+=-march=native 4 | # Tuning 5 | jbwm_cflags+=-fomit-frame-pointer -pipe -flto 6 | #jbwm_cflags+=-W -Wall -Wextra 7 | # disable everything for minimal configuration 8 | #jbwm_cflags+=-DNDEBUG 9 | CFLAGS=${jbwm_cflags} 10 | include jbwm.mk 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JBWM 2 | ![Screenshot](screenshot.png) 3 | 4 | ## FEATURES of JBWM 5 | * *Virtual desktops* with Super-{1-0} (Can be changed in config.h) 6 | and Super-Left and Super-Right. You can access 256 desktops by 7 | using Super-Left/Right. Move windows to a desktop with 8 | Shift-Super-{[1-0]|Left|Right}. 9 | * *Keyboard oriented* control, using the Super, Control and Shift keys 10 | for operations including horizontal maximization, vertical maximization, 11 | full maximization, full screen mode, shading, window closing, 12 | terminal spawning, desktop switching, window moving, window resize, 13 | window manager exit, window raising, window lowering, 14 | and window sticking to all desktops. 15 | * Tiny binary size (~35k on x86-64 with -Os) 16 | * *Title bar* support 17 | * *Xft* support if wanted 18 | * *EWMH* support 19 | * *Window shading* with title bar 20 | * Code cleanups, simple UI and key bindings 21 | * Use of C99 features where appropriate. 22 | 23 | ## DIRECTION 24 | Though jbwm features small size, its main design goal is practical usefulness. 25 | If a change increases binary size but speeds execution, development, or user 26 | interaction, then the change is more than welcome. If you want to see a feature 27 | or contribute code, let me know. I use jbwm as my primary and sole window 28 | manager, however I may not see problems that fall outside of my usage patterns, 29 | so bug reports are also much appreciated. 30 | 31 | ## RELEASES 32 | Releases are made when sufficient changes are made to the code base. Releases 33 | fixing critical bugs are made as soon as possible. 34 | 35 | ## INSTALLATION 36 | Edit configuration options in Makefile and config.h, then build: 37 | ```sh 38 | $ ./configure 39 | $ make 40 | # make install 41 | ``` 42 | 43 | ## REQUIREMENTS 44 | * libX11 45 | 46 | ## ACKNOWLEDGMENTS 47 | 48 | evilwm, by Ciaran Anscomb . http://www.6809.org.uk/evilwm/ 49 | The original code base for this project was that of aewm by Decklin 50 | Foster. His code is very clean and, in later versions, very well 51 | commented. http://www.red-bean.com/~decklin/aewm/ 52 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | Issues: 2 | 3 | * Maximization of shaped windows 4 | 5 | Ideas follow: 6 | 7 | ***Would love others to test this and help out*** 8 | * Too much preprocessor goop. 9 | * Xft alternative 10 | * Possible xcb port 11 | * Too many choices for compile time. 12 | * Too many globals. 13 | 14 | -------------------------------------------------------------------------------- /astylerc: -------------------------------------------------------------------------------- 1 | style=linux 2 | indent=force-tab=8 3 | indent-cases 4 | indent-preproc-define 5 | convert-tabs 6 | min-conditional-indent=0 7 | break-blocks 8 | unpad-paren 9 | delete-empty-lines 10 | align-pointer=name 11 | keep-one-line-blocks 12 | remove-brackets 13 | keep-one-line-statements 14 | max-code-length=70 15 | -------------------------------------------------------------------------------- /atom.c: -------------------------------------------------------------------------------- 1 | #include "atom.h" 2 | char * jbwm_atom_names[]={ 3 | "_NET_SUPPORTED", 4 | "_NET_CURRENT_DESKTOP", 5 | "_NET_NUMBER_OF_DESKTOPS", 6 | "_NET_DESKTOP_VIEWPORT", 7 | "_NET_DESKTOP_GEOMETRY", 8 | "_NET_SUPPORTING_WM_CHECK", 9 | "_NET_ACTIVE_WINDOW", 10 | "_NET_MOVERESIZE_WINDOW", 11 | "_NET_CLOSE_WINDOW", 12 | "_NET_CLIENT_LIST", 13 | "_NET_VIRTUAL_ROOTS", 14 | "_NET_CLIENT_LIST_STACKING", 15 | "_NET_FRAME_EXTENTS", 16 | "_NET_WM_ALLOWED_ACTIONS", 17 | "_NET_WM_NAME", 18 | "_NET_WM_DESKTOP", 19 | "_NET_WM_MOVERESIZE", 20 | "_NET_WM_PID", 21 | "_NET_WM_WINDOW_TYPE", 22 | "_NET_WM_STATE", 23 | "_NET_WM_ACTION_MOVE", 24 | "_NET_WM_ACTION_RESIZE", 25 | "_NET_WM_ACTION_CLOSE", 26 | "_NET_WM_ACTION_SHADE", 27 | "_NET_WM_ACTION_FULLSCREEN", 28 | "_NET_WM_ACTION_CHANGE_DESKTOP", 29 | "_NET_WM_ACTION_ABOVE", 30 | "_NET_WM_ACTION_BELOW", 31 | "_NET_WM_ACTION_MAXIMIZE_HORZ", 32 | "_NET_WM_ACTION_MAXIMIZE_VERT", 33 | "_NET_WM_STATE_STICKY", 34 | "_NET_WM_STATE_MAXIMIZED_VERT", 35 | "_NET_WM_STATE_MAXIMIZED_HORZ", 36 | "_NET_WM_STATE_SHADED", 37 | "_NET_WM_STATE_HIDDEN", 38 | "_NET_WM_STATE_FULLSCREEN", 39 | "_NET_WM_STATE_ABOVE", 40 | "_NET_WM_STATE_BELOW", 41 | "_NET_WM_STATE_FOCUSED", 42 | "_MOTIF_WM_HINTS" 43 | }; 44 | Atom jbwm_atoms[JBWM_ATOM_COUNT]; 45 | void jbwm_create_atoms(Display *d){ 46 | XInternAtoms(d,jbwm_atom_names,JBWM_ATOM_COUNT,False,jbwm_atoms); 47 | } 48 | -------------------------------------------------------------------------------- /atom.h: -------------------------------------------------------------------------------- 1 | #ifndef JBWM_ATOM_H 2 | #define JBWM_ATOM_H 3 | #include "JBWMAtomName.h" 4 | #include 5 | extern char * jbwm_atom_names[]; 6 | extern Atom jbwm_atoms[]; 7 | void jbwm_create_atoms(Display *d); 8 | #endif//!JBWM_ATOM_H 9 | -------------------------------------------------------------------------------- /button_event.c: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | //#undef DEBUG 6 | #include "button_event.h" 7 | #include "client.h" 8 | #include "drag.h" 9 | #include "log.h" 10 | #include "title_bar.h" 11 | #include "wm_state.h" 12 | static void handle_title_bar_button(XButtonEvent * e, struct JBWMClient * c, 13 | struct JBWMClient ** head_client, struct JBWMClient ** current_client) 14 | { 15 | JBWM_LOG("e->window: %d, c->title_bar: %d, e->subwindow: %d", 16 | (int)e->window, (int)c->tb.win, (int)e->subwindow); 17 | JBWM_LOG("c->tb.close: %d", (int)c->tb.close); 18 | JBWM_LOG("e->button: %d", (int)e->button); 19 | struct JBWMClientOptions * o = &c->opt; 20 | if (!e->subwindow) 21 | jbwm_drag(c, head_client, false); 22 | else if (e->subwindow == c->tb.close && !o->no_close) 23 | jbwm_send_wm_delete(c); 24 | else if (e->subwindow == c->tb.resize && !o->no_resize) 25 | jbwm_drag(c, head_client, !c->opt.no_resize); 26 | else if (e->subwindow == c->tb.shade && !o->no_shade) 27 | jbwm_toggle_shade(c); 28 | else if (e->subwindow == c->tb.stick) 29 | jbwm_toggle_sticky(c, current_client); 30 | else 31 | jbwm_drag(c, head_client, false); 32 | } 33 | void jbwm_handle_button_event(XButtonEvent * e, struct JBWMClient * c, 34 | struct JBWMClient ** head_client, 35 | struct JBWMClient ** current_client) 36 | { 37 | JBWM_LOG("jbwm_handle_button_event"); 38 | if (c) { // keep this check, added in response to segfault 39 | const bool fs = c->opt.fullscreen; 40 | Display * d = e->display; 41 | switch (e->button) { 42 | case Button1: 43 | if (fs) 44 | XRaiseWindow(d, c->parent); 45 | else 46 | handle_title_bar_button(e, c, head_client, current_client); 47 | break; 48 | case Button2: 49 | XLowerWindow(d, c->parent); 50 | break; 51 | case Button3: 52 | /* Resize operations more useful here, 53 | rather than for third button, for laptop 54 | users especially, where it is difficult 55 | to register a middle button press, even 56 | with X Emulate3Buttons enabled. */ 57 | if (fs) 58 | XLowerWindow(d, c->parent); 59 | else 60 | jbwm_drag(c, head_client, !c->opt.shaded); 61 | break; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /button_event.h: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #ifndef JBWM_BUTTON_EVENT_H 6 | #define JBWM_BUTTON_EVENT_H 7 | #include 8 | struct JBWMClient; 9 | void jbwm_handle_button_event(XButtonEvent * e, struct JBWMClient * c, 10 | struct JBWMClient ** head_client, 11 | struct JBWMClient ** current_client); 12 | #endif /* JBWM_BUTTON_EVENT_H */ 13 | -------------------------------------------------------------------------------- /client.c: -------------------------------------------------------------------------------- 1 | /* jbwm - Minimalist Window Manager for X */ 2 | /* Copyright 2008-2020, Alisa Bedard */ 3 | /* Copyright 1999-2015, Ciaran Anscomb */ 4 | /* See README for license and other details. */ 5 | #include "client.h" 6 | #include 7 | #include "ewmh.h" 8 | #include "ewmh_state.h" 9 | #include "atom.h" 10 | #include "select.h" 11 | #include "title_bar.h" 12 | #include "util.h" 13 | #include "vdesk.h" 14 | #include "wm_state.h" 15 | #include 16 | #include 17 | /* Relink c's linked list to exclude c. 18 | * Note: As *c and *i may alias each other, use of 'restrict' 19 | * in relink would be invalid. */ 20 | static void relink(const struct JBWMClient * c, struct JBWMClient * i, 21 | struct JBWMClient ** head_client, struct JBWMClient ** current_client) 22 | { 23 | if (*(current_client) == c) 24 | *(current_client) = NULL; // flag as invalid 25 | if (i == c) /* c is head client. */ 26 | *(head_client) = c->next; /* removed first client. */ 27 | if (i && i->next) 28 | relink(c, (i->next != c) ? i->next : (i->next = c->next), 29 | head_client, current_client); 30 | } 31 | void jbwm_set_client_vdesk(struct JBWMClient * c, uint8_t desktop) 32 | { 33 | Display *d; 34 | if(c){ 35 | d=c->screen->xlib->display; 36 | c->vdesk=desktop; 37 | /* Save in an atomic property, useful for restart and deskbars. */ 38 | XChangeProperty(d, c->window, jbwm_atoms[JBWM_NET_WM_DESKTOP], 39 | XA_CARDINAL, 8, PropModeReplace, (unsigned char *)&desktop, 1); 40 | if(c->screen->vdesk!=c->vdesk) 41 | jbwm_hide_client(c); 42 | } 43 | } 44 | /* Return the client that has specified window as either window or parent. 45 | * This is the a frequently called function. Show restraint in adding any 46 | * future tests. */ 47 | struct JBWMClient * jbwm_find_client( 48 | struct JBWMClient *head, const Window w) 49 | { 50 | return (head && head->parent != w && head->window != w 51 | && head->tb.win != w) ? jbwm_find_client(head->next, w) : head; 52 | 53 | } 54 | void jbwm_toggle_sticky(struct JBWMClient * c, 55 | struct JBWMClient ** current_client) 56 | { 57 | if(c){ 58 | c->opt.sticky ^= true; /* toggle */ 59 | jbwm_select_client(c, current_client); 60 | jbwm_update_title_bar(c); 61 | { 62 | Display *d; 63 | d=c->screen->xlib->display; 64 | (c->opt.sticky ? jbwm_ewmh_add_state : jbwm_ewmh_remove_state) 65 | (d, c->window, 66 | jbwm_atoms[JBWM_NET_WM_STATE_STICKY]); 67 | } 68 | } 69 | } 70 | /* Free client and destroy its windows and properties. */ 71 | void jbwm_client_free(struct JBWMClient * c, struct JBWMClient ** head_client, 72 | struct JBWMClient ** current_client) 73 | { 74 | Display *d; 75 | const Window w = c->window, parent = c->parent; 76 | const union JBWMRectangle * p = &c->size; 77 | d = c->screen->xlib->display; 78 | /* Per ICCCM + wm-spec */ 79 | XDeleteProperty(d, w, jbwm_atoms[JBWM_NET_WM_STATE]); 80 | XDeleteProperty(d, w, jbwm_atoms[JBWM_NET_WM_DESKTOP]); 81 | XReparentWindow(d, w, c->screen->xlib->root, p->x, p->y); 82 | XRemoveFromSaveSet(d, w); 83 | if(parent) 84 | XDestroyWindow(d, parent); 85 | relink(c, *head_client, head_client, current_client); 86 | free(c); 87 | } 88 | void jbwm_hide_client(const struct JBWMClient * c) 89 | { 90 | XUnmapWindow(c->screen->xlib->display, c->parent); 91 | jbwm_set_wm_state(c, IconicState); 92 | } 93 | void jbwm_restore_client(const struct JBWMClient * c) 94 | { 95 | XMapWindow(c->screen->xlib->display, c->parent); 96 | jbwm_set_wm_state(c, NormalState); 97 | } 98 | -------------------------------------------------------------------------------- /client.h: -------------------------------------------------------------------------------- 1 | /* jbwm - Minimalist Window Manager for X */ 2 | /* Copyright 2008-2020, Alisa Bedard */ 3 | /* Copyright 1999-2015, Ciaran Anscomb */ 4 | /* See README for license and other details. */ 5 | #ifndef JBWM_CLIENT_H 6 | #define JBWM_CLIENT_H 7 | #include 8 | #include 9 | struct JBWMClient; 10 | /* Free client and destroy its windows and properties. */ 11 | void jbwm_client_free(struct JBWMClient * c, 12 | struct JBWMClient ** head_client, 13 | struct JBWMClient ** current_client); 14 | /* Get the client with input focus. */ 15 | void jbwm_hide_client(const struct JBWMClient * c); 16 | /* Move the client to the specified virtual desktop */ 17 | void jbwm_set_client_vdesk(struct JBWMClient * c, uint8_t desktop); 18 | void jbwm_toggle_sticky(struct JBWMClient * c, 19 | struct JBWMClient ** current_client); 20 | void jbwm_restore_client(struct JBWMClient const * c); 21 | __attribute__((pure)) 22 | /* Return the client that has specified window as either window or parent. 23 | * This is the third most called function. Show restraint in adding any 24 | * future tests. */ 25 | struct JBWMClient * jbwm_find_client(struct JBWMClient * head, 26 | const Window w); 27 | #endif/* !JBWM_CLIENT_H */ 28 | -------------------------------------------------------------------------------- /command_line.c: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #include "command_line.h" 6 | // 7 | #include "config.h" 8 | #include "log.h" 9 | // 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | // 16 | void jbwm_parse_command_line(const int argc, char **argv) 17 | { 18 | JBWM_LOG("parse_argv(%d,%s...)", argc, argv[0]); 19 | static const char optstring[] = "1:2:v"; 20 | int8_t opt; 21 | while((opt = getopt(argc, argv, optstring)) != -1) 22 | switch (opt) { 23 | case 'v': 24 | printf("%s version %s\n", argv[0], VERSION); 25 | exit(0); 26 | default: 27 | printf("%s -[%s]\n", argv[0], optstring); 28 | exit(1); 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /command_line.h: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #ifndef JBWM_COMMAND_LINE_H 6 | #define JBWM_COMMAND_LINE_H 7 | void jbwm_parse_command_line(const int argc, char **argv); 8 | #endif//!JBWM_COMMAND_LINE_H 9 | -------------------------------------------------------------------------------- /config.h: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #ifndef JBWM_CONFIG_H 6 | #define JBWM_CONFIG_H 7 | #include // for keymasks 8 | /* Note: Also, adjust the values in JBWMDefaults.h as necessary. */ 9 | #define JBWM_TERM "xterm" 10 | /* Default fonts */ 11 | #ifdef JBWM_USE_XFT 12 | #define JBWM_FONT "Sans:size=8:aspect=1.2" 13 | #else//!JBWM_USE_XFT 14 | #define JBWM_FONT "fixed" 15 | #endif//JBWM_USE_XFT 16 | /* Default colors */ 17 | #ifndef USE_OLD_THEME 18 | //#define JBWM_FG "#bbf" 19 | #define JBWM_FG "white" 20 | #define JBWM_FC "green1" 21 | #define JBWM_BG "black" 22 | #define JBWM_CLOSE "#a77" 23 | #define JBWM_RESIZE "#aaa" 24 | #define JBWM_SHADE "#77a" 25 | #define JBWM_STICK "#7a7" 26 | #define JBWM_NAME "jbwm" 27 | #else//USE_OLD_THEME 28 | #define JBWM_FG "#bad0ff" 29 | #define JBWM_FC "#00ff2f" 30 | #define JBWM_BG "#3b4352" 31 | #define JBWM_CLOSE "#ff2600" 32 | #define JBWM_RESIZE "#00a1ff" 33 | #define JBWM_SHADE "#ffe200" 34 | #define JBWM_STICK "#5bf662" 35 | #define JBWM_NAME "jbwm" 36 | #endif//!USE_OLD_THEME 37 | /* Compile-time defaults of an integer type shall be stored here. */ 38 | enum { 39 | JBWM_KEYMASK_GRAB = Mod1Mask | ControlMask, 40 | JBWM_KEYMASK_MOD = ShiftMask, 41 | JBWM_SNAP = 10, 42 | JBWM_RESIZE_INCREMENT = 20, 43 | JBWM_NUMBER_OF_DESKTOPS = 255 44 | }; 45 | #endif//JBWM_CONFIG_H 46 | -------------------------------------------------------------------------------- /configure: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright 2020, Alisa Bedard 3 | #set -x 4 | OS=`uname -s` 5 | CF=config.mk 6 | echo "# Configuration for $OS" > $CF 7 | echo "CFLAGS=${CFLAGS}" >> $CF 8 | echo "LDFLAGS=${LDFLAGS}" >> $CF 9 | echo "DESTDIR=${DESTDIR}" >> $CF 10 | echo "PREFIX=${PREFIX:-/usr/local}" >> $CF 11 | DEBUG=false USE_GDB=false SMALL=false USE_XFT=false USE_XOSD=false 12 | while getopts 'dghoSsx' opt; do 13 | case $opt in 14 | d) DEBUG=true ;; 15 | g) USE_GDB=true ;; 16 | o) USE_XOSD=true ;; 17 | S) USE_GDB=true SMALL=true ;; 18 | s) SMALL=true ;; 19 | x) USE_XFT=true ;; 20 | h|?) for line in \ 21 | '-d enable debugging with verbose log output' \ 22 | '-g enable debug symbols' \ 23 | '-h show configure usage' \ 24 | '-S optimize for size with symbols' \ 25 | '-s optimize for size' \ 26 | '-x use Xft fonts' \ 27 | '-o use xosd library' \ 28 | '-? show usage' \ 29 | ; do 30 | echo $line 31 | done 32 | exit 0 ;; 33 | esac 34 | done 35 | # Append path if exists: 1:path, 2:destinatio, 3:prefix 36 | check(){ 37 | local path=$1 dest=$2 prefix=$3 38 | echo -n "Checking for $1... " 39 | if [ -d $path ]; then 40 | echo 'found' 41 | eval "$dest=\"\$$dest $prefix$path\"" 42 | # For NetBSD: 43 | if [ "$prefix" = "-L" ]; then 44 | eval "$dest=\"\$$dest -Wl,-R$path\"" 45 | fi 46 | return 0 47 | fi 48 | echo 'not found' 49 | return 1 50 | } 51 | check /usr/local/include jbwm_cflags -I 52 | check /usr/X11R7/include jbwm_cflags -I 53 | check /usr/X11R6/include jbwm_cflags -I 54 | check /usr/X11R7/include/freetype2 jbwm_cflags -I 55 | check /usr/X11R6/include/freetype2 jbwm_cflags -I 56 | check /usr/local/lib jbwm_ldflags -L 57 | check /usr/X11R7/lib jbwm_ldflags -L 58 | check /usr/X11R6/lib jbwm_ldflags -L 59 | echo "jbwm_cflags=$jbwm_cflags" >> $CF 60 | echo "jbwm_ldflags=$jbwm_ldflags" >> $CF 61 | if $SMALL; then 62 | echo SMALL 63 | echo 'jbwm_cflags+=-DJBWM_SMALL -Os' >> $CF 64 | fi 65 | if $DEBUG; then 66 | echo DEBUG 67 | echo 'include debug.mk' >> $CF 68 | fi 69 | if $USE_GDB; then 70 | echo USE_GDB 71 | echo 'jbwm_cflags+=-ggdb -O0' >> $CF 72 | echo 'include debug_gcc.mk' >> $CF 73 | fi 74 | if $USE_XFT; then 75 | echo 'include xft.mk' >> $CF 76 | fi 77 | if $USE_XOSD; then 78 | echo 'include xosd.mk' >> $CF 79 | fi 80 | -------------------------------------------------------------------------------- /dbg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export DISPLAY=:1 3 | make debug 4 | exec gdb ./jbwm 5 | -------------------------------------------------------------------------------- /debug.mk: -------------------------------------------------------------------------------- 1 | # Debug 2 | jbwm_cflags=-O0 -ggdb -DDEBUG 3 | # Select compiler 4 | #include debug_clang.mk 5 | include debug_gcc.mk 6 | -------------------------------------------------------------------------------- /debug_clang.mk: -------------------------------------------------------------------------------- 1 | # Debug 2 | CC=clang 3 | jbwm_cflags+=-W -Wall -Wextra -Werror 4 | jbwm_cflags+=-Wuninitialized -Wstrict-overflow=5 5 | #jbwm_cflags+=-Wlarger-than=512 6 | #jbwm_cflags+=-Wframe-larger-than=512 7 | jbwm_cflags+=-Wcast-qual -Wcast-align 8 | jbwm_cflags+=-Weverything 9 | jbwm_cflags+=-Wno-conversion 10 | jbwm_cflags+=-Wno-vla 11 | jbwm_cflags+=-Wno-switch-enum 12 | -------------------------------------------------------------------------------- /debug_gcc.mk: -------------------------------------------------------------------------------- 1 | # Debug 2 | CC=gcc 3 | # Profile 4 | jbwm_cflags+=-pg -no-pie 5 | # Enable all warnings 6 | jbwm_cflags+=-W -Wall -Wextra -Werror 7 | jbwm_cflags+=-Wuninitialized -Wstrict-overflow=5 8 | jbwm_cflags+=-Wsuggest-attribute=pure 9 | jbwm_cflags+=-Wsuggest-attribute=const 10 | jbwm_cflags+=-Wsuggest-attribute=noreturn 11 | jbwm_cflags+=-Wsuggest-attribute=format 12 | #jbwm_cflags+=-Wlarger-than=512 13 | #jbwm_cflags+=-Wframe-larger-than=512 14 | jbwm_cflags+=-Wcast-qual -Wcast-align 15 | jbwm_cflags+=-Wjump-misses-init 16 | jbwm_cflags+=-Wlogical-op 17 | jbwm_cflags+=-Wmissing-prototypes 18 | jbwm_cflags+=-Wredundant-decls -Wpointer-sign 19 | jbwm_cflags+=-fstrict-aliasing -Wstrict-aliasing=2 20 | jbwm_cflags+=-Wformat=2 21 | jbwm_cflags+=-Wno-pointer-to-int-cast 22 | jbwm_cflags+=-Wno-narrowing 23 | -------------------------------------------------------------------------------- /depend.mk: -------------------------------------------------------------------------------- 1 | atom.o: atom.c atom.h 2 | button_event.o: button_event.c button_event.h client.h drag.h log.h title_bar.h wm_state.h 3 | client.o: client.c client.h ewmh.h ewmh_state.h atom.h select.h title_bar.h util.h vdesk.h wm_state.h 4 | command_line.o: command_line.c command_line.h config.h log.h 5 | display.o: display.c display.h client.h config.h log.h util.h 6 | drag.o: drag.c drag.h font.h JBWMClient.h move_resize.h snap.h 7 | draw.o: draw.c draw.h font.h 8 | events.o: events.c events.h button_event.h client.h ewmh.h ewmh_client.h ewmh_client_list.h JBWMScreen.h key_event.h log.h move_resize.h new.h select.h title_bar.h util.h wm_state.h 9 | ewmh.o: ewmh.c ewmh.h atom.h config.h JBWMClient.h log.h macros.h 10 | ewmh_client.o: ewmh_client.c ewmh_client.h client.h config.h drag.h ewmh.h ewmh_wm_state.h atom.h select.h util.h vdesk.h wm_state.h 11 | ewmh_client_list.o: ewmh_client_list.c ewmh_client_list.h JBWMClient.h atom.h config.h log.h macros.h 12 | ewmh_state.o: ewmh_state.c ewmh_state.h client.h drag.h ewmh.h jbwm.h atom.h log.h max.h select.h util.h wm_state.h 13 | ewmh_wm_state.o: ewmh_wm_state.c ewmh_wm_state.h atom.h JBWMClient.h client.h ewmh.h ewmh_state.h log.h max.h util.h 14 | exec.o: exec.c exec.h config.h 15 | font.o: font.c font.h config.h util.h 16 | geometry.o: geometry.c geometry.h JBWMClient.h JBWMScreen.h JBWMSize.h log.h macros.h 17 | jbwm.o: jbwm.c jbwm.h config.h ewmh.h font.h atom.h JBWMScreen.h keys.h log.h new.h util.h vdesk.h 18 | key_event.o: key_event.c key_event.h JBWMClient.h JBWMKeys.h JBWMScreen.h client.h config.h drag.h exec.h log.h max.h move_resize.h select.h snap.h title_bar.h vdesk.h wm_state.h 19 | keys.o: keys.c keys.h JBWMKeys.h config.h 20 | main.o: main.c JBWMScreen.h atom.h command_line.h display.h events.h font.h jbwm.h 21 | max.o: max.c max.h ewmh.h ewmh_state.h font.h atom.h JBWMClient.h move_resize.h title_bar.h 22 | move_resize.o: move_resize.c move_resize.h JBWMClient.h font.h log.h mwm.h shape.h title_bar.h 23 | mwm.o: mwm.c mwm.h ewmh.h atom.h JBWMClient.h log.h mwmproto.h util.h 24 | new.o: new.c new.h client.h config.h ewmh.h geometry.h atom.h JBWMClient.h keys.h log.h mwm.h select.h shape.h snap.h util.h vdesk.h 25 | select.o: select.c select.h client.h ewmh.h ewmh_state.h atom.h JBWMClient.h util.h 26 | shape.o: shape.c shape.h JBWMClient.h log.h 27 | snap.o: snap.c snap.h config.h JBWMClient.h JBWMPoint.h JBWMSize.h 28 | title_bar.o: title_bar.c title_bar.h config.h draw.h ewmh.h ewmh_state.h font.h atom.h move_resize.h util.h wm_state.h 29 | util.o: util.c util.h 30 | vdesk.o: vdesk.c vdesk.h client.h config.h draw.h ewmh.h font.h log.h atom.h JBWMClient.h JBWMScreen.h util.h 31 | wm_state.o: wm_state.c wm_state.h ewmh.h ewmh_state.h atom.h log.h util.h 32 | -------------------------------------------------------------------------------- /display.c: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #include "display.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "client.h" 8 | #include "config.h" 9 | #include "log.h" 10 | #include "util.h" 11 | static struct JBWMClient ** current_client; 12 | static struct JBWMClient ** head_client; 13 | void jbwm_set_up_error_handler(struct JBWMClient ** head_client_arg, 14 | struct JBWMClient ** current_client_arg){ 15 | head_client=head_client_arg; 16 | current_client=current_client_arg; 17 | } 18 | __attribute__((pure)) 19 | static int handle_xerror(Display * d __attribute__((unused)), 20 | XErrorEvent * e) 21 | { 22 | struct JBWMClient *c; 23 | switch (e->error_code) { 24 | case BadAccess: 25 | if (e->request_code == X_ChangeWindowAttributes) 26 | jbwm_error("Cannot access the root window."); 27 | break; 28 | case BadWindow: 29 | c=jbwm_find_client(*head_client, e->resourceid); 30 | if(c) 31 | jbwm_client_free(c, head_client, current_client); 32 | break; 33 | case BadAtom: 34 | break; 35 | } 36 | JBWM_LOG("XError type:%d xid:%lu serial:%lu" 37 | " err:%d req:%d min:%d\n", 38 | e->type, e->resourceid, e->serial, e->error_code, 39 | e->request_code, e->minor_code); 40 | return 0; // Ignore everything else. 41 | } 42 | Display * jbwm_open_display(void) 43 | { 44 | Display * display; 45 | errno = ECONNREFUSED; // Default error message 46 | display=XOpenDisplay(NULL); 47 | if(!display) 48 | jbwm_error(getenv("DISPLAY")); 49 | XSetErrorHandler(handle_xerror); 50 | return display; 51 | } 52 | -------------------------------------------------------------------------------- /display.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #ifndef JBWM_DISPLAY_H 3 | #define JBWM_DISPLAY_H 4 | #include 5 | struct JBWMClient; 6 | void jbwm_set_up_error_handler(struct JBWMClient ** head_client_arg, 7 | struct JBWMClient ** current_client_arg); 8 | Display * jbwm_open_display(void); 9 | #endif//!JBWM_DISPLAY_H 10 | -------------------------------------------------------------------------------- /drag.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2020, Alisa Bedard */ 2 | #include "drag.h" 3 | #include "font.h" 4 | #include "JBWMClient.h" 5 | #include "move_resize.h" 6 | #include "snap.h" 7 | #include 8 | #include 9 | enum { 10 | JBWMMouseMask = ButtonPressMask | ButtonReleaseMask 11 | | PointerMotionMask 12 | }; 13 | extern inline void jbwm_warp(Display * dpy, const Window w, const short x, 14 | const short y); 15 | __attribute__((nonnull)) 16 | static inline void query_pointer(Display * dpy, Window w, 17 | int16_t * p) 18 | { 19 | int x, y; 20 | int d; /* dummy integer */ 21 | unsigned int u; /* dummy unsigned integer */ 22 | XQueryPointer(dpy, w, &w, &w, &d, &d, &x, &y, &u); 23 | p[0] = x; 24 | p[1] = y; 25 | } 26 | __attribute__((nonnull)) 27 | static void draw_outline(struct JBWMClient * c) 28 | { 29 | if(c->opt.border){ 30 | uint8_t const fh=c->screen->font_height, o = (c->opt.no_title_bar^1)*fh; 31 | const union JBWMRectangle * g = &c->size; 32 | enum { BORDER = 1 }; 33 | Display * d = c->screen->xlib->display; 34 | XDrawRectangle(d, c->screen->xlib->root, c->screen->border_gc, 35 | g->x, g->y - o, g->width + BORDER, g->height + BORDER + o); 36 | } else { 37 | jbwm_move_resize(c); 38 | } 39 | } 40 | static void drag_event_loop(struct JBWMClient * c, 41 | struct JBWMClient ** head_client, int16_t * start, bool const resize) 42 | { 43 | Display *d; 44 | union JBWMRectangle * g; 45 | XEvent e; 46 | /***/ 47 | d=c->screen->xlib->display; 48 | g = &c->size; 49 | for(;;){ 50 | XMaskEvent(d, JBWMMouseMask, &e); 51 | if(e.type==MotionNotify){ 52 | int16_t p[]={e.xmotion.x,e.xmotion.y}; 53 | draw_outline(c); 54 | if(resize){ 55 | /* Compute distance. */ 56 | p[0]=abs(g->array[0]-p[0]); 57 | p[1]=abs(g->array[1]-p[1]); 58 | /* Avoid client crashes if the axis geometry is 0. */ 59 | g->array[2]=p[0]>0?p[0]:1; 60 | g->array[3]=p[1]>0?p[1]:1; 61 | } else { /* move */ 62 | p[0]+=start[0]; 63 | p[1]+=start[1]; 64 | g->array[0]=p[0]; 65 | g->array[1]=p[1]; 66 | jbwm_snap_client(c, head_client); 67 | } 68 | draw_outline(c); /* Erase the previous outline. */ 69 | /* Test that this function remains an atomic call by 70 | using its recursive definition. 71 | drag_event_loop(c, start, resize); */ 72 | } else 73 | break; 74 | } 75 | } 76 | /* Drag the specified client. Resize the client if resize is true. */ 77 | void jbwm_drag(struct JBWMClient * c, struct JBWMClient ** head_client, 78 | const bool resize) 79 | { 80 | int16_t start[2]; 81 | Display * d = c->screen->xlib->display; 82 | Window const r = c->screen->xlib->root; 83 | union JBWMRectangle * g = &c->size; 84 | Cursor const cursor = XCreateFontCursor(d, XC_fleur); 85 | XRaiseWindow(d, c->parent); 86 | if (!(resize && (c->opt.no_resize || c->opt.shaded))){ 87 | XGrabPointer(d, r, false, JBWMMouseMask, GrabModeAsync, 88 | GrabModeAsync, None, cursor, CurrentTime); 89 | if (resize){ 90 | jbwm_warp(d, c->window, g->width, g->height); 91 | } 92 | query_pointer(d, r, start); 93 | /* Adjust for the current window position to find the offset. */ 94 | start[0]=g->array[0]-start[0]; 95 | start[1]=g->array[1]-start[1]; 96 | drag_event_loop(c, head_client, start, resize); 97 | draw_outline(c); 98 | XUngrabPointer(d, CurrentTime); 99 | jbwm_move_resize(c); 100 | } 101 | } 102 | 103 | -------------------------------------------------------------------------------- /drag.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #ifndef JBWM_DRAG_H 3 | #define JBWM_DRAG_H 4 | #include 5 | #include 6 | struct JBWMClient; 7 | /* Drag the specified client. Resize the client if resize is true. */ 8 | void jbwm_drag(struct JBWMClient * c, struct JBWMClient ** head_client, 9 | const bool resize) 10 | __attribute__((nonnull)); 11 | /* Warp the pointer to the specified position. */ 12 | inline void jbwm_warp(Display * dpy, const Window w, const short x, 13 | const short y) 14 | { 15 | XWarpPointer(dpy, None, w, 0, 0, 0, 0, x, y); 16 | } 17 | #endif//!JBWM_DRAG_H 18 | -------------------------------------------------------------------------------- /draw.c: -------------------------------------------------------------------------------- 1 | #include "draw.h" 2 | #include "font.h" 3 | void jbwm_draw_string(struct JBWMScreen *s, Window const target, 4 | int16_t const x, int16_t const y, char *text, size_t const length){ 5 | #ifdef JBWM_USE_XFT 6 | XftDraw *xd; 7 | xd = s->xft; 8 | XftDrawChange(xd, target); 9 | XftDrawStringUtf8(xd, &s->font_color, jbwm_get_font(), 10 | x, /*jbwm_get_font_ascent()+*/y, (XftChar8 *)text, length); 11 | #else//!JBWM_USE_XFT 12 | XDrawString(s->xlib->display,target,s->gc,x, 13 | /*jbwm_get_font_ascent()+*/y, text, length); 14 | #endif//JBWM_USE_XFT 15 | } 16 | -------------------------------------------------------------------------------- /draw.h: -------------------------------------------------------------------------------- 1 | #ifndef JBWM_DRAW_H 2 | #define JBWM_DRAW_H 3 | #include "JBWMScreen.h" 4 | void jbwm_draw_string(struct JBWMScreen *s, Window const target, 5 | int16_t const x, int16_t const y, char *text, size_t const length); 6 | #endif//!JBWM_DRAW_H 7 | -------------------------------------------------------------------------------- /events.c: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #include "events.h" 6 | #include 7 | #include "button_event.h" 8 | #include "client.h" 9 | #include "ewmh.h" 10 | #include "ewmh_client.h" 11 | #include "ewmh_client_list.h" 12 | #include "JBWMScreen.h" 13 | #include "key_event.h" 14 | #include "log.h" 15 | #include "move_resize.h" 16 | #include "new.h" 17 | #include "select.h" 18 | #include "title_bar.h" 19 | #include "util.h" 20 | #include "wm_state.h" 21 | // Set log level for events 22 | #define JBWM_LOG_EVENTS 1 23 | static struct JBWMScreen * get_screen(struct JBWMScreen *s, 24 | const Window root, const int i) { 25 | return RootWindowOfScreen(s[i].xlib) == root ? s 26 | // Check that the next iteration is not outside array bounds, using 27 | // suppporting field as validation 28 | : s[i + 1].supporting ? get_screen(s,root, i + 1) : s; 29 | } 30 | static void jbwm_handle_PropertyNotify(XEvent * ev, struct JBWMClient * c) 31 | { 32 | if (c) { 33 | XPropertyEvent * e = &ev->xproperty; 34 | if (e->state != PropertyNewValue) 35 | return; 36 | if (e->atom == XA_WM_NAME) 37 | jbwm_update_title_bar(c); 38 | else { 39 | Display * d = e->display; 40 | #if JBWM_LOG_EVENTS > 3 41 | jbwm_print_atom(d, e->atom, __FILE__, __LINE__); 42 | #endif//JBWM_LOG_EVENTS > 3 43 | if (e->atom == jbwm_get_wm_state(d)) 44 | jbwm_move_resize(c); 45 | } 46 | } 47 | } 48 | static void jbwm_handle_MapRequest(XEvent * ev, struct JBWMClient * c, 49 | struct JBWMScreen * s, struct JBWMClient ** head_client, 50 | struct JBWMClient ** current_client) { 51 | if (!c) { 52 | XMapRequestEvent * e = &ev->xmaprequest; 53 | /* This check fixes a race condition in old libreoffice and 54 | * certain Motif dialogs where an attempt is made to 55 | * request mapping twice: */ 56 | static unsigned long serial; 57 | if (e->serial != serial){ 58 | serial = e->serial; 59 | JBWM_LOG("jbwm_handle_MapRequest(), send_event:%d", 60 | e->send_event); 61 | jbwm_new_client(get_screen(s, e->parent, 0), head_client, 62 | current_client, e->window); 63 | } 64 | } 65 | } 66 | static void jbwm_handle_ColormapNotify(XEvent * ev, struct JBWMClient * c) 67 | { 68 | XColormapEvent * e = &ev->xcolormap; 69 | if (c && e->new) 70 | XInstallColormap(e->display, c->cmap = e->colormap); 71 | } 72 | static void jbwm_handle_ConfigureNotify(XEvent * ev, struct JBWMClient * c) 73 | { 74 | (void)ev; 75 | if (c && !ev->xconfigure.override_redirect) 76 | jbwm_move_resize(c); 77 | } 78 | static void jbwm_handle_ConfigureRequest(XEvent * ev, struct JBWMClient * c) 79 | { 80 | XConfigureRequestEvent * e = &ev->xconfigurerequest; 81 | JBWM_LOG("handle_configure_request():" 82 | "x: %d, y: %d, w: %d, h: %d, b: %d", 83 | e->x, e->y, e->width, e->height, e->border_width); 84 | XConfigureWindow(e->display, e->window, e->value_mask, 85 | &(XWindowChanges){ .x = e->x, .y = e->y, 86 | .width = e->width, .height = e->height, 87 | .border_width = e->border_width, 88 | .sibling = e->above, .stack_mode = e->detail}); 89 | XSync(e->display, false); 90 | if (c) 91 | jbwm_move_resize(c); 92 | } 93 | static void jbwm_handle_EnterNotify(XEvent * ev, struct JBWMClient * c, 94 | struct JBWMClient ** current_client) 95 | { 96 | if (c && ev->xcrossing.window == c->parent) 97 | jbwm_select_client(c, current_client); 98 | } 99 | static void jbwm_handle_Expose(XEvent * ev, struct JBWMClient * c) 100 | { 101 | if (c && !ev->xexpose.count) 102 | jbwm_update_title_bar(c); 103 | } 104 | void jbwm_events_loop(struct JBWMScreen * s, struct JBWMClient ** head_client, 105 | struct JBWMClient ** current_client) 106 | { 107 | Display *d; 108 | d=s->xlib->display; 109 | for (;;) { 110 | XEvent ev; 111 | XNextEvent(d, &ev); 112 | struct JBWMClient * c = jbwm_find_client(*head_client, ev.xany.window); 113 | if (c) 114 | s = c->screen; 115 | switch (ev.type) { 116 | case ConfigureNotify: 117 | jbwm_handle_ConfigureNotify(&ev,c); 118 | break; 119 | case ConfigureRequest: 120 | jbwm_handle_ConfigureRequest(&ev,c); 121 | break; 122 | case KeyPress: 123 | JBWM_LOG("c: %d, window: %d, root: %d", (int)c, 124 | (int)ev.xkey.window, (int)ev.xkey.root); 125 | if (!c) 126 | c = *current_client; 127 | jbwm_handle_key_event(s, c, head_client, current_client, &ev.xkey); 128 | break; 129 | case ButtonPress: 130 | jbwm_handle_button_event(&ev.xbutton, c, head_client, 131 | current_client); 132 | break; 133 | case EnterNotify: 134 | jbwm_handle_EnterNotify(&ev, c, current_client); 135 | break; 136 | case Expose: 137 | jbwm_handle_Expose(&ev,c); 138 | break; 139 | case CreateNotify: 140 | case DestroyNotify: 141 | jbwm_ewmh_update_client_list(*head_client); 142 | break; 143 | case UnmapNotify: 144 | if (c && (c->opt.remove || (c->ignore_unmap--<1))) 145 | jbwm_client_free(c, head_client, current_client); 146 | break; 147 | case MapRequest: 148 | jbwm_handle_MapRequest(&ev, c, s, head_client, current_client); 149 | break; 150 | case PropertyNotify: 151 | jbwm_handle_PropertyNotify(&ev,c); 152 | break; 153 | case ColormapNotify: 154 | jbwm_handle_ColormapNotify(&ev,c); 155 | break; 156 | case ClientMessage: 157 | jbwm_ewmh_handle_client_message(&ev.xclient, c, head_client, 158 | current_client); 159 | break; 160 | // ignore 161 | case ButtonRelease: 162 | case KeyRelease: 163 | case MapNotify: 164 | case MappingNotify: 165 | case MotionNotify: 166 | case ReparentNotify: 167 | default: 168 | break; 169 | } 170 | } 171 | } 172 | 173 | -------------------------------------------------------------------------------- /events.h: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #ifndef JBWM_EVENTS_H 6 | #define JBWM_EVENTS_H 7 | struct JBWMClient; 8 | struct JBWMScreen; 9 | void jbwm_events_loop(struct JBWMScreen * s, struct JBWMClient ** head_client, 10 | struct JBWMClient ** current_client) __attribute__((noreturn)); 11 | #endif /* ! JBWM_EVENTS_H */ 12 | -------------------------------------------------------------------------------- /ewmh.c: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020,Alisa Bedard 3 | // Copyright 1999-2015,Ciaran Anscomb 4 | // See README for license and other details. 5 | //#undef DEBUG 6 | #include "ewmh.h" 7 | #include "atom.h" 8 | #include "config.h" 9 | #include "JBWMClient.h" 10 | #include "log.h" 11 | #include "macros.h" 12 | #include 13 | #include 14 | #include 15 | #include 16 | void jbwm_ewmh_set_allowed_actions(Display * d, 17 | Window const w) 18 | { 19 | Atom a[]={ 20 | jbwm_atoms[JBWM_NET_WM_ACTION_MOVE], 21 | jbwm_atoms[JBWM_NET_WM_ACTION_RESIZE], 22 | jbwm_atoms[JBWM_NET_WM_ACTION_CLOSE], 23 | jbwm_atoms[JBWM_NET_WM_ACTION_SHADE], 24 | jbwm_atoms[JBWM_NET_WM_ACTION_FULLSCREEN], 25 | jbwm_atoms[JBWM_NET_WM_ACTION_CHANGE_DESKTOP], 26 | jbwm_atoms[JBWM_NET_WM_ACTION_ABOVE], 27 | jbwm_atoms[JBWM_NET_WM_ACTION_BELOW], 28 | jbwm_atoms[JBWM_NET_WM_ACTION_MAXIMIZE_HORZ], 29 | jbwm_atoms[JBWM_NET_WM_ACTION_MAXIMIZE_VERT], 30 | }; 31 | XChangeProperty(d,w,a[0],XA_ATOM, 32, PropModeReplace, 32 | (unsigned char *)&a,sizeof(a) / sizeof(Atom)); 33 | } 34 | static void init_desktops(Display * d,struct JBWMScreen * s) 35 | { 36 | int32_t data[2]; 37 | Window root=s->xlib->root; 38 | data[0]=s->xlib->width; 39 | data[1]=s->xlib->height; 40 | XChangeProperty(d, root, jbwm_atoms[JBWM_NET_DESKTOP_GEOMETRY], 41 | XA_CARDINAL, 32, PropModeReplace, (unsigned char*)data, 2); 42 | data[0]=data[1]=0; 43 | XChangeProperty(d, root, jbwm_atoms[JBWM_NET_DESKTOP_VIEWPORT], 44 | XA_CARDINAL, 32, PropModeReplace, (unsigned char*)data, 2); 45 | data[0]=JBWM_NUMBER_OF_DESKTOPS; 46 | XChangeProperty(d, root, jbwm_atoms[JBWM_NET_NUMBER_OF_DESKTOPS], 47 | XA_CARDINAL, 32, PropModeReplace, (unsigned char*)data, 1); 48 | XChangeProperty(d, root, jbwm_atoms[JBWM_NET_CURRENT_DESKTOP], 49 | XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&s->vdesk, 1); 50 | XChangeProperty(d, root, jbwm_atoms[JBWM_NET_VIRTUAL_ROOTS], 51 | XA_WINDOW, 32, PropModeReplace, (unsigned char*)&root, 1); 52 | } 53 | static Window init_supporting(Display * d,Window const r) 54 | { 55 | Window w; 56 | w=XCreateSimpleWindow(d,r,0,0,1,1,0,0,0); 57 | XChangeProperty(d, r, jbwm_atoms[JBWM_NET_SUPPORTING_WM_CHECK], 58 | XA_WINDOW, 32, PropModeReplace, (unsigned char *)&w, 1); 59 | XChangeProperty(d, w, jbwm_atoms[JBWM_NET_SUPPORTING_WM_CHECK], 60 | XA_WINDOW, 32, PropModeReplace, (unsigned char *)&w, 1); 61 | XChangeProperty(d, w, jbwm_atoms[JBWM_NET_WM_PID], XA_CARDINAL, 62 | 32, PropModeReplace, (unsigned char *)&(pid_t){getpid()},1); 63 | XChangeProperty(d, w, jbwm_atoms[JBWM_NET_WM_NAME], XA_STRING, 64 | 8, PropModeReplace, (unsigned char *)JBWM_NAME, sizeof(JBWM_NAME)); 65 | return w; 66 | } 67 | void jbwm_ewmh_init_screen(Display * d, struct JBWMScreen * s) 68 | { 69 | Window *r; 70 | /* Use a pointer to the original screen data to prevent 71 | * the pointers passed as property data from being invalid 72 | * once this function looses scope. */ 73 | r=&s->xlib->root; 74 | /* Set this to the root window until we have some clients. 75 | Point to original screen data. */ 76 | XChangeProperty(d, *r, jbwm_atoms[JBWM_NET_CLIENT_LIST], XA_WINDOW, 77 | 32, PropModeReplace, (unsigned char *)r, 1); 78 | XChangeProperty(d,*r,jbwm_atoms[JBWM_NET_SUPPORTED], 79 | XA_ATOM, 32, PropModeReplace, (unsigned char *)&jbwm_atoms, 80 | JBWM_ATOM_COUNT); 81 | XChangeProperty(d,*r,jbwm_atoms[JBWM_NET_WM_NAME],XA_STRING, 82 | 8, PropModeReplace, (unsigned char *)JBWM_NAME, sizeof(JBWM_NAME)); 83 | init_desktops(d,s); 84 | s->supporting=init_supporting(d,*r); 85 | } 86 | // Required by wm-spec: 87 | void jbwm_set_frame_extents(struct JBWMClient * c) 88 | { 89 | static uint32_t f[4]; 90 | Atom a; 91 | JBWM_LOG("jbwm_set_frame_extents()"); 92 | // Fields: left,right,top,bottom 93 | f[0]=f[1]=f[2]=f[3]=c->opt.border; 94 | if (!c->opt.no_title_bar) 95 | f[2] += c->screen->font_height; 96 | a=jbwm_atoms[JBWM_NET_FRAME_EXTENTS]; 97 | XChangeProperty(c->screen->xlib->display, c->parent, a, XA_CARDINAL, 32, 98 | PropModeReplace, (unsigned char *)f, 4); 99 | } 100 | -------------------------------------------------------------------------------- /ewmh.h: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #ifndef JBWM_EWMH_H 6 | #define JBWM_EWMH_H 7 | #include 8 | #include 9 | struct JBWMClient; 10 | struct JBWMScreen; 11 | void jbwm_ewmh_set_allowed_actions(Display * d, 12 | const Window w) __attribute__((nonnull)); 13 | void jbwm_ewmh_init_screen(Display * d, struct JBWMScreen * s) 14 | __attribute__((nonnull)); 15 | void jbwm_set_frame_extents(struct JBWMClient * c); 16 | #endif//!JBWM_EWMH_H 17 | -------------------------------------------------------------------------------- /ewmh_client.c: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #include "ewmh_client.h" 3 | #include "client.h" 4 | #include "config.h" 5 | #include "drag.h" 6 | #include "ewmh.h" 7 | #include "ewmh_wm_state.h" 8 | #include "atom.h" 9 | #include "select.h" 10 | #include "util.h" 11 | #include "vdesk.h" 12 | #include "wm_state.h" 13 | static void handle_moveresize(XClientMessageEvent * e) 14 | { 15 | /* per wm-spec: fields come from e->data.l 16 | l[0]: gravity and flags, l[1]: x, l[2]: y, l[3]: w, l[4]: h 17 | l[0]: bits 0-7 idicate gravity, 18 | l[0]: bits 8-11 use x, y, width, height, respectively 19 | l[0]: bits 12-15 indicate the source, 20 | */ 21 | enum { 22 | SRC_SHIFT = 12, SRC_MASK = 3, VM_SHIFT = 8, VM_MASK = 0xf, 23 | USER_ACTION = 2 24 | }; 25 | const long * l = e->data.l; 26 | const uint8_t src = (l[0] >> SRC_SHIFT) & SRC_MASK; 27 | if (src != USER_ACTION) 28 | return; 29 | const uint32_t vm = (l[0] >> VM_SHIFT) & VM_MASK; 30 | XConfigureWindow(e->display, e->window, vm, &(XWindowChanges){ 31 | .x = l[1], .y = l[2], .width = l[3], .height = l[4]}); 32 | // use bit width truncation to mask for gravity: 33 | const uint8_t win_gravity = l[0]; 34 | XChangeWindowAttributes(e->display, e->window, CWWinGravity, 35 | &(XSetWindowAttributes){.win_gravity = win_gravity}); 36 | } 37 | // returns true if handled, false if not 38 | static bool client_specific_message(XClientMessageEvent * e, 39 | struct JBWMClient * c, struct JBWMClient ** head_client, 40 | struct JBWMClient ** current_client, const Atom t) 41 | { 42 | Display * d; 43 | d = e->display; 44 | jbwm_print_atom(d, t, __FILE__, __LINE__); 45 | if (t == jbwm_atoms[JBWM_NET_WM_DESKTOP]) 46 | jbwm_set_client_vdesk(c, e->data.l[0]); 47 | // If user moves window (client-side title bars): 48 | else if (t == jbwm_atoms[JBWM_NET_WM_MOVERESIZE]) { 49 | XRaiseWindow(d, c->parent); 50 | jbwm_drag(c, head_client, false); 51 | } else if (t == jbwm_atoms[JBWM_NET_WM_STATE]) 52 | jbwm_ewmh_handle_wm_state_changes(e, c); 53 | else if (t == jbwm_atoms[JBWM_NET_ACTIVE_WINDOW]) 54 | jbwm_select_client(c, current_client); 55 | else if (t == jbwm_atoms[JBWM_NET_CLOSE_WINDOW]) 56 | jbwm_send_wm_delete(c); 57 | else 58 | return false; 59 | return true; 60 | } 61 | #if defined(JBWM_DEBUG_EWMH_STATE) && defined(DEBUG) 62 | static void debug_client_message(XClientMessageEvent * e) 63 | { 64 | Display * d = e->display; 65 | const long * l = e->data.l; 66 | JBWM_LOG("jbwm_ewmh_client_message()"); 67 | jbwm_print_atom(d, e->message_type, __FILE__, __LINE__); 68 | JBWM_LOG("\t\tl[0: %ld, 1: %ld, 2: %ld, 3: %ld, 4: %ld]", 69 | l[0], l[1], l[2], l[3], l[4]); 70 | } 71 | #else//!JBWM_DEBUG_EWMH_STATE||!DEBUG 72 | #define debug_client_message(e) 73 | #endif//JBWM_DEBUG_EWMH_STATE&&DEBUG 74 | void jbwm_ewmh_handle_client_message(XClientMessageEvent * e, 75 | struct JBWMClient * c, struct JBWMClient ** head_client, 76 | struct JBWMClient ** current_client) 77 | { 78 | const Atom t = e->message_type; 79 | debug_client_message(e); 80 | if(!(c && client_specific_message(e, c, head_client, current_client, t))){ 81 | if (t == jbwm_atoms[JBWM_NET_CURRENT_DESKTOP]) { 82 | jbwm_set_vdesk(c->screen, *head_client, e->data.l[0]); 83 | } else if (t == jbwm_atoms[JBWM_NET_MOVERESIZE_WINDOW]) { 84 | // If something else moves the window: 85 | handle_moveresize(e); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /ewmh_client.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #ifndef JBWM_EWMH_CLIENT_H 3 | #define JBWM_EWMH_CLIENT_H 4 | #include 5 | struct JBWMClient; 6 | void jbwm_ewmh_handle_client_message(XClientMessageEvent * e, 7 | struct JBWMClient * c, struct JBWMClient ** head_client, 8 | struct JBWMClient ** current_client); 9 | #endif//!JBWM_EWMH_CLIENT_H 10 | -------------------------------------------------------------------------------- /ewmh_client_list.c: -------------------------------------------------------------------------------- 1 | #include "ewmh_client_list.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "JBWMClient.h" 7 | #include "atom.h" 8 | #include "config.h" 9 | #include "log.h" 10 | #include "macros.h" 11 | // returns number of elements in window list 12 | static int get_client_list_r(Window ** list,Display * d, 13 | struct JBWMClient * i,int const count) { 14 | int rval; 15 | if (i) { 16 | int const new_count =count + 1; 17 | *list=realloc(*list,new_count * sizeof(Window)); 18 | (*list)[count]= i->window; 19 | rval=get_client_list_r(list,d,i->next,new_count); 20 | } else 21 | rval=count; 22 | return rval; 23 | } 24 | #ifdef JBWM_EWMH_DEBUG_WINDOW_LIST 25 | static void debug_window_list(int n,Window * window_list) 26 | { 27 | if (n > 0) { 28 | JBWM_LOG("window_list[%d] is 0x%x", 29 | n,(int)window_list[n]); 30 | debug_window_list(n - 1,window_list); 31 | } 32 | } 33 | #else//!JBWM_EWMH_DEBUG_WINDOW_LIST 34 | #define debug_window_list(n,w) 35 | #endif//DEBUG 36 | static Window * get_mixed_client_list(struct JBWMClient *head) 37 | { 38 | static Window * window_list; 39 | Display *d; 40 | Atom a; 41 | int n; 42 | if (window_list) { 43 | free(window_list); 44 | window_list=NULL; 45 | } 46 | d=head->screen->xlib->display; 47 | n=get_client_list_r(&window_list,d,head,0); 48 | a=jbwm_atoms[JBWM_NET_CLIENT_LIST]; 49 | XChangeProperty(d, head->screen->xlib->root, a, XA_WINDOW, 32, 50 | PropModeReplace, (unsigned char *)window_list, n); 51 | debug_window_list(n,window_list); 52 | return window_list; 53 | } 54 | static inline bool query_tree(Display * d,Window ** children_return, 55 | unsigned int * nchildren_return) 56 | { 57 | Window parent,root; 58 | bool r; 59 | if(d&&children_return&&nchildren_return) 60 | r=XQueryTree(d,DefaultRootWindow(d),&parent,&root,children_return, 61 | nchildren_return); 62 | else 63 | r=false; 64 | return r; 65 | } 66 | static unsigned int get_window_list(Display * d,uint8_t const max_clients, 67 | Window * window_list) 68 | { 69 | Window * wl; 70 | unsigned int n; 71 | if (query_tree(d,&wl,&n)) { 72 | n=JB_MIN(n,max_clients); // limit to MAX_CLIENTS 73 | memcpy(window_list,wl,n * sizeof(Window)); 74 | debug_window_list(n,wl); 75 | XFree(wl); 76 | } 77 | return n; 78 | } 79 | static Window * get_ordered_client_list(Display * d, Window const root) 80 | { 81 | enum {MAX_CLIENTS=64}; 82 | static Window window_list[MAX_CLIENTS]; 83 | Atom a; 84 | // get ordered list of all windows on default screen: 85 | unsigned int const n=get_window_list(d,MAX_CLIENTS,window_list); 86 | JBWM_LOG("get_ordered_client_list() n: %d",(int)n); 87 | a=jbwm_atoms[JBWM_NET_CLIENT_LIST_STACKING]; 88 | XChangeProperty(d, root,a,XA_WINDOW, 32, PropModeReplace, 89 | (unsigned char *)window_list,n); 90 | return window_list; 91 | } 92 | void jbwm_ewmh_update_client_list(struct JBWMClient *head) 93 | { 94 | if(head){ // there may be no clients 95 | get_mixed_client_list(head); 96 | get_ordered_client_list(head->screen->xlib->display, 97 | head->screen->xlib->root); 98 | } 99 | } 100 | 101 | 102 | -------------------------------------------------------------------------------- /ewmh_client_list.h: -------------------------------------------------------------------------------- 1 | #ifndef JBWM_EWMH_CLIENT_LIST_H 2 | #define JBWM_EWMH_CLIENT_LIST_H 3 | struct JBWMClient; 4 | void jbwm_ewmh_update_client_list(struct JBWMClient *head); 5 | #endif // !JBWM_EWMH_CLIENT_LIST_H 6 | -------------------------------------------------------------------------------- /ewmh_state.c: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #undef DEBUG 3 | #include "ewmh_state.h" 4 | #include "client.h" 5 | #include "drag.h" 6 | #include "ewmh.h" 7 | #include "jbwm.h" 8 | #include "atom.h" 9 | #include "log.h" 10 | #include "max.h" 11 | #include "select.h" 12 | #include "util.h" 13 | #include "wm_state.h" 14 | #include 15 | // Remove specified atom from WM_STATE 16 | void jbwm_ewmh_remove_state(Display * display, 17 | const Window window, const Atom state) 18 | { 19 | uint16_t n; 20 | const Atom wm_state = jbwm_atoms[JBWM_NET_WM_STATE]; 21 | Atom *a = jbwm_get_property(display, window, wm_state, &n); 22 | if(a){ // found property 23 | uint16_t i; 24 | for(i=0;i 5 | #include 6 | struct JBWMClient; 7 | void jbwm_ewmh_add_state(Display * d, const Window w, Atom state); 8 | bool jbwm_ewmh_get_state(Display * d, const Window w, const Atom state); 9 | void jbwm_ewmh_remove_state(Display * d, const Window w, const Window state); 10 | #endif//JBWM_EWMH_STATE_H 11 | -------------------------------------------------------------------------------- /ewmh_wm_state.c: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #include "ewmh_wm_state.h" 3 | #include "atom.h" 4 | #include "JBWMClient.h" 5 | #include "client.h" 6 | #include "ewmh.h" 7 | #include "ewmh_state.h" 8 | #include "log.h" 9 | #include "max.h" 10 | #include "util.h" 11 | /* Reference, per wm-spec: 12 | window = the respective client window 13 | message_type = _NET_WM_STATE 14 | format = 32 15 | data.l[0] = the action, as listed below 16 | _NET_WM_STATE_REMOVE 0 remove/unset property 17 | _NET_WM_STATE_ADD 1 add/set property 18 | _NET_WM_STATE_TOGGLE 2 toggle property 19 | data.l[1] = first property to alter 20 | data.l[2] = second property to alter 21 | data.l[3] = source indication 22 | other data.l[] elements = 0 */ 23 | static void set_state(struct JBWMClient * c, 24 | bool add, Atom const atom){ 25 | if (c){ 26 | if(atom==jbwm_atoms[JBWM_NET_WM_STATE_FULLSCREEN]) 27 | (add?jbwm_set_fullscreen:jbwm_set_not_fullscreen)(c); 28 | else if(atom==jbwm_atoms[JBWM_NET_WM_STATE_STICKY]) 29 | c->opt.sticky=add; 30 | else if(atom==jbwm_atoms[JBWM_NET_WM_STATE_ABOVE]) 31 | add = !add; // fall through 32 | else if(atom==jbwm_atoms[JBWM_NET_WM_STATE_BELOW]) 33 | (add ? XRaiseWindow : XLowerWindow)(c->screen->xlib->display, c->parent); 34 | else if(atom==jbwm_atoms[JBWM_NET_WM_STATE_HIDDEN]) 35 | (add ? jbwm_hide_client : jbwm_restore_client)(c); 36 | else if(atom==jbwm_atoms[JBWM_NET_WM_STATE_MAXIMIZED_VERT]) 37 | (add ? jbwm_set_vert : jbwm_set_not_vert)(c); 38 | else if(atom==jbwm_atoms[JBWM_NET_WM_STATE_MAXIMIZED_HORZ]) 39 | (add ? jbwm_set_horz : jbwm_set_not_horz)(c); 40 | else{ 41 | JBWM_LOG("\tWARNING: Unhandled state"); 42 | } 43 | } 44 | } 45 | __attribute__((nonnull)) 46 | static void check_state(XClientMessageEvent * e, // event data 47 | Atom const atom, // state to test 48 | struct JBWMClient * c){ 49 | // 2 atoms can be set at once 50 | long * l = &e->data.l[0]; 51 | const bool set = l[1] == (long)atom || l[2] == (long)atom; 52 | if(!set) 53 | return; 54 | Display * d = e->display; 55 | switch (e->data.l[0]) { 56 | default: 57 | case 0: // remove 58 | set_state(c, false, atom); 59 | jbwm_ewmh_remove_state(d, e->window, atom); 60 | break; 61 | case 1: // add 62 | set_state(c,true,atom); 63 | jbwm_ewmh_add_state(d, e->window, atom); 64 | break; 65 | case 2: { // toggle 66 | const bool add = !jbwm_ewmh_get_state(e->display, 67 | e->window, atom); 68 | set_state(c,add,atom); 69 | (add ? jbwm_ewmh_add_state : jbwm_ewmh_remove_state) 70 | (d, e->window, atom); 71 | } 72 | } 73 | } 74 | void jbwm_ewmh_handle_wm_state_changes(XClientMessageEvent * e, 75 | struct JBWMClient * c){ 76 | check_state(e, jbwm_atoms[JBWM_NET_WM_STATE_ABOVE], c); 77 | check_state(e, jbwm_atoms[JBWM_NET_WM_STATE_BELOW], c); 78 | check_state(e, jbwm_atoms[JBWM_NET_WM_STATE_FULLSCREEN], c); 79 | check_state(e, jbwm_atoms[JBWM_NET_WM_STATE_MAXIMIZED_HORZ], c); 80 | check_state(e, jbwm_atoms[JBWM_NET_WM_STATE_MAXIMIZED_VERT], c); 81 | check_state(e, jbwm_atoms[JBWM_NET_WM_STATE_STICKY], c); 82 | } 83 | -------------------------------------------------------------------------------- /ewmh_wm_state.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #ifndef JBWM_EWMH_WM_STATE_H 3 | #define JBWM_EWMH_WM_STATE_H 4 | #include 5 | struct JBWMClient; 6 | void jbwm_ewmh_handle_wm_state_changes(XClientMessageEvent * e, 7 | struct JBWMClient * c); 8 | #endif//!JBWM_EWMH_WM_STATE_H 9 | -------------------------------------------------------------------------------- /exec.c: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #include "exec.h" 3 | #include "config.h" 4 | #include // for signal() 5 | #include 6 | #include // for fork(), execl() 7 | void jbwm_exec(const char * command) 8 | { 9 | if (fork() == 0) { // child 10 | execl("/bin/sh", "sh", "-c", command, NULL); 11 | // This is only reached on error. 12 | exit(1); 13 | } else // in controlling process: 14 | signal(SIGCHLD, SIG_IGN); 15 | } 16 | -------------------------------------------------------------------------------- /exec.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #ifndef JBWM_EXEC_H 3 | #define JBWM_EXEC_H 4 | // Execute command as forked process. 5 | void jbwm_exec(const char * command); 6 | #endif//!JBWM_EXEC_H 7 | -------------------------------------------------------------------------------- /font.c: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #include "font.h" 3 | #ifdef JBWM_USE_XFT 4 | #include 5 | #endif//JBWM_USE_XFT 6 | #include "config.h" 7 | #include 8 | #include "util.h" 9 | static struct JBWMFont { 10 | #ifdef JBWM_USE_XFT 11 | XftFont * font; 12 | #else//!JBWM_USE_XFT 13 | XFontStruct * font; 14 | #endif//JBWM_USE_XFT 15 | short ascent,descent,height; 16 | } jbwm_font; 17 | void jbwm_open_font(Display * d) 18 | { 19 | static bool already_created; 20 | if(!already_created){ 21 | #ifdef JBWM_USE_XFT 22 | jbwm_font.font = XftFontOpenName(d, DefaultScreen(d), JBWM_FONT); 23 | #else//!JBWM_USE_XFT 24 | jbwm_font.font = XLoadQueryFont(d, JBWM_FONT); 25 | #endif//JBWM_USE_XFT 26 | if (!jbwm_font.font) 27 | jbwm_error(JBWM_FONT); 28 | #ifdef JBWM_USE_XFT 29 | jbwm_font.ascent=jbwm_font.font->ascent; 30 | jbwm_font.descent=jbwm_font.font->descent; 31 | #else//!JBWM_USE_XFT 32 | jbwm_font.ascent=jbwm_font.font->max_bounds.ascent; 33 | jbwm_font.descent=jbwm_font.font->max_bounds.descent; 34 | #endif//JBWM_USE_XFT 35 | jbwm_font.height=jbwm_font.ascent+jbwm_font.descent; 36 | already_created=true; 37 | } 38 | } 39 | void * jbwm_get_font(void) 40 | { 41 | return jbwm_font.font; 42 | } 43 | uint8_t jbwm_get_font_ascent(void) 44 | { 45 | return jbwm_font.ascent; 46 | } 47 | uint8_t jbwm_get_font_height(void) 48 | { 49 | return jbwm_font.height; 50 | } 51 | -------------------------------------------------------------------------------- /font.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #ifndef JBWM_FONT_H 3 | #define JBWM_FONT_H 4 | #include 5 | #include 6 | void * jbwm_get_font(void); 7 | uint8_t jbwm_get_font_ascent(void); 8 | uint8_t jbwm_get_font_height(void); 9 | void jbwm_open_font(Display * d); 10 | #endif//JBWM_FONT_H 11 | -------------------------------------------------------------------------------- /geometry.c: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #include "geometry.h" 3 | #include "JBWMClient.h" 4 | #include "JBWMScreen.h" 5 | #include "JBWMSize.h" 6 | #include "log.h" 7 | #include "macros.h" 8 | #include 9 | struct GeometryData { 10 | Display * display; 11 | union JBWMRectangle * attribute; 12 | union JBWMRectangle * geometry; 13 | Window window; 14 | }; 15 | static long handle_wm_normal_hints(struct GeometryData * g) 16 | { 17 | /* Though these statements may be combined, writing the following 18 | * assignment this way ensures the conditional is only evaluated once. 19 | * */ 20 | XSizeHints h; 21 | if (XGetWMNormalHints(g->display, g->window, &h, &(long){0}) 22 | && (h.flags & USSize)) { 23 | // if size hints provided, use them 24 | g->geometry->width = JB_MAX(h.width, h.min_width); 25 | g->geometry->height = JB_MAX(h.height, h.min_height); 26 | } else // use existing window attributes 27 | *g->geometry = *g->attribute; 28 | return h.flags; 29 | } 30 | static void check_dimensions(union JBWMRectangle * g, 31 | const struct JBWMSize screen) 32 | { 33 | g->width = JB_MIN(g->width, screen.width); 34 | g->height = JB_MIN(g->height, screen.height); 35 | } 36 | __attribute__((const)) 37 | static int16_t get_center(const int16_t window_size, 38 | const int16_t screen_size) 39 | { 40 | return (screen_size - window_size) >> 1; 41 | } 42 | static void center(union JBWMRectangle * g, 43 | const struct JBWMSize s) 44 | { 45 | g->x = get_center(g->width, s.width); 46 | g->y = get_center(g->height, s.height); 47 | } 48 | // returns true if window is viewable 49 | static bool get_window_attributes(struct JBWMClient * c, 50 | union JBWMRectangle * geometry_attribute) 51 | { 52 | XWindowAttributes a; 53 | Display * d = c->screen->xlib->display; 54 | XGetWindowAttributes(d, c->window, &a); 55 | JBWM_LOG("XGetWindowAttributes() win: 0x%x," 56 | "x: %d, y: %d, w: %d, h: %d", 57 | (int)c->window, a.x, a.y, a.width, a.height); 58 | c->cmap = a.colormap; 59 | *geometry_attribute = (union JBWMRectangle){.x = a.x, .y = a.y, 60 | .width = a.width, .height = a.height}; 61 | return a.map_state == IsViewable; 62 | } 63 | static void init_geometry_for_screen(struct JBWMClient * c, 64 | union JBWMRectangle * geometry_attribute) 65 | { 66 | struct JBWMScreen *s=c->screen; 67 | Display * d = c->screen->xlib->display; 68 | struct JBWMSize screen_size={s->xlib->width,s->xlib->height}; 69 | struct GeometryData g={ .display=d, .attribute = geometry_attribute, 70 | .geometry = &c->size, .window = c->window}; 71 | check_dimensions(g.geometry, screen_size); 72 | { 73 | const long flags = handle_wm_normal_hints(&g); 74 | const bool user_specified_position = flags & USPosition; 75 | const bool nonzero_position = g.attribute->x || 76 | g.attribute->y; 77 | if (user_specified_position && nonzero_position) { 78 | JBWM_LOG("\t\tPosition is set by hints."); 79 | g.geometry->x = g.attribute->x; 80 | g.geometry->y = g.attribute->y; 81 | } else // Position not specified 82 | center(g.geometry, screen_size); 83 | } 84 | } 85 | void jbwm_set_client_geometry(struct JBWMClient * c) 86 | { 87 | union JBWMRectangle geometry_attribute; 88 | if (get_window_attributes(c, &geometry_attribute)) { // viewable 89 | /* Increment unmap event counter for the reparent event. */ 90 | ++c->ignore_unmap; 91 | /* If the window is already on screen before the window 92 | manager starts, simply save its geometry then return. */ 93 | c->size = geometry_attribute; 94 | } else // not viewable yet 95 | init_geometry_for_screen(c, &geometry_attribute); 96 | } 97 | -------------------------------------------------------------------------------- /geometry.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #ifndef JBWM_GEOMETRY_H 3 | #define JBWM_GEOMETRY_H 4 | #include 5 | #include 6 | #include "JBWMSize.h" 7 | struct JBWMClient; 8 | //struct JBWMSize jbwm_get_display_size(Display * d, 9 | // const uint8_t screen) __attribute__((pure)); 10 | void jbwm_set_client_geometry(struct JBWMClient * c); 11 | #endif//!JBWM_GEOMETRY_H 12 | -------------------------------------------------------------------------------- /gprof.out: -------------------------------------------------------------------------------- 1 | Flat profile: 2 | 3 | Each sample counts as 0.01 seconds. 4 | no time accumulated 5 | 6 | % cumulative self self total 7 | time seconds seconds calls Ts/call Ts/call name 8 | 0.00 0.00 0.00 2932 0.00 0.00 absmin 9 | 0.00 0.00 0.00 2184 0.00 0.00 sborder 10 | 0.00 0.00 0.00 1092 0.00 0.00 sborderdir 11 | 0.00 0.00 0.00 1044 0.00 0.00 jbwm_find_client 12 | 0.00 0.00 0.00 962 0.00 0.00 draw_outline 13 | 0.00 0.00 0.00 922 0.00 0.00 snap_dir 14 | 0.00 0.00 0.00 920 0.00 0.00 adjust_for_titlebar 15 | 0.00 0.00 0.00 918 0.00 0.00 snap_cond 16 | 0.00 0.00 0.00 783 0.00 0.00 mv 17 | 0.00 0.00 0.00 733 0.00 0.00 jbwm_snap_dim 18 | 0.00 0.00 0.00 553 0.00 0.00 jbwm_get_property 19 | 0.00 0.00 0.00 546 0.00 0.00 jbwm_snap_border 20 | 0.00 0.00 0.00 461 0.00 0.00 jbwm_snap_client 21 | 0.00 0.00 0.00 461 0.00 0.00 snap_search 22 | 0.00 0.00 0.00 334 0.00 0.00 jbwm_handle_PropertyNotify 23 | 0.00 0.00 0.00 263 0.00 0.00 get_atom 24 | 0.00 0.00 0.00 261 0.00 0.00 draw_text 25 | 0.00 0.00 0.00 261 0.00 0.00 draw_title 26 | 0.00 0.00 0.00 261 0.00 0.00 jbwm_get_font_ascent 27 | 0.00 0.00 0.00 261 0.00 0.00 jbwm_get_title 28 | 0.00 0.00 0.00 261 0.00 0.00 jbwm_update_title_bar 29 | 0.00 0.00 0.00 261 0.00 0.00 move_buttons 30 | 0.00 0.00 0.00 261 0.00 0.00 resize_title_bar 31 | 0.00 0.00 0.00 259 0.00 0.00 jbwm_get_wm_state 32 | 0.00 0.00 0.00 200 0.00 0.00 jbwm_handle_mwm_hints 33 | 0.00 0.00 0.00 196 0.00 0.00 do_move 34 | 0.00 0.00 0.00 196 0.00 0.00 jbwm_configure_client 35 | 0.00 0.00 0.00 196 0.00 0.00 jbwm_move_resize 36 | 0.00 0.00 0.00 196 0.00 0.00 jbwm_set_shape 37 | 0.00 0.00 0.00 184 0.00 0.00 jbwm_handle_EnterNotify 38 | 0.00 0.00 0.00 168 0.00 0.00 jbwm_handle_ConfigureNotify 39 | 0.00 0.00 0.00 108 0.00 0.00 jbwm_get_mod_mask 40 | 0.00 0.00 0.00 107 0.00 0.00 jbwm_handle_key_event 41 | 0.00 0.00 0.00 94 0.00 0.00 handle_client_key_event 42 | 0.00 0.00 0.00 94 0.00 0.00 jbwm_ewmh_add_state 43 | 0.00 0.00 0.00 87 0.00 0.00 jbwm_ewmh_remove_state 44 | 0.00 0.00 0.00 86 0.00 0.00 jbwm_warp 45 | 0.00 0.00 0.00 85 0.00 0.00 commit_key_move 46 | 0.00 0.00 0.00 85 0.00 0.00 get_antecedent 47 | 0.00 0.00 0.00 85 0.00 0.00 get_move_flags 48 | 0.00 0.00 0.00 85 0.00 0.00 handle_key_move 49 | 0.00 0.00 0.00 85 0.00 0.00 key_move 50 | 0.00 0.00 0.00 85 0.00 0.00 point 51 | 0.00 0.00 0.00 66 0.00 0.00 jbwm_select_client 52 | 0.00 0.00 0.00 66 0.00 0.00 set_active_window_property 53 | 0.00 0.00 0.00 66 0.00 0.00 set_border 54 | 0.00 0.00 0.00 66 0.00 0.00 set_focused 55 | 0.00 0.00 0.00 65 0.00 0.00 get_bg 56 | 0.00 0.00 0.00 65 0.00 0.00 jbwm_handle_Expose 57 | 0.00 0.00 0.00 65 0.00 0.00 set_state_not_focused 58 | 0.00 0.00 0.00 38 0.00 0.00 jbwm_set_wm_state 59 | 0.00 0.00 0.00 25 0.00 0.00 can_resize 60 | 0.00 0.00 0.00 25 0.00 0.00 has_sufficient_size 61 | 0.00 0.00 0.00 22 0.00 0.00 jbwm_hide_client 62 | 0.00 0.00 0.00 20 0.00 0.00 get_win 63 | 0.00 0.00 0.00 16 0.00 0.00 jbwm_restore_client 64 | 0.00 0.00 0.00 13 0.00 0.00 get_client_list_r 65 | 0.00 0.00 0.00 13 0.00 0.00 get_mixed_client_list 66 | 0.00 0.00 0.00 13 0.00 0.00 get_ordered_client_list 67 | 0.00 0.00 0.00 13 0.00 0.00 get_window_list 68 | 0.00 0.00 0.00 13 0.00 0.00 jbwm_ewmh_update_client_list 69 | 0.00 0.00 0.00 13 0.00 0.00 query_tree 70 | 0.00 0.00 0.00 11 0.00 0.00 check_visibility 71 | 0.00 0.00 0.00 11 0.00 0.00 cond_set_vdesk 72 | 0.00 0.00 0.00 11 0.00 0.00 jbwm_set_vdesk 73 | 0.00 0.00 0.00 8 0.00 0.00 drag_event_loop 74 | 0.00 0.00 0.00 8 0.00 0.00 jbwm_drag 75 | 0.00 0.00 0.00 8 0.00 0.00 jbwm_grab_button 76 | 0.00 0.00 0.00 8 0.00 0.00 jbwm_handle_button_event 77 | 0.00 0.00 0.00 8 0.00 0.00 query_pointer 78 | 0.00 0.00 0.00 7 0.00 0.00 handle_title_bar_button 79 | 0.00 0.00 0.00 7 0.00 0.00 jbwm_get_pixel 80 | 0.00 0.00 0.00 5 0.00 0.00 jbwm_get_grab_mask 81 | 0.00 0.00 0.00 4 0.00 0.00 add_buttons 82 | 0.00 0.00 0.00 4 0.00 0.00 check_redirect 83 | 0.00 0.00 0.00 4 0.00 0.00 configure_title_bar 84 | 0.00 0.00 0.00 4 0.00 0.00 do_grabs 85 | 0.00 0.00 0.00 4 0.00 0.00 get_JBWMClient 86 | 0.00 0.00 0.00 4 0.00 0.00 get_parent 87 | 0.00 0.00 0.00 4 0.00 0.00 get_vdesk 88 | 0.00 0.00 0.00 4 0.00 0.00 get_window_attributes 89 | 0.00 0.00 0.00 4 0.00 0.00 is_shaped 90 | 0.00 0.00 0.00 4 0.00 0.00 jbwm_ewmh_set_allowed_actions 91 | 0.00 0.00 0.00 4 0.00 0.00 jbwm_new_client 92 | 0.00 0.00 0.00 4 0.00 0.00 jbwm_new_shaped_client 93 | 0.00 0.00 0.00 4 0.00 0.00 jbwm_set_client_geometry 94 | 0.00 0.00 0.00 4 0.00 0.00 jbwm_set_frame_extents 95 | 0.00 0.00 0.00 4 0.00 0.00 new_title_bar 96 | 0.00 0.00 0.00 4 0.00 0.00 reparent 97 | 0.00 0.00 0.00 4 0.00 0.00 reparent_window 98 | 0.00 0.00 0.00 4 0.00 0.00 toggle_maximize 99 | 0.00 0.00 0.00 4 0.00 0.00 wm_desktop 100 | 0.00 0.00 0.00 3 0.00 0.00 get_wm_delete_window 101 | 0.00 0.00 0.00 3 0.00 0.00 jbwm_handle_ConfigureRequest 102 | 0.00 0.00 0.00 3 0.00 0.00 jbwm_set_horz 103 | 0.00 0.00 0.00 3 0.00 0.00 jbwm_set_not_horz 104 | 0.00 0.00 0.00 3 0.00 0.00 jbwm_set_not_vert 105 | 0.00 0.00 0.00 3 0.00 0.00 jbwm_set_vert 106 | 0.00 0.00 0.00 3 0.00 0.00 set_horz 107 | 0.00 0.00 0.00 3 0.00 0.00 set_not_horz 108 | 0.00 0.00 0.00 3 0.00 0.00 set_not_vert 109 | 0.00 0.00 0.00 3 0.00 0.00 set_vert 110 | 0.00 0.00 0.00 2 0.00 0.00 grab_r 111 | 0.00 0.00 0.00 1 0.00 0.00 allocate_colors 112 | 0.00 0.00 0.00 1 0.00 0.00 check_dimensions 113 | 0.00 0.00 0.00 1 0.00 0.00 find_delete_proto 114 | 0.00 0.00 0.00 1 0.00 0.00 get_screen 115 | 0.00 0.00 0.00 1 0.00 0.00 get_windows 116 | 0.00 0.00 0.00 1 0.00 0.00 get_wm_protocols 117 | 0.00 0.00 0.00 1 0.00 0.00 handle_wm_normal_hints 118 | 0.00 0.00 0.00 1 0.00 0.00 has_delete_proto 119 | 0.00 0.00 0.00 1 0.00 0.00 init_desktops 120 | 0.00 0.00 0.00 1 0.00 0.00 init_geometry_for_screen 121 | 0.00 0.00 0.00 1 0.00 0.00 init_supporting 122 | 0.00 0.00 0.00 1 0.00 0.00 jbwm_client_free 123 | 0.00 0.00 0.00 1 0.00 0.00 jbwm_create_atoms 124 | 0.00 0.00 0.00 1 0.00 0.00 jbwm_events_loop 125 | 0.00 0.00 0.00 1 0.00 0.00 jbwm_ewmh_init_screen 126 | 0.00 0.00 0.00 1 0.00 0.00 jbwm_exec 127 | 0.00 0.00 0.00 1 0.00 0.00 jbwm_get_font 128 | 0.00 0.00 0.00 1 0.00 0.00 jbwm_get_font_height 129 | 0.00 0.00 0.00 1 0.00 0.00 jbwm_grab_root_keys 130 | 0.00 0.00 0.00 1 0.00 0.00 jbwm_handle_MapRequest 131 | 0.00 0.00 0.00 1 0.00 0.00 jbwm_init_screens 132 | 0.00 0.00 0.00 1 0.00 0.00 jbwm_open_display 133 | 0.00 0.00 0.00 1 0.00 0.00 jbwm_open_font 134 | 0.00 0.00 0.00 1 0.00 0.00 jbwm_parse_command_line 135 | 0.00 0.00 0.00 1 0.00 0.00 jbwm_relink_client_list 136 | 0.00 0.00 0.00 1 0.00 0.00 jbwm_send_wm_delete 137 | 0.00 0.00 0.00 1 0.00 0.00 jbwm_set_up_error_handler 138 | 0.00 0.00 0.00 1 0.00 0.00 setup_clients 139 | 0.00 0.00 0.00 1 0.00 0.00 setup_event_listeners 140 | 0.00 0.00 0.00 1 0.00 0.00 setup_gc 141 | 0.00 0.00 0.00 1 0.00 0.00 xmsg 142 | 143 | % the percentage of the total running time of the 144 | time program used by this function. 145 | 146 | cumulative a running sum of the number of seconds accounted 147 | seconds for by this function and those listed above it. 148 | 149 | self the number of seconds accounted for by this 150 | seconds function alone. This is the major sort for this 151 | listing. 152 | 153 | calls the number of times this function was invoked, if 154 | this function is profiled, else blank. 155 | 156 | self the average number of milliseconds spent in this 157 | ms/call function per call, if this function is profiled, 158 | else blank. 159 | 160 | total the average number of milliseconds spent in this 161 | ms/call function and its descendents per call, if this 162 | function is profiled, else blank. 163 | 164 | name the name of the function. This is the minor sort 165 | for this listing. The index shows the location of 166 | the function in the gprof listing. If the index is 167 | in parenthesis it shows where it would appear in 168 | the gprof listing if it were to be printed. 169 | 170 | Copyright (C) 2012-2017 Free Software Foundation, Inc. 171 | 172 | Copying and distribution of this file, with or without modification, 173 | are permitted in any medium without royalty provided the copyright 174 | notice and this notice are preserved. 175 | 176 | Call graph (explanation follows) 177 | 178 | 179 | granularity: each sample hit covers 2 byte(s) no time propagated 180 | 181 | index % time self children called name 182 | 0.00 0.00 2932/2932 jbwm_snap_dim [10] 183 | [1] 0.0 0.00 0.00 2932 absmin [1] 184 | ----------------------------------------------- 185 | 0.00 0.00 2184/2184 sborderdir [3] 186 | [2] 0.0 0.00 0.00 2184 sborder [2] 187 | ----------------------------------------------- 188 | 0.00 0.00 1092/1092 jbwm_snap_border [12] 189 | [3] 0.0 0.00 0.00 1092 sborderdir [3] 190 | 0.00 0.00 2184/2184 sborder [2] 191 | ----------------------------------------------- 192 | 1885 jbwm_find_client [4] 193 | 0.00 0.00 4/1044 handle_xerror [149] 194 | 0.00 0.00 1040/1044 jbwm_events_loop [117] 195 | [4] 0.0 0.00 0.00 1044+1885 jbwm_find_client [4] 196 | 1885 jbwm_find_client [4] 197 | ----------------------------------------------- 198 | 0.00 0.00 8/962 jbwm_drag [67] 199 | 0.00 0.00 954/962 drag_event_loop [66] 200 | [5] 0.0 0.00 0.00 962 draw_outline [5] 201 | ----------------------------------------------- 202 | 0.00 0.00 922/922 jbwm_snap_client [13] 203 | [6] 0.0 0.00 0.00 922 snap_dir [6] 204 | ----------------------------------------------- 205 | 0.00 0.00 920/920 snap_search [14] 206 | [7] 0.0 0.00 0.00 920 adjust_for_titlebar [7] 207 | ----------------------------------------------- 208 | 0.00 0.00 918/918 snap_search [14] 209 | [8] 0.0 0.00 0.00 918 snap_cond [8] 210 | ----------------------------------------------- 211 | 0.00 0.00 783/783 move_buttons [22] 212 | [9] 0.0 0.00 0.00 783 mv [9] 213 | ----------------------------------------------- 214 | 0.00 0.00 733/733 snap_search [14] 215 | [10] 0.0 0.00 0.00 733 jbwm_snap_dim [10] 216 | 0.00 0.00 2932/2932 absmin [1] 217 | ----------------------------------------------- 218 | 0.00 0.00 1/553 jbwm_init_screens [124] 219 | 0.00 0.00 4/553 wm_desktop [92] 220 | 0.00 0.00 87/553 jbwm_ewmh_remove_state [36] 221 | 0.00 0.00 200/553 jbwm_handle_mwm_hints [25] 222 | 0.00 0.00 261/553 jbwm_get_title [20] 223 | [11] 0.0 0.00 0.00 553 jbwm_get_property [11] 224 | ----------------------------------------------- 225 | 0.00 0.00 85/546 commit_key_move [38] 226 | 0.00 0.00 461/546 jbwm_snap_client [13] 227 | [12] 0.0 0.00 0.00 546 jbwm_snap_border [12] 228 | 0.00 0.00 1092/1092 sborderdir [3] 229 | ----------------------------------------------- 230 | 0.00 0.00 4/461 jbwm_new_client [84] 231 | 0.00 0.00 457/461 drag_event_loop [66] 232 | [13] 0.0 0.00 0.00 461 jbwm_snap_client [13] 233 | 0.00 0.00 922/922 snap_dir [6] 234 | 0.00 0.00 461/546 jbwm_snap_border [12] 235 | 0.00 0.00 461/461 snap_search [14] 236 | ----------------------------------------------- 237 | 0.00 0.00 461/461 jbwm_snap_client [13] 238 | [14] 0.0 0.00 0.00 461 snap_search [14] 239 | 0.00 0.00 920/920 adjust_for_titlebar [7] 240 | 0.00 0.00 918/918 snap_cond [8] 241 | 0.00 0.00 733/733 jbwm_snap_dim [10] 242 | ----------------------------------------------- 243 | 0.00 0.00 334/334 jbwm_events_loop [117] 244 | [15] 0.0 0.00 0.00 334 jbwm_handle_PropertyNotify [15] 245 | 0.00 0.00 221/259 jbwm_get_wm_state [24] 246 | 0.00 0.00 38/196 jbwm_move_resize [28] 247 | ----------------------------------------------- 248 | 0.00 0.00 1/263 get_wm_protocols [109] 249 | 0.00 0.00 3/263 get_wm_delete_window [93] 250 | 0.00 0.00 259/263 jbwm_get_wm_state [24] 251 | [16] 0.0 0.00 0.00 263 get_atom [16] 252 | ----------------------------------------------- 253 | 0.00 0.00 261/261 draw_title [18] 254 | [17] 0.0 0.00 0.00 261 draw_text [17] 255 | ----------------------------------------------- 256 | 0.00 0.00 261/261 jbwm_update_title_bar [21] 257 | [18] 0.0 0.00 0.00 261 draw_title [18] 258 | 0.00 0.00 261/261 jbwm_get_title [20] 259 | 0.00 0.00 261/261 jbwm_get_font_ascent [19] 260 | 0.00 0.00 261/261 draw_text [17] 261 | ----------------------------------------------- 262 | 0.00 0.00 261/261 draw_title [18] 263 | [19] 0.0 0.00 0.00 261 jbwm_get_font_ascent [19] 264 | ----------------------------------------------- 265 | 0.00 0.00 261/261 draw_title [18] 266 | [20] 0.0 0.00 0.00 261 jbwm_get_title [20] 267 | 0.00 0.00 261/553 jbwm_get_property [11] 268 | ----------------------------------------------- 269 | 0.00 0.00 65/261 jbwm_handle_Expose [49] 270 | 0.00 0.00 196/261 jbwm_move_resize [28] 271 | [21] 0.0 0.00 0.00 261 jbwm_update_title_bar [21] 272 | 0.00 0.00 261/261 resize_title_bar [23] 273 | 0.00 0.00 261/261 draw_title [18] 274 | 0.00 0.00 4/4 new_title_bar [88] 275 | ----------------------------------------------- 276 | 0.00 0.00 261/261 resize_title_bar [23] 277 | [22] 0.0 0.00 0.00 261 move_buttons [22] 278 | 0.00 0.00 783/783 mv [9] 279 | ----------------------------------------------- 280 | 0.00 0.00 261/261 jbwm_update_title_bar [21] 281 | [23] 0.0 0.00 0.00 261 resize_title_bar [23] 282 | 0.00 0.00 261/261 move_buttons [22] 283 | ----------------------------------------------- 284 | 0.00 0.00 38/259 jbwm_set_wm_state [51] 285 | 0.00 0.00 221/259 jbwm_handle_PropertyNotify [15] 286 | [24] 0.0 0.00 0.00 259 jbwm_get_wm_state [24] 287 | 0.00 0.00 259/263 get_atom [16] 288 | ----------------------------------------------- 289 | 0.00 0.00 4/200 jbwm_new_client [84] 290 | 0.00 0.00 196/200 jbwm_move_resize [28] 291 | [25] 0.0 0.00 0.00 200 jbwm_handle_mwm_hints [25] 292 | 0.00 0.00 200/553 jbwm_get_property [11] 293 | ----------------------------------------------- 294 | 0.00 0.00 196/196 jbwm_move_resize [28] 295 | [26] 0.0 0.00 0.00 196 do_move [26] 296 | ----------------------------------------------- 297 | 0.00 0.00 196/196 jbwm_move_resize [28] 298 | [27] 0.0 0.00 0.00 196 jbwm_configure_client [27] 299 | ----------------------------------------------- 300 | 0.00 0.00 3/196 jbwm_set_not_horz [96] 301 | 0.00 0.00 3/196 jbwm_set_horz [95] 302 | 0.00 0.00 3/196 jbwm_set_not_vert [97] 303 | 0.00 0.00 3/196 jbwm_set_vert [98] 304 | 0.00 0.00 8/196 jbwm_drag [67] 305 | 0.00 0.00 38/196 jbwm_handle_PropertyNotify [15] 306 | 0.00 0.00 53/196 jbwm_handle_ConfigureNotify [31] 307 | 0.00 0.00 85/196 commit_key_move [38] 308 | [28] 0.0 0.00 0.00 196 jbwm_move_resize [28] 309 | 0.00 0.00 196/261 jbwm_update_title_bar [21] 310 | 0.00 0.00 196/200 jbwm_handle_mwm_hints [25] 311 | 0.00 0.00 196/196 do_move [26] 312 | 0.00 0.00 196/196 jbwm_configure_client [27] 313 | 0.00 0.00 196/196 jbwm_set_shape [29] 314 | ----------------------------------------------- 315 | 0.00 0.00 196/196 jbwm_move_resize [28] 316 | [29] 0.0 0.00 0.00 196 jbwm_set_shape [29] 317 | ----------------------------------------------- 318 | 0.00 0.00 184/184 jbwm_events_loop [117] 319 | [30] 0.0 0.00 0.00 184 jbwm_handle_EnterNotify [30] 320 | 0.00 0.00 62/66 jbwm_select_client [44] 321 | ----------------------------------------------- 322 | 0.00 0.00 168/168 jbwm_events_loop [117] 323 | [31] 0.0 0.00 0.00 168 jbwm_handle_ConfigureNotify [31] 324 | 0.00 0.00 53/196 jbwm_move_resize [28] 325 | ----------------------------------------------- 326 | 0.00 0.00 1/108 jbwm_grab_root_keys [122] 327 | 0.00 0.00 107/108 jbwm_handle_key_event [33] 328 | [32] 0.0 0.00 0.00 108 jbwm_get_mod_mask [32] 329 | ----------------------------------------------- 330 | 0.00 0.00 107/107 jbwm_events_loop [117] 331 | [33] 0.0 0.00 0.00 107 jbwm_handle_key_event [33] 332 | 0.00 0.00 107/108 jbwm_get_mod_mask [32] 333 | 0.00 0.00 94/94 handle_client_key_event [34] 334 | 0.00 0.00 11/11 cond_set_vdesk [64] 335 | 0.00 0.00 1/1 jbwm_exec [119] 336 | ----------------------------------------------- 337 | 0.00 0.00 94/94 jbwm_handle_key_event [33] 338 | [34] 0.0 0.00 0.00 94 handle_client_key_event [34] 339 | 0.00 0.00 85/85 handle_key_move [41] 340 | 0.00 0.00 4/4 toggle_maximize [91] 341 | 0.00 0.00 1/1 jbwm_send_wm_delete [129] 342 | 0.00 0.00 1/3 jbwm_set_not_horz [96] 343 | 0.00 0.00 1/3 jbwm_set_horz [95] 344 | 0.00 0.00 1/3 jbwm_set_not_vert [97] 345 | 0.00 0.00 1/3 jbwm_set_vert [98] 346 | ----------------------------------------------- 347 | 0.00 0.00 3/94 jbwm_set_horz [95] 348 | 0.00 0.00 3/94 set_vert [102] 349 | 0.00 0.00 22/94 jbwm_set_wm_state [51] 350 | 0.00 0.00 66/94 set_focused [47] 351 | [35] 0.0 0.00 0.00 94 jbwm_ewmh_add_state [35] 352 | ----------------------------------------------- 353 | 0.00 0.00 3/87 set_not_horz [100] 354 | 0.00 0.00 3/87 set_not_vert [101] 355 | 0.00 0.00 16/87 jbwm_set_wm_state [51] 356 | 0.00 0.00 65/87 set_state_not_focused [50] 357 | [36] 0.0 0.00 0.00 87 jbwm_ewmh_remove_state [36] 358 | 0.00 0.00 87/553 jbwm_get_property [11] 359 | ----------------------------------------------- 360 | 0.00 0.00 1/86 jbwm_drag [67] 361 | 0.00 0.00 85/86 point [43] 362 | [37] 0.0 0.00 0.00 86 jbwm_warp [37] 363 | ----------------------------------------------- 364 | 0.00 0.00 85/85 key_move [42] 365 | [38] 0.0 0.00 0.00 85 commit_key_move [38] 366 | 0.00 0.00 85/546 jbwm_snap_border [12] 367 | 0.00 0.00 85/196 jbwm_move_resize [28] 368 | 0.00 0.00 85/85 point [43] 369 | ----------------------------------------------- 370 | 0.00 0.00 85/85 key_move [42] 371 | [39] 0.0 0.00 0.00 85 get_antecedent [39] 372 | 0.00 0.00 25/25 has_sufficient_size [53] 373 | 0.00 0.00 25/25 can_resize [52] 374 | ----------------------------------------------- 375 | 0.00 0.00 85/85 handle_key_move [41] 376 | [40] 0.0 0.00 0.00 85 get_move_flags [40] 377 | ----------------------------------------------- 378 | 0.00 0.00 85/85 handle_client_key_event [34] 379 | [41] 0.0 0.00 0.00 85 handle_key_move [41] 380 | 0.00 0.00 85/85 get_move_flags [40] 381 | 0.00 0.00 85/85 key_move [42] 382 | ----------------------------------------------- 383 | 0.00 0.00 85/85 handle_key_move [41] 384 | [42] 0.0 0.00 0.00 85 key_move [42] 385 | 0.00 0.00 85/85 get_antecedent [39] 386 | 0.00 0.00 85/85 commit_key_move [38] 387 | ----------------------------------------------- 388 | 0.00 0.00 85/85 commit_key_move [38] 389 | [43] 0.0 0.00 0.00 85 point [43] 390 | 0.00 0.00 85/86 jbwm_warp [37] 391 | ----------------------------------------------- 392 | 0.00 0.00 4/66 jbwm_new_client [84] 393 | 0.00 0.00 62/66 jbwm_handle_EnterNotify [30] 394 | [44] 0.0 0.00 0.00 66 jbwm_select_client [44] 395 | 0.00 0.00 66/66 set_focused [47] 396 | 0.00 0.00 66/66 set_border [46] 397 | 0.00 0.00 66/66 set_active_window_property [45] 398 | 0.00 0.00 65/65 set_state_not_focused [50] 399 | ----------------------------------------------- 400 | 0.00 0.00 66/66 jbwm_select_client [44] 401 | [45] 0.0 0.00 0.00 66 set_active_window_property [45] 402 | ----------------------------------------------- 403 | 0.00 0.00 66/66 jbwm_select_client [44] 404 | [46] 0.0 0.00 0.00 66 set_border [46] 405 | ----------------------------------------------- 406 | 0.00 0.00 66/66 jbwm_select_client [44] 407 | [47] 0.0 0.00 0.00 66 set_focused [47] 408 | 0.00 0.00 66/94 jbwm_ewmh_add_state [35] 409 | ----------------------------------------------- 410 | 0.00 0.00 65/65 set_state_not_focused [50] 411 | [48] 0.0 0.00 0.00 65 get_bg [48] 412 | ----------------------------------------------- 413 | 0.00 0.00 65/65 jbwm_events_loop [117] 414 | [49] 0.0 0.00 0.00 65 jbwm_handle_Expose [49] 415 | 0.00 0.00 65/261 jbwm_update_title_bar [21] 416 | ----------------------------------------------- 417 | 0.00 0.00 65/65 jbwm_select_client [44] 418 | [50] 0.0 0.00 0.00 65 set_state_not_focused [50] 419 | 0.00 0.00 65/65 get_bg [48] 420 | 0.00 0.00 65/87 jbwm_ewmh_remove_state [36] 421 | ----------------------------------------------- 422 | 0.00 0.00 16/38 jbwm_restore_client [56] 423 | 0.00 0.00 22/38 jbwm_hide_client [54] 424 | [51] 0.0 0.00 0.00 38 jbwm_set_wm_state [51] 425 | 0.00 0.00 38/259 jbwm_get_wm_state [24] 426 | 0.00 0.00 22/94 jbwm_ewmh_add_state [35] 427 | 0.00 0.00 16/87 jbwm_ewmh_remove_state [36] 428 | ----------------------------------------------- 429 | 0.00 0.00 25/25 get_antecedent [39] 430 | [52] 0.0 0.00 0.00 25 can_resize [52] 431 | ----------------------------------------------- 432 | 0.00 0.00 25/25 get_antecedent [39] 433 | [53] 0.0 0.00 0.00 25 has_sufficient_size [53] 434 | ----------------------------------------------- 435 | 0.00 0.00 1/22 jbwm_new_client [84] 436 | 0.00 0.00 21/22 check_visibility [63] 437 | [54] 0.0 0.00 0.00 22 jbwm_hide_client [54] 438 | 0.00 0.00 22/38 jbwm_set_wm_state [51] 439 | ----------------------------------------------- 440 | 0.00 0.00 4/20 new_title_bar [88] 441 | 0.00 0.00 16/20 add_buttons [74] 442 | [55] 0.0 0.00 0.00 20 get_win [55] 443 | ----------------------------------------------- 444 | 0.00 0.00 4/16 jbwm_new_client [84] 445 | 0.00 0.00 12/16 check_visibility [63] 446 | [56] 0.0 0.00 0.00 16 jbwm_restore_client [56] 447 | 0.00 0.00 16/38 jbwm_set_wm_state [51] 448 | ----------------------------------------------- 449 | 35 get_client_list_r [57] 450 | 0.00 0.00 13/13 get_mixed_client_list [58] 451 | [57] 0.0 0.00 0.00 13+35 get_client_list_r [57] 452 | 35 get_client_list_r [57] 453 | ----------------------------------------------- 454 | 0.00 0.00 13/13 jbwm_ewmh_update_client_list [61] 455 | [58] 0.0 0.00 0.00 13 get_mixed_client_list [58] 456 | 0.00 0.00 13/13 get_client_list_r [57] 457 | ----------------------------------------------- 458 | 0.00 0.00 13/13 jbwm_ewmh_update_client_list [61] 459 | [59] 0.0 0.00 0.00 13 get_ordered_client_list [59] 460 | 0.00 0.00 13/13 get_window_list [60] 461 | ----------------------------------------------- 462 | 0.00 0.00 13/13 get_ordered_client_list [59] 463 | [60] 0.0 0.00 0.00 13 get_window_list [60] 464 | 0.00 0.00 13/13 query_tree [62] 465 | ----------------------------------------------- 466 | 0.00 0.00 13/13 jbwm_events_loop [117] 467 | [61] 0.0 0.00 0.00 13 jbwm_ewmh_update_client_list [61] 468 | 0.00 0.00 13/13 get_mixed_client_list [58] 469 | 0.00 0.00 13/13 get_ordered_client_list [59] 470 | ----------------------------------------------- 471 | 0.00 0.00 13/13 get_window_list [60] 472 | [62] 0.0 0.00 0.00 13 query_tree [62] 473 | ----------------------------------------------- 474 | 33 check_visibility [63] 475 | 0.00 0.00 11/11 jbwm_set_vdesk [65] 476 | [63] 0.0 0.00 0.00 11+33 check_visibility [63] 477 | 0.00 0.00 21/22 jbwm_hide_client [54] 478 | 0.00 0.00 12/16 jbwm_restore_client [56] 479 | 33 check_visibility [63] 480 | ----------------------------------------------- 481 | 0.00 0.00 11/11 jbwm_handle_key_event [33] 482 | [64] 0.0 0.00 0.00 11 cond_set_vdesk [64] 483 | 0.00 0.00 11/11 jbwm_set_vdesk [65] 484 | ----------------------------------------------- 485 | 0.00 0.00 11/11 cond_set_vdesk [64] 486 | [65] 0.0 0.00 0.00 11 jbwm_set_vdesk [65] 487 | 0.00 0.00 11/11 check_visibility [63] 488 | ----------------------------------------------- 489 | 0.00 0.00 8/8 jbwm_drag [67] 490 | [66] 0.0 0.00 0.00 8 drag_event_loop [66] 491 | 0.00 0.00 954/962 draw_outline [5] 492 | 0.00 0.00 457/461 jbwm_snap_client [13] 493 | ----------------------------------------------- 494 | 0.00 0.00 1/8 jbwm_handle_button_event [69] 495 | 0.00 0.00 7/8 handle_title_bar_button [71] 496 | [67] 0.0 0.00 0.00 8 jbwm_drag [67] 497 | 0.00 0.00 8/8 query_pointer [70] 498 | 0.00 0.00 8/962 draw_outline [5] 499 | 0.00 0.00 8/8 drag_event_loop [66] 500 | 0.00 0.00 8/196 jbwm_move_resize [28] 501 | 0.00 0.00 1/86 jbwm_warp [37] 502 | ----------------------------------------------- 503 | 0.00 0.00 4/8 do_grabs [77] 504 | 0.00 0.00 4/8 configure_title_bar [76] 505 | [68] 0.0 0.00 0.00 8 jbwm_grab_button [68] 506 | ----------------------------------------------- 507 | 0.00 0.00 8/8 jbwm_events_loop [117] 508 | [69] 0.0 0.00 0.00 8 jbwm_handle_button_event [69] 509 | 0.00 0.00 7/7 handle_title_bar_button [71] 510 | 0.00 0.00 1/8 jbwm_drag [67] 511 | ----------------------------------------------- 512 | 0.00 0.00 8/8 jbwm_drag [67] 513 | [70] 0.0 0.00 0.00 8 query_pointer [70] 514 | ----------------------------------------------- 515 | 0.00 0.00 7/7 jbwm_handle_button_event [69] 516 | [71] 0.0 0.00 0.00 7 handle_title_bar_button [71] 517 | 0.00 0.00 7/8 jbwm_drag [67] 518 | ----------------------------------------------- 519 | 0.00 0.00 7/7 allocate_colors [104] 520 | [72] 0.0 0.00 0.00 7 jbwm_get_pixel [72] 521 | ----------------------------------------------- 522 | 0.00 0.00 1/5 jbwm_grab_root_keys [122] 523 | 0.00 0.00 4/5 do_grabs [77] 524 | [73] 0.0 0.00 0.00 5 jbwm_get_grab_mask [73] 525 | ----------------------------------------------- 526 | 0.00 0.00 4/4 new_title_bar [88] 527 | [74] 0.0 0.00 0.00 4 add_buttons [74] 528 | 0.00 0.00 16/20 get_win [55] 529 | ----------------------------------------------- 530 | 0.00 0.00 4/4 setup_clients [131] 531 | [75] 0.0 0.00 0.00 4 check_redirect [75] 532 | ----------------------------------------------- 533 | 0.00 0.00 4/4 new_title_bar [88] 534 | [76] 0.0 0.00 0.00 4 configure_title_bar [76] 535 | 0.00 0.00 4/8 jbwm_grab_button [68] 536 | ----------------------------------------------- 537 | 0.00 0.00 4/4 jbwm_new_client [84] 538 | [77] 0.0 0.00 0.00 4 do_grabs [77] 539 | 0.00 0.00 4/4 jbwm_ewmh_set_allowed_actions [83] 540 | 0.00 0.00 4/5 jbwm_get_grab_mask [73] 541 | 0.00 0.00 4/8 jbwm_grab_button [68] 542 | ----------------------------------------------- 543 | 0.00 0.00 4/4 jbwm_new_client [84] 544 | [78] 0.0 0.00 0.00 4 get_JBWMClient [78] 545 | ----------------------------------------------- 546 | 0.00 0.00 4/4 reparent [89] 547 | [79] 0.0 0.00 0.00 4 get_parent [79] 548 | ----------------------------------------------- 549 | 0.00 0.00 4/4 jbwm_new_client [84] 550 | [80] 0.0 0.00 0.00 4 get_vdesk [80] 551 | 0.00 0.00 4/4 wm_desktop [92] 552 | ----------------------------------------------- 553 | 0.00 0.00 4/4 jbwm_set_client_geometry [86] 554 | [81] 0.0 0.00 0.00 4 get_window_attributes [81] 555 | ----------------------------------------------- 556 | 0.00 0.00 4/4 jbwm_new_shaped_client [85] 557 | [82] 0.0 0.00 0.00 4 is_shaped [82] 558 | ----------------------------------------------- 559 | 0.00 0.00 4/4 do_grabs [77] 560 | [83] 0.0 0.00 0.00 4 jbwm_ewmh_set_allowed_actions [83] 561 | ----------------------------------------------- 562 | 0.00 0.00 1/4 jbwm_handle_MapRequest [123] 563 | 0.00 0.00 3/4 setup_clients [131] 564 | [84] 0.0 0.00 0.00 4 jbwm_new_client [84] 565 | 0.00 0.00 4/4 get_JBWMClient [78] 566 | 0.00 0.00 4/4 do_grabs [77] 567 | 0.00 0.00 4/200 jbwm_handle_mwm_hints [25] 568 | 0.00 0.00 4/4 jbwm_set_client_geometry [86] 569 | 0.00 0.00 4/4 reparent [89] 570 | 0.00 0.00 4/4 get_vdesk [80] 571 | 0.00 0.00 4/461 jbwm_snap_client [13] 572 | 0.00 0.00 4/16 jbwm_restore_client [56] 573 | 0.00 0.00 4/66 jbwm_select_client [44] 574 | 0.00 0.00 1/22 jbwm_hide_client [54] 575 | ----------------------------------------------- 576 | 0.00 0.00 4/4 reparent [89] 577 | [85] 0.0 0.00 0.00 4 jbwm_new_shaped_client [85] 578 | 0.00 0.00 4/4 is_shaped [82] 579 | ----------------------------------------------- 580 | 0.00 0.00 4/4 jbwm_new_client [84] 581 | [86] 0.0 0.00 0.00 4 jbwm_set_client_geometry [86] 582 | 0.00 0.00 4/4 get_window_attributes [81] 583 | 0.00 0.00 1/1 init_geometry_for_screen [113] 584 | ----------------------------------------------- 585 | 0.00 0.00 4/4 reparent [89] 586 | [87] 0.0 0.00 0.00 4 jbwm_set_frame_extents [87] 587 | ----------------------------------------------- 588 | 0.00 0.00 4/4 jbwm_update_title_bar [21] 589 | [88] 0.0 0.00 0.00 4 new_title_bar [88] 590 | 0.00 0.00 4/20 get_win [55] 591 | 0.00 0.00 4/4 add_buttons [74] 592 | 0.00 0.00 4/4 configure_title_bar [76] 593 | ----------------------------------------------- 594 | 0.00 0.00 4/4 jbwm_new_client [84] 595 | [89] 0.0 0.00 0.00 4 reparent [89] 596 | 0.00 0.00 4/4 jbwm_new_shaped_client [85] 597 | 0.00 0.00 4/4 get_parent [79] 598 | 0.00 0.00 4/4 jbwm_set_frame_extents [87] 599 | 0.00 0.00 4/4 reparent_window [90] 600 | ----------------------------------------------- 601 | 0.00 0.00 4/4 reparent [89] 602 | [90] 0.0 0.00 0.00 4 reparent_window [90] 603 | ----------------------------------------------- 604 | 0.00 0.00 4/4 handle_client_key_event [34] 605 | [91] 0.0 0.00 0.00 4 toggle_maximize [91] 606 | 0.00 0.00 2/3 jbwm_set_not_horz [96] 607 | 0.00 0.00 2/3 jbwm_set_not_vert [97] 608 | 0.00 0.00 2/3 jbwm_set_vert [98] 609 | 0.00 0.00 2/3 jbwm_set_horz [95] 610 | ----------------------------------------------- 611 | 0.00 0.00 4/4 get_vdesk [80] 612 | [92] 0.0 0.00 0.00 4 wm_desktop [92] 613 | 0.00 0.00 4/553 jbwm_get_property [11] 614 | ----------------------------------------------- 615 | 0.00 0.00 1/3 jbwm_send_wm_delete [129] 616 | 0.00 0.00 2/3 find_delete_proto [106] 617 | [93] 0.0 0.00 0.00 3 get_wm_delete_window [93] 618 | 0.00 0.00 3/263 get_atom [16] 619 | ----------------------------------------------- 620 | 0.00 0.00 3/3 jbwm_events_loop [117] 621 | [94] 0.0 0.00 0.00 3 jbwm_handle_ConfigureRequest [94] 622 | ----------------------------------------------- 623 | 0.00 0.00 1/3 handle_client_key_event [34] 624 | 0.00 0.00 2/3 toggle_maximize [91] 625 | [95] 0.0 0.00 0.00 3 jbwm_set_horz [95] 626 | 0.00 0.00 3/94 jbwm_ewmh_add_state [35] 627 | 0.00 0.00 3/3 set_horz [99] 628 | 0.00 0.00 3/196 jbwm_move_resize [28] 629 | ----------------------------------------------- 630 | 0.00 0.00 1/3 handle_client_key_event [34] 631 | 0.00 0.00 2/3 toggle_maximize [91] 632 | [96] 0.0 0.00 0.00 3 jbwm_set_not_horz [96] 633 | 0.00 0.00 3/196 jbwm_move_resize [28] 634 | 0.00 0.00 3/3 set_not_horz [100] 635 | ----------------------------------------------- 636 | 0.00 0.00 1/3 handle_client_key_event [34] 637 | 0.00 0.00 2/3 toggle_maximize [91] 638 | [97] 0.0 0.00 0.00 3 jbwm_set_not_vert [97] 639 | 0.00 0.00 3/196 jbwm_move_resize [28] 640 | 0.00 0.00 3/3 set_not_vert [101] 641 | ----------------------------------------------- 642 | 0.00 0.00 1/3 handle_client_key_event [34] 643 | 0.00 0.00 2/3 toggle_maximize [91] 644 | [98] 0.0 0.00 0.00 3 jbwm_set_vert [98] 645 | 0.00 0.00 3/3 set_vert [102] 646 | 0.00 0.00 3/196 jbwm_move_resize [28] 647 | ----------------------------------------------- 648 | 0.00 0.00 3/3 jbwm_set_horz [95] 649 | [99] 0.0 0.00 0.00 3 set_horz [99] 650 | ----------------------------------------------- 651 | 0.00 0.00 3/3 jbwm_set_not_horz [96] 652 | [100] 0.0 0.00 0.00 3 set_not_horz [100] 653 | 0.00 0.00 3/87 jbwm_ewmh_remove_state [36] 654 | ----------------------------------------------- 655 | 0.00 0.00 3/3 jbwm_set_not_vert [97] 656 | [101] 0.0 0.00 0.00 3 set_not_vert [101] 657 | 0.00 0.00 3/87 jbwm_ewmh_remove_state [36] 658 | ----------------------------------------------- 659 | 0.00 0.00 3/3 jbwm_set_vert [98] 660 | [102] 0.0 0.00 0.00 3 set_vert [102] 661 | 0.00 0.00 3/94 jbwm_ewmh_add_state [35] 662 | ----------------------------------------------- 663 | 47 grab_r [103] 664 | 0.00 0.00 2/2 jbwm_grab_root_keys [122] 665 | [103] 0.0 0.00 0.00 2+47 grab_r [103] 666 | 47 grab_r [103] 667 | ----------------------------------------------- 668 | 0.00 0.00 1/1 jbwm_init_screens [124] 669 | [104] 0.0 0.00 0.00 1 allocate_colors [104] 670 | 0.00 0.00 7/7 jbwm_get_pixel [72] 671 | ----------------------------------------------- 672 | 0.00 0.00 1/1 init_geometry_for_screen [113] 673 | [105] 0.0 0.00 0.00 1 check_dimensions [105] 674 | ----------------------------------------------- 675 | 1 find_delete_proto [106] 676 | 0.00 0.00 1/1 has_delete_proto [111] 677 | [106] 0.0 0.00 0.00 1+1 find_delete_proto [106] 678 | 0.00 0.00 2/3 get_wm_delete_window [93] 679 | 1 find_delete_proto [106] 680 | ----------------------------------------------- 681 | 0.00 0.00 1/1 jbwm_handle_MapRequest [123] 682 | [107] 0.0 0.00 0.00 1 get_screen [107] 683 | ----------------------------------------------- 684 | 0.00 0.00 1/1 setup_clients [131] 685 | [108] 0.0 0.00 0.00 1 get_windows [108] 686 | ----------------------------------------------- 687 | 0.00 0.00 1/1 jbwm_send_wm_delete [129] 688 | [109] 0.0 0.00 0.00 1 get_wm_protocols [109] 689 | 0.00 0.00 1/263 get_atom [16] 690 | ----------------------------------------------- 691 | 0.00 0.00 1/1 init_geometry_for_screen [113] 692 | [110] 0.0 0.00 0.00 1 handle_wm_normal_hints [110] 693 | ----------------------------------------------- 694 | 0.00 0.00 1/1 jbwm_send_wm_delete [129] 695 | [111] 0.0 0.00 0.00 1 has_delete_proto [111] 696 | 0.00 0.00 1/1 find_delete_proto [106] 697 | ----------------------------------------------- 698 | 0.00 0.00 1/1 jbwm_ewmh_init_screen [118] 699 | [112] 0.0 0.00 0.00 1 init_desktops [112] 700 | ----------------------------------------------- 701 | 0.00 0.00 1/1 jbwm_set_client_geometry [86] 702 | [113] 0.0 0.00 0.00 1 init_geometry_for_screen [113] 703 | 0.00 0.00 1/1 check_dimensions [105] 704 | 0.00 0.00 1/1 handle_wm_normal_hints [110] 705 | ----------------------------------------------- 706 | 0.00 0.00 1/1 jbwm_ewmh_init_screen [118] 707 | [114] 0.0 0.00 0.00 1 init_supporting [114] 708 | ----------------------------------------------- 709 | 0.00 0.00 1/1 jbwm_events_loop [117] 710 | [115] 0.0 0.00 0.00 1 jbwm_client_free [115] 711 | 0.00 0.00 1/1 jbwm_relink_client_list [128] 712 | ----------------------------------------------- 713 | 0.00 0.00 1/1 main [162] 714 | [116] 0.0 0.00 0.00 1 jbwm_create_atoms [116] 715 | ----------------------------------------------- 716 | 0.00 0.00 1/1 main [162] 717 | [117] 0.0 0.00 0.00 1 jbwm_events_loop [117] 718 | 0.00 0.00 1040/1044 jbwm_find_client [4] 719 | 0.00 0.00 334/334 jbwm_handle_PropertyNotify [15] 720 | 0.00 0.00 184/184 jbwm_handle_EnterNotify [30] 721 | 0.00 0.00 168/168 jbwm_handle_ConfigureNotify [31] 722 | 0.00 0.00 107/107 jbwm_handle_key_event [33] 723 | 0.00 0.00 65/65 jbwm_handle_Expose [49] 724 | 0.00 0.00 13/13 jbwm_ewmh_update_client_list [61] 725 | 0.00 0.00 8/8 jbwm_handle_button_event [69] 726 | 0.00 0.00 3/3 jbwm_handle_ConfigureRequest [94] 727 | 0.00 0.00 1/1 jbwm_client_free [115] 728 | 0.00 0.00 1/1 jbwm_handle_MapRequest [123] 729 | ----------------------------------------------- 730 | 0.00 0.00 1/1 jbwm_init_screens [124] 731 | [118] 0.0 0.00 0.00 1 jbwm_ewmh_init_screen [118] 732 | 0.00 0.00 1/1 init_desktops [112] 733 | 0.00 0.00 1/1 init_supporting [114] 734 | ----------------------------------------------- 735 | 0.00 0.00 1/1 jbwm_handle_key_event [33] 736 | [119] 0.0 0.00 0.00 1 jbwm_exec [119] 737 | ----------------------------------------------- 738 | 0.00 0.00 1/1 jbwm_init_screens [124] 739 | [120] 0.0 0.00 0.00 1 jbwm_get_font [120] 740 | ----------------------------------------------- 741 | 0.00 0.00 1/1 jbwm_init_screens [124] 742 | [121] 0.0 0.00 0.00 1 jbwm_get_font_height [121] 743 | ----------------------------------------------- 744 | 0.00 0.00 1/1 jbwm_init_screens [124] 745 | [122] 0.0 0.00 0.00 1 jbwm_grab_root_keys [122] 746 | 0.00 0.00 2/2 grab_r [103] 747 | 0.00 0.00 1/5 jbwm_get_grab_mask [73] 748 | 0.00 0.00 1/108 jbwm_get_mod_mask [32] 749 | ----------------------------------------------- 750 | 0.00 0.00 1/1 jbwm_events_loop [117] 751 | [123] 0.0 0.00 0.00 1 jbwm_handle_MapRequest [123] 752 | 0.00 0.00 1/1 get_screen [107] 753 | 0.00 0.00 1/4 jbwm_new_client [84] 754 | ----------------------------------------------- 755 | 1 jbwm_init_screens [124] 756 | 0.00 0.00 1/1 main [162] 757 | [124] 0.0 0.00 0.00 1+1 jbwm_init_screens [124] 758 | 0.00 0.00 1/553 jbwm_get_property [11] 759 | 0.00 0.00 1/1 jbwm_get_font [120] 760 | 0.00 0.00 1/1 jbwm_get_font_height [121] 761 | 0.00 0.00 1/1 allocate_colors [104] 762 | 0.00 0.00 1/1 setup_gc [133] 763 | 0.00 0.00 1/1 setup_event_listeners [132] 764 | 0.00 0.00 1/1 jbwm_grab_root_keys [122] 765 | 0.00 0.00 1/1 setup_clients [131] 766 | 0.00 0.00 1/1 jbwm_ewmh_init_screen [118] 767 | 1 jbwm_init_screens [124] 768 | ----------------------------------------------- 769 | 0.00 0.00 1/1 main [162] 770 | [125] 0.0 0.00 0.00 1 jbwm_open_display [125] 771 | ----------------------------------------------- 772 | 0.00 0.00 1/1 main [162] 773 | [126] 0.0 0.00 0.00 1 jbwm_open_font [126] 774 | ----------------------------------------------- 775 | 0.00 0.00 1/1 main [162] 776 | [127] 0.0 0.00 0.00 1 jbwm_parse_command_line [127] 777 | ----------------------------------------------- 778 | 0.00 0.00 1/1 jbwm_client_free [115] 779 | [128] 0.0 0.00 0.00 1 jbwm_relink_client_list [128] 780 | ----------------------------------------------- 781 | 0.00 0.00 1/1 handle_client_key_event [34] 782 | [129] 0.0 0.00 0.00 1 jbwm_send_wm_delete [129] 783 | 0.00 0.00 1/1 has_delete_proto [111] 784 | 0.00 0.00 1/3 get_wm_delete_window [93] 785 | 0.00 0.00 1/1 get_wm_protocols [109] 786 | 0.00 0.00 1/1 xmsg [134] 787 | ----------------------------------------------- 788 | 0.00 0.00 1/1 main [162] 789 | [130] 0.0 0.00 0.00 1 jbwm_set_up_error_handler [130] 790 | ----------------------------------------------- 791 | 0.00 0.00 1/1 jbwm_init_screens [124] 792 | [131] 0.0 0.00 0.00 1 setup_clients [131] 793 | 0.00 0.00 4/4 check_redirect [75] 794 | 0.00 0.00 3/4 jbwm_new_client [84] 795 | 0.00 0.00 1/1 get_windows [108] 796 | ----------------------------------------------- 797 | 0.00 0.00 1/1 jbwm_init_screens [124] 798 | [132] 0.0 0.00 0.00 1 setup_event_listeners [132] 799 | ----------------------------------------------- 800 | 0.00 0.00 1/1 jbwm_init_screens [124] 801 | [133] 0.0 0.00 0.00 1 setup_gc [133] 802 | ----------------------------------------------- 803 | 0.00 0.00 1/1 jbwm_send_wm_delete [129] 804 | [134] 0.0 0.00 0.00 1 xmsg [134] 805 | ----------------------------------------------- 806 | 807 | This table describes the call tree of the program, and was sorted by 808 | the total amount of time spent in each function and its children. 809 | 810 | Each entry in this table consists of several lines. The line with the 811 | index number at the left hand margin lists the current function. 812 | The lines above it list the functions that called this function, 813 | and the lines below it list the functions this one called. 814 | This line lists: 815 | index A unique number given to each element of the table. 816 | Index numbers are sorted numerically. 817 | The index number is printed next to every function name so 818 | it is easier to look up where the function is in the table. 819 | 820 | % time This is the percentage of the `total' time that was spent 821 | in this function and its children. Note that due to 822 | different viewpoints, functions excluded by options, etc, 823 | these numbers will NOT add up to 100%. 824 | 825 | self This is the total amount of time spent in this function. 826 | 827 | children This is the total amount of time propagated into this 828 | function by its children. 829 | 830 | called This is the number of times the function was called. 831 | If the function called itself recursively, the number 832 | only includes non-recursive calls, and is followed by 833 | a `+' and the number of recursive calls. 834 | 835 | name The name of the current function. The index number is 836 | printed after it. If the function is a member of a 837 | cycle, the cycle number is printed between the 838 | function's name and the index number. 839 | 840 | 841 | For the function's parents, the fields have the following meanings: 842 | 843 | self This is the amount of time that was propagated directly 844 | from the function into this parent. 845 | 846 | children This is the amount of time that was propagated from 847 | the function's children into this parent. 848 | 849 | called This is the number of times this parent called the 850 | function `/' the total number of times the function 851 | was called. Recursive calls to the function are not 852 | included in the number after the `/'. 853 | 854 | name This is the name of the parent. The parent's index 855 | number is printed after it. If the parent is a 856 | member of a cycle, the cycle number is printed between 857 | the name and the index number. 858 | 859 | If the parents of the function cannot be determined, the word 860 | `' is printed in the `name' field, and all the other 861 | fields are blank. 862 | 863 | For the function's children, the fields have the following meanings: 864 | 865 | self This is the amount of time that was propagated directly 866 | from the child into the function. 867 | 868 | children This is the amount of time that was propagated from the 869 | child's children to the function. 870 | 871 | called This is the number of times the function called 872 | this child `/' the total number of times the child 873 | was called. Recursive calls by the child are not 874 | listed in the number after the `/'. 875 | 876 | name This is the name of the child. The child's index 877 | number is printed after it. If the child is a 878 | member of a cycle, the cycle number is printed 879 | between the name and the index number. 880 | 881 | If there are any cycles (circles) in the call graph, there is an 882 | entry for the cycle-as-a-whole. This entry shows who called the 883 | cycle (as parents) and the members of the cycle (as children.) 884 | The `+' recursive calls entry shows the number of function calls that 885 | were internal to the cycle, and the calls entry for each member shows, 886 | for that member, how many times it was called from other members of 887 | the cycle. 888 | 889 | Copyright (C) 2012-2017 Free Software Foundation, Inc. 890 | 891 | Copying and distribution of this file, with or without modification, 892 | are permitted in any medium without royalty provided the copyright 893 | notice and this notice are preserved. 894 | 895 | Index by function name 896 | 897 | [1] absmin (snap.c) [82] is_shaped (shape.c) [86] jbwm_set_client_geometry 898 | [74] add_buttons (title_bar.c) [115] jbwm_client_free [87] jbwm_set_frame_extents 899 | [7] adjust_for_titlebar (snap.c) [27] jbwm_configure_client (move_resize.c) [95] jbwm_set_horz 900 | [104] allocate_colors (jbwm.c) [116] jbwm_create_atoms [96] jbwm_set_not_horz 901 | [52] can_resize (key_event.c) [67] jbwm_drag [97] jbwm_set_not_vert 902 | [105] check_dimensions (geometry.c) [117] jbwm_events_loop [29] jbwm_set_shape 903 | [75] check_redirect (jbwm.c) [35] jbwm_ewmh_add_state [130] jbwm_set_up_error_handler 904 | [63] check_visibility (vdesk.c) [118] jbwm_ewmh_init_screen [65] jbwm_set_vdesk 905 | [38] commit_key_move (key_event.c) [36] jbwm_ewmh_remove_state [98] jbwm_set_vert 906 | [64] cond_set_vdesk (key_event.c) [83] jbwm_ewmh_set_allowed_actions [51] jbwm_set_wm_state 907 | [76] configure_title_bar (title_bar.c) [61] jbwm_ewmh_update_client_list [12] jbwm_snap_border 908 | [77] do_grabs (new.c) [119] jbwm_exec [13] jbwm_snap_client 909 | [26] do_move (move_resize.c) [4] jbwm_find_client [10] jbwm_snap_dim (snap.c) 910 | [66] drag_event_loop (drag.c) [120] jbwm_get_font [21] jbwm_update_title_bar 911 | [5] draw_outline (drag.c) [19] jbwm_get_font_ascent [37] jbwm_warp 912 | [17] draw_text (title_bar.c) [121] jbwm_get_font_height [42] key_move (key_event.c) 913 | [18] draw_title (title_bar.c) [73] jbwm_get_grab_mask [22] move_buttons (title_bar.c) 914 | [106] find_delete_proto (wm_state.c) [32] jbwm_get_mod_mask [9] mv (title_bar.c) 915 | [78] get_JBWMClient (new.c) [72] jbwm_get_pixel [88] new_title_bar (title_bar.c) 916 | [39] get_antecedent (key_event.c) [11] jbwm_get_property [43] point (key_event.c) 917 | [16] get_atom (wm_state.c) [20] jbwm_get_title (title_bar.c) [70] query_pointer (drag.c) 918 | [48] get_bg (select.c) [24] jbwm_get_wm_state [62] query_tree (ewmh.c) 919 | [57] get_client_list_r (ewmh.c) [68] jbwm_grab_button [89] reparent (new.c) 920 | [58] get_mixed_client_list (ewmh.c) [122] jbwm_grab_root_keys [90] reparent_window (new.c) 921 | [40] get_move_flags (key_event.c) [31] jbwm_handle_ConfigureNotify (events.c) [23] resize_title_bar (title_bar.c) 922 | [59] get_ordered_client_list (ewmh.c) [94] jbwm_handle_ConfigureRequest (events.c) [2] sborder (snap.c) 923 | [79] get_parent (new.c) [30] jbwm_handle_EnterNotify (events.c) [3] sborderdir (snap.c) 924 | [107] get_screen (events.c) [49] jbwm_handle_Expose (events.c) [45] set_active_window_property (select.c) 925 | [80] get_vdesk (new.c) [123] jbwm_handle_MapRequest (events.c) [46] set_border (select.c) 926 | [55] get_win (title_bar.c) [15] jbwm_handle_PropertyNotify (events.c) [47] set_focused (select.c) 927 | [81] get_window_attributes (geometry.c) [69] jbwm_handle_button_event [99] set_horz (max.c) 928 | [60] get_window_list (ewmh.c) [33] jbwm_handle_key_event [100] set_not_horz (max.c) 929 | [108] get_windows (jbwm.c) [25] jbwm_handle_mwm_hints [101] set_not_vert (max.c) 930 | [93] get_wm_delete_window (wm_state.c) [54] jbwm_hide_client [50] set_state_not_focused (select.c) 931 | [109] get_wm_protocols (wm_state.c) [124] jbwm_init_screens [102] set_vert (max.c) 932 | [103] grab_r (keys.c) [28] jbwm_move_resize [131] setup_clients (jbwm.c) 933 | [34] handle_client_key_event (key_event.c) [84] jbwm_new_client [132] setup_event_listeners (jbwm.c) 934 | [41] handle_key_move (key_event.c) [85] jbwm_new_shaped_client [133] setup_gc (jbwm.c) 935 | [71] handle_title_bar_button (button_event.c) [125] jbwm_open_display [8] snap_cond (snap.c) 936 | [110] handle_wm_normal_hints (geometry.c) [126] jbwm_open_font [6] snap_dir (snap.c) 937 | [111] has_delete_proto (wm_state.c) [127] jbwm_parse_command_line [14] snap_search (snap.c) 938 | [53] has_sufficient_size (key_event.c) [128] jbwm_relink_client_list [91] toggle_maximize (key_event.c) 939 | [112] init_desktops (ewmh.c) [56] jbwm_restore_client [92] wm_desktop (new.c) 940 | [113] init_geometry_for_screen (geometry.c) [44] jbwm_select_client [134] xmsg (wm_state.c) 941 | [114] init_supporting (ewmh.c) [129] jbwm_send_wm_delete 942 | -------------------------------------------------------------------------------- /indent.scr: -------------------------------------------------------------------------------- 1 | gg=G:wq 2 | -------------------------------------------------------------------------------- /indent.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | for f in *.[ch]; do vim -s indent.scr $f; done 3 | -------------------------------------------------------------------------------- /jbwm.1: -------------------------------------------------------------------------------- 1 | .TH jbwm 1 "01 JAN 2017" 2 | 3 | .SH NAME 4 | jbwm \- minimalistic window manager for X 5 | 6 | .SH SYNOPSIS 7 | .B jbwm 8 | [\fB-1\fR \fIMODS\fR] 9 | [\fB-2\fR \fIMODS\fR] 10 | [\fB-v\fR] 11 | 12 | .SH DESCRIPTION 13 | .B jbwm 14 | is a minimalist window manager forked from evilwm, adding basic title bar 15 | support, simpler key bindings, and various code cleanups and size 16 | reductions. evilwm is based on aewm, extended to feature 17 | many keyboard controls, and otherwise altered to be more friendly. 18 | 19 | .SH OPTIONS 20 | .IP "\fB-1 \fIMOD" 21 | Set first modifier key. \fBMOD\fR may be control, alt, mod1, mod2, mod3, 22 | mod4, or mod5. 23 | .IP "\fB-2 \fIMOD" 24 | Set second modifier key. \fBMOD\fR is as above. 25 | .IP "\fB-v" 26 | Print version then exit. 27 | .IP "\fB-*" 28 | For all other options, display usage then exit. 29 | 30 | .SH NOTES 31 | In jbwm, the focus follows the mouse pointer, and focus is not lost if 32 | you stray onto the root window. 33 | .PP 34 | You can use the mouse to manipulate windows either by click/dragging 35 | the 1 pixel border, or by holding down \fBMod1\fR and doing so anywhere 36 | in the client window. The controls are: 37 | .IP "\fBButton 1" 38 | Move or raise window. 39 | .IP "\fBButton 2" 40 | Lower window. 41 | .IP "\fBButton 3" 42 | Resize window. 43 | .PP 44 | Most keyboard controls are used by holding down \fBMod1\fR, then 45 | pressing a key. Available functions are: 46 | .IP \fBEscape 47 | Exit jbwm. 48 | .IP \fBReturn 49 | Spawn new terminal. 50 | .IP \fBq 51 | Delete current window. 52 | .IP "\fBDown Arrow" 53 | Lower current window. 54 | .IP "\fBUp Arrow" 55 | Raise current window. 56 | .IP "\fBH, J, K, L" 57 | Move window left, down, up or right. Holding \fBShift\fR resizes the 58 | window instead. 59 | .IP \fBa 60 | Toggle fullscreen. 61 | .IP \fBSpace 62 | Toggle maximization. 63 | .IP \fBz 64 | Toggle vertical maximization. 65 | .IP \fBx 66 | Toggle horizontal maximization. 67 | .IP \fBs 68 | Toggle window shade. 69 | .PP 70 | If compiled with virtual desktop support, these functions are also available: 71 | .IP \fB. 72 | Toggle window stickiness. 73 | .IP "\fB1--0" 74 | Switch virtual desktop. 75 | .IP \fBLeft 76 | Previous virtual desktop. 77 | .IP \fBRight 78 | Next virtual desktop. 79 | .PP 80 | In addition to the above, \fBMod1+Tab\fR can be used 81 | to cycle through windows on screen. 82 | 83 | .SH ENVIRONMENT 84 | .IP \fBDISPLAY 85 | DISPLAY should be set, otherwise default of :0 will be used. 86 | .IP \fBJBWM_FC 87 | Set sticky window border color. 88 | .IP \fBJBWM_FG 89 | Set foreground color. 90 | .IP \fBJBWM_BG 91 | Set background color. 92 | .IP \fBJBWM_CLOSE 93 | Set close button color. 94 | .IP \fBJBWM_SHADE 95 | Set shade button color. 96 | .IP \fBJBWM_RESIZE 97 | Set resize button color. 98 | .IP \fBJBWM_FONT 99 | Set font. 100 | .IP \fBJBWM_TERM 101 | Set terminal emulator program. 102 | 103 | .SH BUGS 104 | EWMH support is a work in progress. 105 | 106 | .SH AUTHOR 107 | Jeffrey Bedard <\fIalisabedard@gmail.com\fR> 108 | Ciaran Anscomb <\fIevilwm@6809.org.uk\fR> wrote evilwm. 109 | Decklin Foster <\fIfosterd@hartwick.edu\fR> wrote aewm. 110 | David Hogan <\fIdhog@cs.su.oz.au\fR> wrote 9wm. 111 | 112 | .SH "SEE ALSO" 113 | .BR xinit (1), 114 | .BR X (7) 115 | -------------------------------------------------------------------------------- /jbwm.c: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2019, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | //#undef DEBUG 6 | #include "jbwm.h" 7 | #include "config.h" 8 | #include "ewmh.h" 9 | #include "font.h" 10 | #include "atom.h" 11 | #include "JBWMScreen.h" 12 | #include "keys.h" 13 | #include "log.h" 14 | #include "new.h" 15 | #include 16 | #include "util.h" 17 | #include "vdesk.h" 18 | #ifdef JBWM_USE_XFT 19 | static void allocate_xft_color(Display * d, struct JBWMScreen * s) 20 | { 21 | XftColorAllocName(d, DefaultVisualOfScreen(s->xlib), 22 | DefaultColormapOfScreen(s->xlib), JBWM_FG, 23 | &s->font_color); 24 | } 25 | #endif//JBWM_USE_XFT 26 | static void allocate_colors(struct JBWMScreen * s) 27 | { 28 | Display * d=s->xlib->display; 29 | const uint8_t n = s->id; 30 | #define PIX(field, color) s->pixels.field = jbwm_get_pixel(d, n, color); 31 | PIX(bg, JBWM_BG); 32 | PIX(fc, JBWM_FC); 33 | PIX(fg, JBWM_FG); 34 | PIX(close, JBWM_CLOSE); 35 | PIX(resize, JBWM_RESIZE); 36 | PIX(shade, JBWM_SHADE); 37 | PIX(stick, JBWM_STICK); 38 | #undef PIX 39 | #ifdef JBWM_USE_XFT 40 | allocate_xft_color(d, s); 41 | #endif//JBWM_USE_XFT 42 | } 43 | static bool check_redirect(Display * d, const Window w) 44 | { 45 | XWindowAttributes a; 46 | XGetWindowAttributes(d, w, &a); 47 | JBWM_LOG("check_redirect(0x%x): override_redirect: %s, " 48 | "map_state: %s", (int)w, 49 | a.override_redirect ? "true" : "false", 50 | a.map_state == IsViewable ? "IsViewable" 51 | : "not IsViewable"); 52 | return (!a.override_redirect && (a.map_state == IsViewable)); 53 | } 54 | // Free returned data with XFree() 55 | static Window * get_windows(Display * dpy, const Window root, 56 | uint16_t * win_count) 57 | { 58 | Window * w, d; 59 | unsigned int n; 60 | XQueryTree(dpy, root, &d, &d, &w, &n); 61 | *win_count = n; 62 | return w; 63 | } 64 | static void setup_clients(Display * d, struct JBWMScreen * s, 65 | struct JBWMClient ** head_client, struct JBWMClient ** current_client) 66 | { 67 | uint16_t n; 68 | Window * w = get_windows(d, RootWindow(d, s->id), &n); 69 | JBWM_LOG("Started with %d clients", n); 70 | if (w) { // Avoid segmentation fault on empty list. 71 | while(n--) 72 | if(check_redirect(d,w[n])) 73 | jbwm_new_client(s, head_client, current_client, w[n]); 74 | XFree(w); 75 | } 76 | } 77 | static inline void setup_gc(Display * d, struct JBWMScreen * s) 78 | { 79 | XGCValues v={ 80 | .foreground = s->pixels.fg, 81 | .background = s->pixels.bg, 82 | .subwindow_mode = IncludeInferiors, 83 | .line_width = 1 84 | }; 85 | unsigned long mask = GCSubwindowMode | GCLineWidth 86 | | GCForeground | GCBackground; 87 | #ifndef JBWM_USE_XFT 88 | v.font=s->font->fid; 89 | mask|=GCFont; 90 | #endif//JBWM_USE_XFT 91 | s->gc=DefaultGC(d,s->id); 92 | XChangeGC(d,s->gc,mask,&v); 93 | s->border_gc=XCreateGC(d,s->xlib->root,GCFunction, 94 | &(XGCValues){.function=GXxor}); 95 | XCopyGC(d,s->gc,mask,s->border_gc); 96 | } 97 | static inline void setup_event_listeners(Display * d, const Window root) 98 | { 99 | enum { 100 | EMASK = SubstructureRedirectMask | SubstructureNotifyMask | 101 | EnterWindowMask | PropertyChangeMask 102 | | ColormapChangeMask 103 | }; 104 | XChangeWindowAttributes(d, root, CWEventMask, 105 | &(XSetWindowAttributes){.event_mask = EMASK }); 106 | } 107 | #ifdef JBWM_USE_XFT 108 | /* Create a unique XftDraw for each screen to properly handle colormaps and 109 | * screen limitations. */ 110 | static XftDraw * new_xft_draw(Screen * s) 111 | { 112 | return XftDrawCreate(DisplayOfScreen(s), RootWindowOfScreen(s), 113 | DefaultVisualOfScreen(s), DefaultColormapOfScreen(s)); 114 | } 115 | #endif//JBWM_USE_XFT 116 | // Initialize SCREENS amount of screens. 117 | void jbwm_init_screens(Display *d, struct JBWMScreen *s, 118 | struct JBWMClient ** head_client, struct JBWMClient ** current_client, 119 | const short screens) 120 | { 121 | if(screens>=0){ 122 | unsigned long *lprop; 123 | uint16_t n; 124 | uint8_t vdesk; 125 | JBWM_LOG("jbwm_init_screen(d, screens), screens is %d", screens); 126 | s->id = screens; 127 | s->xlib = ScreenOfDisplay(d, screens); 128 | lprop=jbwm_get_property(d,s->xlib->root, 129 | jbwm_atoms[JBWM_NET_CURRENT_DESKTOP],&n); 130 | if(n){ 131 | vdesk=lprop[0]; 132 | XFree(lprop); 133 | }else 134 | vdesk=0; 135 | #ifdef JBWM_USE_XFT 136 | s->xft = new_xft_draw(s->xlib); 137 | #else//!JBWM_USE_XFT 138 | s->font = jbwm_get_font(); 139 | #endif//JBWM_USE_XFT 140 | s->font_height=jbwm_get_font_height(); 141 | allocate_colors(s); 142 | setup_gc(d, s); 143 | { // r scope 144 | const Window r = RootWindow(d, screens); 145 | setup_event_listeners(d, r); 146 | jbwm_grab_root_keys(d, r); 147 | } 148 | /* scan all the windows on this screen */ 149 | setup_clients(d, s, head_client, current_client); 150 | jbwm_ewmh_init_screen(d, s); 151 | jbwm_init_screens(d, s, head_client, current_client, screens - 1); 152 | jbwm_set_vdesk(s, *head_client, vdesk); 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /jbwm.h: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #ifndef JBWM_JBWM_H 6 | #define JBWM_JBWM_H 7 | #include 8 | struct JBWMClient; 9 | struct JBWMScreen; 10 | void jbwm_init_screens(Display *d, struct JBWMScreen *s, 11 | struct JBWMClient ** head_client, struct JBWMClient ** current_client, 12 | const short screens); 13 | #endif /* not JBWM_JBWM_H */ 14 | -------------------------------------------------------------------------------- /key_combos.h: -------------------------------------------------------------------------------- 1 | /* Mixtures of Ctrl, Alt an Escape are used for things like VMWare and 2 | * XFree86/Cygwin, so the KILL key is an option in the Makefile */ 3 | #ifndef JBWM_KEY_COMBOS_H 4 | #define JBWM_KEY_COMBOS_H 5 | 6 | #define JBWM_NUM_KEYS JBWM_KEY_0, JBWM_KEY_1, JBWM_KEY_2, \ 7 | JBWM_KEY_3, JBWM_KEY_4, JBWM_KEY_5, JBWM_KEY_6, JBWM_KEY_7, \ 8 | JBWM_KEY_8, JBWM_KEY_9 9 | 10 | #define JBWM_VWM_KEYS JBWM_KEY_PREVDESK, JBWM_KEY_NEXTDESK, \ 11 | JBWM_NUM_KEYS, JBWM_KEY_VDESK_NEXT_ROW, JBWM_KEY_VDESK_PREV_ROW 12 | #define JBWM_DIRECTION_KEYS JBWM_KEY_LEFT, JBWM_KEY_RIGHT, \ 13 | JBWM_KEY_DOWN, JBWM_KEY_UP 14 | #define JBWM_KEYS_TO_GRAB JBWM_KEY_NEXT, JBWM_KEY_NEW, JBWM_KEY_QUIT,\ 15 | JBWM_KEY_KILL, JBWM_DIRECTION_KEYS, JBWM_KEY_LOWER,\ 16 | JBWM_KEY_ALTLOWER, JBWM_KEY_MAX, JBWM_KEY_STICK,\ 17 | JBWM_VWM_KEYS, JBWM_KEY_MOVE, JBWM_KEY_RAISE, JBWM_KEY_SHADE,\ 18 | JBWM_KEY_MAX_H, JBWM_KEY_MAX_V, JBWM_KEY_FS, 0 19 | #define JBWM_ALT_KEYS_TO_GRAB JBWM_KEY_KILL, JBWM_DIRECTION_KEYS,\ 20 | JBWM_VWM_KEYS, 0 21 | #endif//!JBWM_KEY_COMBOS_H 22 | -------------------------------------------------------------------------------- /key_event.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2020, Alisa Bedard */ 2 | /* Module: */ 3 | #include "key_event.h" 4 | /* Local: */ 5 | #include "JBWMClient.h" 6 | #include "JBWMKeys.h" 7 | #include "JBWMScreen.h" 8 | #include "client.h" 9 | #include "config.h" 10 | #include "drag.h" 11 | #include "exec.h" 12 | #include "log.h" 13 | #include "max.h" 14 | #include "move_resize.h" 15 | #include "select.h" 16 | #include "snap.h" 17 | #include "title_bar.h" 18 | #include "vdesk.h" 19 | #include "wm_state.h" 20 | /* System: */ 21 | #include 22 | #include 23 | /* Program: */ 24 | __attribute__((nonnull)) 25 | static void point(struct JBWMClient * c, 26 | const int16_t x, const int16_t y) 27 | { 28 | Display * d = c->screen->xlib->display; 29 | XRaiseWindow(d, c->parent); 30 | jbwm_warp(d, c->window, x, y); 31 | } 32 | __attribute__((nonnull)) 33 | static void commit_key_move(struct JBWMClient * c) 34 | { 35 | jbwm_snap_border(c); 36 | jbwm_move_resize(c); 37 | point(c, 1, 1); 38 | } 39 | enum KeyMoveFlags { 40 | KEY_MOVE_HORIZONTAL = 1, 41 | KEY_MOVE_POSITIVE = 2, 42 | KEY_MOVE_MODIFIER = 4 43 | }; 44 | static inline bool can_resize(struct JBWMClientOptions * opt) 45 | { 46 | return !opt->shaped && !opt->no_resize; 47 | } 48 | static inline bool has_sufficient_size(const int value) 49 | { 50 | return value > JBWM_RESIZE_INCREMENT << 1; 51 | } 52 | static int16_t * get_antecedent(struct JBWMClient * c, const 53 | uint8_t flags) 54 | { 55 | int16_t * ret; 56 | union JBWMRectangle * s = &c->size; 57 | int16_t * wh = flags & KEY_MOVE_HORIZONTAL ? &s->width : &s->height; 58 | if((flags & KEY_MOVE_MODIFIER) && has_sufficient_size(*wh) 59 | && can_resize(&c->opt)) 60 | ret = wh; 61 | else 62 | ret = (flags & KEY_MOVE_HORIZONTAL ? &s->x : &s->y); 63 | return ret; 64 | } 65 | __attribute__((nonnull)) 66 | static void key_move(struct JBWMClient * c, uint8_t const flags) 67 | { 68 | int8_t const d = flags & KEY_MOVE_POSITIVE 69 | ? JBWM_RESIZE_INCREMENT : - JBWM_RESIZE_INCREMENT; 70 | *get_antecedent(c, flags) += d; 71 | commit_key_move(c); 72 | } 73 | static uint8_t get_move_flags(const KeySym k, const bool mod) 74 | { 75 | uint8_t flags = (mod ? KEY_MOVE_MODIFIER : 0) | KEY_MOVE_POSITIVE; 76 | switch (k) { 77 | case JBWM_KEY_LEFT: 78 | flags &= ~KEY_MOVE_POSITIVE; 79 | /* FALLTHROUGH */ 80 | case JBWM_KEY_RIGHT: 81 | flags |= KEY_MOVE_HORIZONTAL; 82 | break; 83 | case JBWM_KEY_UP: 84 | flags &= ~KEY_MOVE_POSITIVE; 85 | } 86 | return flags; 87 | } 88 | static void handle_key_move(struct JBWMClient * c, 89 | const KeySym k, const bool mod) 90 | { 91 | /* These operations invalid when fullscreen. */ 92 | if (c->opt.fullscreen) 93 | return; 94 | key_move(c, get_move_flags(k, mod)); 95 | } 96 | static void toggle_maximize(struct JBWMClient * c) 97 | { 98 | const struct JBWMClientOptions o = c->opt; 99 | /* Honor mwm hints. Do not maximize shaped windows. */ 100 | /* Ignore fullscreen windows. Let the fullscreen code handle them. */ 101 | if (!o.no_max && !o.fullscreen && !o.shaped) { 102 | if (o.max_horz && o.max_vert) { 103 | jbwm_set_not_horz(c); 104 | jbwm_set_not_vert(c); 105 | } else { 106 | jbwm_set_horz(c); 107 | jbwm_set_vert(c); 108 | } 109 | } 110 | } 111 | __attribute__((nonnull)) 112 | static void handle_client_key_event(struct JBWMClient ** head_client, 113 | struct JBWMClient ** current_client, 114 | const bool mod, const KeySym key) 115 | { 116 | struct JBWMClient * c; 117 | JBWM_LOG("handle_client_key_event: %d", (int)key); 118 | c=*current_client; 119 | if (c) { 120 | if (c->opt.fullscreen) { 121 | /* only allow exiting from fullscreen */ 122 | if (key == JBWM_KEY_FS) 123 | jbwm_set_not_fullscreen(c); 124 | return; /* prevent other operations while fullscreen */ 125 | } 126 | switch (key) { 127 | case JBWM_KEY_LEFT: 128 | case JBWM_KEY_RIGHT: 129 | case JBWM_KEY_UP: 130 | case JBWM_KEY_DOWN: 131 | handle_key_move(c, key, mod); 132 | break; 133 | case JBWM_KEY_KILL: 134 | jbwm_send_wm_delete(c); 135 | break; 136 | case JBWM_KEY_LOWER: 137 | case JBWM_KEY_ALTLOWER: 138 | XLowerWindow(c->screen->xlib->display, c->parent); 139 | break; 140 | case JBWM_KEY_RAISE: 141 | XRaiseWindow(c->screen->xlib->display, c->parent); 142 | break; 143 | case JBWM_KEY_FS: 144 | jbwm_set_fullscreen(c); 145 | break; 146 | case JBWM_KEY_MAX: 147 | toggle_maximize(c); 148 | break; 149 | case JBWM_KEY_MAX_H: 150 | (c->opt.max_horz ? jbwm_set_not_horz : jbwm_set_horz)(c); 151 | break; 152 | case JBWM_KEY_MAX_V: 153 | (c->opt.max_vert ? jbwm_set_not_vert : jbwm_set_vert)(c); 154 | break; 155 | case JBWM_KEY_STICK: 156 | jbwm_toggle_sticky(c, current_client); 157 | break; 158 | case JBWM_KEY_MOVE: 159 | jbwm_drag(c, head_client, false); 160 | break; 161 | case JBWM_KEY_SHADE: 162 | jbwm_toggle_shade(c); 163 | break; 164 | } 165 | } 166 | } 167 | static void next(struct JBWMClient * c, 168 | struct JBWMClient ** current_client, struct JBWMClient ** head_client, 169 | uint8_t const v){ 170 | if(!c->next) 171 | c=*(head_client); 172 | else 173 | c=c->next; 174 | if (c!=*current_client) { /* prevent infinite recursion with dessktop */ 175 | if(c->vdesk != v) { 176 | next(c, current_client, head_client, v); 177 | } else { 178 | point(c, 0, 0); 179 | point(c, c->size.width-1, c->size.height-1); 180 | jbwm_select_client(c, current_client); 181 | } 182 | } 183 | } 184 | static void cond_set_vdesk(struct JBWMClient * c, 185 | struct JBWMClient * head_client, 186 | struct JBWMScreen * s, const uint8_t desktop, const bool mod) 187 | { 188 | if (mod && c) 189 | jbwm_set_client_vdesk(c, desktop); 190 | else 191 | jbwm_set_vdesk(s, head_client, desktop); 192 | } 193 | void jbwm_handle_key_event(struct JBWMScreen * s, struct JBWMClient * target, 194 | struct JBWMClient ** head_client, struct JBWMClient ** current_client, 195 | XKeyEvent * e) 196 | { 197 | enum { MOD = 1 << 0, ZERO = 1 << 1, VDESK_ROW_INCREMENT=16}; 198 | uint8_t flags; 199 | const KeySym key = XLookupKeysym(e, 0); 200 | flags = e->state & JBWM_KEYMASK_MOD ? MOD : 0; 201 | JBWM_LOG("jbwm_handle_key_event mod: %d", flags); 202 | switch (key) { 203 | case JBWM_KEY_NEW: 204 | jbwm_exec(JBWM_TERM); 205 | break; 206 | case JBWM_KEY_QUIT: 207 | exit(0); 208 | case JBWM_KEY_NEXT: 209 | if(*current_client) 210 | next(*current_client, current_client, head_client, s->vdesk); 211 | break; 212 | case JBWM_KEY_0: 213 | flags |= ZERO; 214 | /* FALLTHROUGH */ 215 | case JBWM_KEY_1: 216 | case JBWM_KEY_2: 217 | case JBWM_KEY_3: 218 | case JBWM_KEY_4: 219 | case JBWM_KEY_5: 220 | case JBWM_KEY_6: 221 | case JBWM_KEY_7: 222 | case JBWM_KEY_8: 223 | case JBWM_KEY_9: 224 | /* First desktop 0, per wm-spec */ 225 | cond_set_vdesk(target, *head_client, s, flags & ZERO 226 | ? 10 : key - JBWM_KEY_1, flags & MOD); 227 | break; 228 | case JBWM_KEY_PREVDESK: 229 | cond_set_vdesk(target, *head_client, s, s->vdesk - 1, flags & MOD); 230 | break; 231 | case JBWM_KEY_NEXTDESK: 232 | cond_set_vdesk(target, *head_client, s, s->vdesk + 1, flags & MOD); 233 | break; 234 | case JBWM_KEY_VDESK_NEXT_ROW: 235 | cond_set_vdesk(target, *head_client, s, 236 | s->vdesk - VDESK_ROW_INCREMENT, flags & MOD); 237 | break; 238 | case JBWM_KEY_VDESK_PREV_ROW: 239 | cond_set_vdesk(target, *head_client, s, 240 | s->vdesk + VDESK_ROW_INCREMENT, flags & MOD); 241 | break; 242 | default: 243 | if (!target) 244 | target = *current_client; 245 | if (!target) 246 | target = *head_client; 247 | if (target) { 248 | handle_client_key_event(head_client, current_client, flags & MOD, key); 249 | #ifdef DEBUG 250 | } else { 251 | JBWM_LOG("target is NULL"); 252 | #endif // DEBUG 253 | } 254 | } 255 | } 256 | -------------------------------------------------------------------------------- /key_event.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #ifndef JBWM_KEY_EVENT_H 3 | #define JBWM_KEY_EVENT_H 4 | #include 5 | struct JBWMClient; 6 | struct JBWMScreen; 7 | void jbwm_handle_key_event(struct JBWMScreen *s, struct JBWMClient * target, 8 | struct JBWMClient ** head_client, struct JBWMClient ** current_client, 9 | XKeyEvent * e); 10 | #endif//!JBWM_KEY_EVENT_H 11 | -------------------------------------------------------------------------------- /keys.c: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #include "keys.h" 6 | // 7 | #include "JBWMKeys.h" 8 | #include "config.h" 9 | // 10 | #include 11 | // 12 | __attribute__((nonnull(1,2))) 13 | static void grab_r(Display * d, KeySym const * k, 14 | Window const r, uint32_t const mask) 15 | { 16 | if (*k) { // Terminate at KeySym 0 17 | XGrabKey(d, XKeysymToKeycode(d, *k), mask, r, True, 18 | GrabModeAsync, GrabModeAsync); 19 | grab_r(d, k + 1, r, mask); 20 | } 21 | } 22 | void jbwm_grab_root_keys(Display * d, Window const root) 23 | { 24 | grab_r(d, (KeySym[]){JBWM_KEYS_TO_GRAB}, root, JBWM_KEYMASK_GRAB); 25 | grab_r(d, (KeySym[]){JBWM_KEYS_TO_GRAB}, root, JBWM_KEYMASK_GRAB | LockMask); 26 | grab_r(d, (KeySym[]){JBWM_KEYS_TO_GRAB}, root, JBWM_KEYMASK_GRAB | Mod3Mask); 27 | grab_r(d, (KeySym[]){JBWM_ALT_KEYS_TO_GRAB}, root, JBWM_KEYMASK_GRAB 28 | | JBWM_KEYMASK_MOD); 29 | grab_r(d, (KeySym[]){JBWM_ALT_KEYS_TO_GRAB}, root, JBWM_KEYMASK_GRAB 30 | | JBWM_KEYMASK_MOD | LockMask); 31 | grab_r(d, (KeySym[]){JBWM_ALT_KEYS_TO_GRAB}, root, JBWM_KEYMASK_GRAB 32 | | JBWM_KEYMASK_MOD | Mod3Mask); 33 | } 34 | -------------------------------------------------------------------------------- /keys.h: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #ifndef JBWM_KEYS_H 6 | #define JBWM_KEYS_H 7 | #include 8 | void jbwm_grab_root_keys(Display * d, const Window root) 9 | __attribute__((nonnull)); 10 | #endif//!JBWM_KEYS_H 11 | -------------------------------------------------------------------------------- /keys.txt: -------------------------------------------------------------------------------- 1 | ALTLOWER:minus 2 | BOTTOMLEFT:KP_End 3 | BOTTOMRIGHT:KP_Page_Down 4 | DOWN:j 5 | DOWN_UP:J 6 | FS:a 7 | INFO:F5 8 | LEFT:h 9 | LEFT_UP:H 10 | LOWER:Down 11 | MAX_H:x 12 | MAX:space 13 | MAX_V:z 14 | MOVE:m 15 | NEW:Return 16 | NEXTDESK:Right 17 | NEXT:Tab 18 | PREVDESK:Left 19 | QUIT:Escape 20 | RAISE:Up 21 | RIGHT:l 22 | RIGHT_UP:L 23 | SHADE:s 24 | STICK:period 25 | TOPLEFT:KP_Home 26 | TOPRIGHT:KP_Page_Up 27 | UP:k 28 | UP_UP:K 29 | -------------------------------------------------------------------------------- /log.h: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #ifndef JBWM_LOG_H 6 | #define JBWM_LOG_H 7 | #ifdef DEBUG 8 | #include 9 | #define JBWM_LOG(...)\ 10 | {\ 11 | fprintf(stderr, "%s:%d:%s: ", __FILE__, __LINE__,__FUNCTION__);\ 12 | fprintf(stderr, __VA_ARGS__);\ 13 | fprintf(stderr, "\n");\ 14 | } 15 | #else//!DEBUG 16 | #define JBWM_LOG(...) 17 | #endif//DEBUG 18 | #endif//!JBWM_LOG_H 19 | -------------------------------------------------------------------------------- /macros.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #ifndef LIBJB_MACROS_H 3 | #define LIBJB_MACROS_H 4 | #define JB_MAX(a,b) ((a) > (b) ? (a) : (b)) 5 | #define JB_MIN(a,b) ((a) < (b) ? (a) : (b)) 6 | #define JB_LIMIT(var, max, min) var = JB_MAX(JB_MIN(var, max), min); 7 | #define JB_SWAP(type, a, b) {type c = a; a = b; b = c;} 8 | #define JB_LIKELY(x) __builtin_expect((x), true) 9 | #define JB_UNLIKELY(x) __builtin_expect((x), false) 10 | #endif//!LIBJB_MACROS_H 11 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #include 6 | #include "JBWMScreen.h" 7 | #include "atom.h" 8 | #include "command_line.h" 9 | #include "display.h" 10 | #include "events.h" 11 | #include "font.h" 12 | #include "jbwm.h" 13 | int main(int argc, char **argv) 14 | { 15 | Display * d; 16 | jbwm_parse_command_line(argc, argv); 17 | d = jbwm_open_display(); 18 | jbwm_create_atoms(d); 19 | jbwm_open_font(d); 20 | { 21 | struct JBWMClient *current_client, *head_client; 22 | uint8_t const n = ScreenCount(d); 23 | // allocate using dynamically sized array on stack 24 | struct JBWMScreen s[n]; // remains in scope till exit. 25 | memset(s,0,sizeof(s)); 26 | current_client=NULL; // no clients added yet 27 | head_client=NULL; // flag as empty list 28 | jbwm_set_up_error_handler(&head_client, ¤t_client); 29 | jbwm_init_screens(d, s, &head_client, ¤t_client, 30 | n - 1); // -1 for index 31 | jbwm_events_loop(s,&head_client,¤t_client); // does not return 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /max.c: -------------------------------------------------------------------------------- 1 | // Copyright 2017-2019, Alisa Bedard 2 | #include "max.h" 3 | #include "ewmh.h" 4 | #include "ewmh_state.h" 5 | #include "font.h" 6 | #include "atom.h" 7 | #include "JBWMClient.h" 8 | #include "move_resize.h" 9 | #include "title_bar.h" 10 | /* In this file, the static companion functions perform the requested option 11 | directly, while the global functions call the corresponding static 12 | function and perform sanity checks and adjustments. */ 13 | static void set_not_horz(struct JBWMClient * c) 14 | { 15 | Display *d; 16 | c->opt.max_horz = false; 17 | c->size.x = c->old_size.x; 18 | c->size.width = c->old_size.width; 19 | d=c->screen->xlib->display; 20 | jbwm_ewmh_remove_state(d, c->window, 21 | jbwm_atoms[JBWM_NET_WM_STATE_MAXIMIZED_HORZ]); 22 | } 23 | void jbwm_set_not_horz(struct JBWMClient * c) 24 | { 25 | if (c->opt.max_horz) 26 | set_not_horz(c); 27 | jbwm_move_resize(c); 28 | } 29 | static void set_horz(struct JBWMClient * c, 30 | const uint16_t display_width) 31 | { 32 | c->opt.max_horz = true; 33 | c->old_size.x = c->size.x; 34 | c->old_size.width = c->size.width; 35 | c->size.x = 0; 36 | c->size.width = display_width; 37 | } 38 | void jbwm_set_horz(struct JBWMClient * c) 39 | { 40 | Display *d; 41 | if (c->opt.max_horz) 42 | return; 43 | d=c->screen->xlib->display; 44 | jbwm_ewmh_add_state(d, c->window, 45 | jbwm_atoms[JBWM_NET_WM_STATE_MAXIMIZED_HORZ]); 46 | set_horz(c, DisplayWidth(d, c->screen->id)); 47 | c->size.width -= c->opt.border << 1; 48 | jbwm_move_resize(c); 49 | } 50 | static void set_not_vert(struct JBWMClient * c) 51 | { 52 | Display *d; 53 | c->opt.max_vert = false; 54 | c->size.y = c->old_size.y; 55 | c->size.height = c->old_size.height; 56 | d=c->screen->xlib->display; 57 | jbwm_ewmh_remove_state(d, c->window, 58 | jbwm_atoms[JBWM_NET_WM_STATE_MAXIMIZED_VERT]); 59 | } 60 | void jbwm_set_not_vert(struct JBWMClient * c) 61 | { 62 | if (c->opt.max_vert && !c->opt.shaded) 63 | set_not_vert(c); 64 | jbwm_move_resize(c); 65 | } 66 | static void set_vert(struct JBWMClient * c) 67 | { 68 | Display *d; 69 | c->opt.max_vert = true; 70 | c->old_size.y = c->size.y; 71 | c->old_size.height = c->size.height; 72 | c->size.y = 0; 73 | d=c->screen->xlib->display; 74 | c->size.height = DisplayHeight(d, c->screen->id); 75 | jbwm_ewmh_add_state(d, c->window, 76 | jbwm_atoms[JBWM_NET_WM_STATE_MAXIMIZED_VERT]); 77 | } 78 | void jbwm_set_vert(struct JBWMClient * c) 79 | { 80 | if (c->opt.max_vert || c->opt.shaded) 81 | return; 82 | set_vert(c); 83 | // Offset to hide borders: 84 | const uint8_t b = c->opt.border; 85 | c->size.height -= b << 1; 86 | if (!c->opt.no_title_bar) { 87 | uint8_t const fh=c->screen->font_height; 88 | c->size.y += fh + b; 89 | c->size.height -= fh + (b << 1); 90 | } 91 | jbwm_move_resize(c); 92 | } 93 | static void set_not_fullscreen(struct JBWMClient * c) 94 | { 95 | c->opt.fullscreen = false; 96 | c->size = c->before_fullscreen; 97 | Display * d = c->screen->xlib->display; 98 | XSetWindowBorderWidth(d, c->parent, c->opt.border); 99 | jbwm_ewmh_remove_state(d, c->window, 100 | jbwm_atoms[JBWM_NET_WM_STATE_FULLSCREEN]); 101 | jbwm_update_title_bar(c); 102 | } 103 | void jbwm_set_not_fullscreen(struct JBWMClient * c) 104 | { 105 | if(c->opt.fullscreen) 106 | set_not_fullscreen(c); 107 | jbwm_move_resize(c); 108 | } 109 | static void set_fullscreen(struct JBWMClient * c) 110 | { 111 | Display *d; 112 | const uint8_t id = c->screen->id; 113 | c->opt.fullscreen = true; 114 | c->before_fullscreen = c->size; 115 | c->size.x = c->size.y = 0; 116 | d = c->screen->xlib->display; 117 | c->size.width = DisplayWidth(d, id); 118 | c->size.height = DisplayHeight(d, id); 119 | XSetWindowBorderWidth(d, c->parent, 0); 120 | jbwm_ewmh_add_state(d, c->window, 121 | jbwm_atoms[JBWM_NET_WM_STATE_FULLSCREEN]); 122 | jbwm_update_title_bar(c); 123 | } 124 | void jbwm_set_fullscreen(struct JBWMClient * c) 125 | { 126 | if (c->opt.fullscreen || c->opt.shaded || c->opt.no_max) 127 | return; 128 | set_fullscreen(c); 129 | jbwm_move_resize(c); 130 | } 131 | -------------------------------------------------------------------------------- /max.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #ifndef JBWM_MAX_H 3 | #define JBWM_MAX_H 4 | #include 5 | struct JBWMClient; 6 | void jbwm_set_horz(struct JBWMClient * c) 7 | __attribute__((nonnull)); 8 | void jbwm_set_not_horz(struct JBWMClient * c) 9 | __attribute__((nonnull)); 10 | void jbwm_set_vert(struct JBWMClient * c) 11 | __attribute__((nonnull)); 12 | void jbwm_set_not_vert(struct JBWMClient * c) 13 | __attribute__((nonnull)); 14 | void jbwm_set_fullscreen(struct JBWMClient * c) 15 | __attribute__((nonnull)); 16 | void jbwm_set_not_fullscreen(struct JBWMClient * c) 17 | __attribute__((nonnull)); 18 | #endif//!JBWM_MAX_H 19 | -------------------------------------------------------------------------------- /mkdep.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | OUT=depend.mk 3 | rm -f $OUT 4 | for SRC in *.c; do 5 | LINE="`basename $SRC .c`.o: $SRC" 6 | for DEP in `fgrep '#include "' $SRC \ 7 | | cut -d' ' -f2 \ 8 | | tr -d \" `; do 9 | LINE="$LINE $DEP" 10 | done 11 | echo $LINE >> $OUT 12 | done 13 | 14 | -------------------------------------------------------------------------------- /move_resize.c: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #include "move_resize.h" 6 | #include "JBWMClient.h" 7 | #include "font.h" 8 | #include "log.h" 9 | #include "mwm.h" 10 | #include "shape.h" 11 | #include "title_bar.h" 12 | static void jbwm_configure_client(struct JBWMClient * c) 13 | { 14 | if (!c) // prevent segmentation fault 15 | return; 16 | const Window w = c->window; 17 | union JBWMRectangle * g = &c->size; 18 | XSendEvent(c->screen->xlib->display, w, true, StructureNotifyMask, (XEvent 19 | *) &(XConfigureEvent){.x = g->x, .y = g->y, .width = g->width, 20 | .height = g->height, .type = ConfigureNotify, .event = w, 21 | .window = w, .above = c->parent, .override_redirect = true, 22 | .border_width = c->opt.border}); 23 | } 24 | static void do_move(Display * d, const Window parent, 25 | const Window window, union JBWMRectangle * sz, 26 | const uint8_t offset) 27 | { 28 | XMoveResizeWindow(d, parent, sz->x, sz->y - offset, 29 | sz->width, sz->height + offset); 30 | XMoveResizeWindow(d, window, 0, offset, 31 | sz->width, sz->height); 32 | } 33 | void jbwm_move_resize(struct JBWMClient * c) 34 | { 35 | struct JBWMClientOptions * o = &c->opt; 36 | const uint8_t offset = o->no_title_bar || o->fullscreen 37 | ? 0 : c->screen->font_height; 38 | if(offset) { // Leave braces in case title bar support was disabled. 39 | jbwm_handle_mwm_hints(c); 40 | jbwm_update_title_bar(c); 41 | } // Skip shaped and fullscreen clients. 42 | union JBWMRectangle * s = &c->size; 43 | do_move(c->screen->xlib->display, c->parent, c->window, s, offset); 44 | jbwm_set_shape(c); 45 | jbwm_configure_client(c); 46 | } 47 | 48 | -------------------------------------------------------------------------------- /move_resize.h: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #ifndef JBWM_MOVE_RESIZE_H 6 | #define JBWM_MOVE_RESIZE_H 7 | struct JBWMClient; 8 | void jbwm_move_resize(struct JBWMClient * c); 9 | #endif//!JBWM_MOVE_RESIZE_H 10 | -------------------------------------------------------------------------------- /mwm.c: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #include "mwm.h" 6 | #include "ewmh.h" 7 | #include "atom.h" 8 | #include "JBWMClient.h" 9 | #include "log.h" 10 | #include "mwmproto.h" 11 | #include "util.h" 12 | static void process_flags(struct JBWMClientOptions * o) 13 | { 14 | if (o->tearoff) { 15 | o->no_resize = o->no_shade = o->no_max 16 | = o->no_title_bar = true; 17 | o->border = 0; 18 | } 19 | } 20 | static void do_functions(struct JBWMClientOptions * o, 21 | const enum MwmFunctions f) 22 | { 23 | o->no_close = !(f & MWM_FUNC_CLOSE); 24 | o->no_max = !(f & MWM_FUNC_MAXIMIZE); 25 | o->no_move = !(f & MWM_FUNC_MOVE); 26 | o->no_resize = !(f & MWM_FUNC_RESIZE); 27 | o->no_shade = !(f & MWM_FUNC_MINIMIZE); 28 | } 29 | static void do_decorations(struct JBWMClientOptions * o, 30 | const enum MwmDecor f) 31 | { 32 | o->border = f & MWM_DECOR_BORDER ? 1 : 0; 33 | o->no_close = !(f & MWM_DECOR_MENU); 34 | o->no_max = !(f & MWM_DECOR_MAXIMIZE); 35 | o->no_resize = !(f & MWM_DECOR_RESIZEH); 36 | o->no_shade = !(f & MWM_DECOR_MINIMIZE); 37 | o->no_title_bar = !(f & MWM_DECOR_TITLE); 38 | } 39 | void jbwm_handle_mwm_hints(struct JBWMClient * c) 40 | { 41 | Display * d = c->screen->xlib->display; 42 | const Atom mwm_hints = jbwm_atoms[JBWM_MOTIF_WM_HINTS]; 43 | struct JBWMMwm * m = jbwm_get_property(d, c->window, 44 | mwm_hints, &(uint16_t){0}); 45 | if (m) { // property successfully retrieved 46 | struct JBWMClientOptions * o = &c->opt; 47 | if (!((c->opt.tearoff = m->flags 48 | & MWM_HINTS_STATUS && m->status & 49 | MWM_TEAROFF_WINDOW))) { 50 | // skip the following if tear-off window 51 | if (m->flags & MWM_HINTS_FUNCTIONS 52 | && !(m->functions & MWM_FUNC_ALL)) 53 | do_functions(o, m->functions); 54 | if (m->flags & MWM_HINTS_DECORATIONS 55 | && !(m->decor & MWM_DECOR_ALL)) 56 | do_decorations(o, m->decor); 57 | } 58 | XFree(m); 59 | process_flags(o); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /mwm.h: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #ifndef JBWM_MWM_H 6 | #define JBWM_MWM_H 7 | struct JBWMClient; 8 | void jbwm_handle_mwm_hints(struct JBWMClient * c); 9 | #endif//!JBWM_MWM_H 10 | -------------------------------------------------------------------------------- /mwm.mk: -------------------------------------------------------------------------------- 1 | # Copyright 2019, Alisa Bedard 2 | # MWM hints support 3 | jbwm_cflags+=-DJBWM_USE_MWM 4 | objects+=mwm.o 5 | -------------------------------------------------------------------------------- /mwmproto.h: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2020, Alisa Bedard 3 | #ifndef JBWM_MWMPROTO_H 4 | #define JBWM_MWMPROTO_H 5 | // These are MWM-specific hints 6 | enum MwmFlags { 7 | // flags: 8 | MWM_HINTS_FUNCTIONS = (1L << 0), MWM_HINTS_DECORATIONS = (1L << 1), 9 | MWM_HINTS_INPUT_MODE = (1L << 2), MWM_HINTS_STATUS = (1L << 3) 10 | }; 11 | enum MwmFunctions { 12 | // functions: 13 | MWM_FUNC_ALL = (1L << 0), MWM_FUNC_RESIZE = (1L << 1), 14 | MWM_FUNC_MOVE = (1L << 2), MWM_FUNC_MINIMIZE = (1L << 3), 15 | MWM_FUNC_MAXIMIZE = (1L << 4), MWM_FUNC_CLOSE = (1L << 5), 16 | }; 17 | enum MwmDecor { 18 | // decor: 19 | MWM_DECOR_ALL = (1L << 0), MWM_DECOR_BORDER = (1L << 1), 20 | MWM_DECOR_RESIZEH = (1L << 2), MWM_DECOR_TITLE = (1L << 3), 21 | MWM_DECOR_MENU = (1L << 4), MWM_DECOR_MINIMIZE = (1L << 5), 22 | MWM_DECOR_MAXIMIZE = (1L << 6), 23 | }; 24 | enum MwmStatus { 25 | // status: 26 | MWM_TEAROFF_WINDOW = 1 27 | }; 28 | struct JBWMMwm { // paraphrased from MwmUtil.h 29 | unsigned long flags, functions, decor; 30 | long input_mode; 31 | unsigned long status; 32 | }; 33 | #endif//!JBWM_MWMPROTO_H 34 | -------------------------------------------------------------------------------- /new.c: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #include "new.h" 6 | #include "client.h" 7 | #include "config.h" // for JBWM_MAX_DESKTOPS 8 | #include "ewmh.h" 9 | #include "geometry.h" 10 | #include "atom.h" 11 | #include "JBWMClient.h" 12 | //#include "keys.h" 13 | #include "log.h" // for JBWM_LOG 14 | #include "mwm.h" // for jbwm_handle_mwm_hints 15 | #include "select.h" 16 | #include "shape.h" // for jbwm_new_shaped_client 17 | #include "snap.h" 18 | #include 19 | #include "util.h" 20 | #include "vdesk.h" 21 | #include // for XA_CARDINAL 22 | static uint8_t wm_desktop(Display * d, const Window w, uint8_t vdesk) 23 | { 24 | uint16_t n; 25 | const Atom a = jbwm_atoms[JBWM_NET_WM_DESKTOP]; 26 | unsigned long *lprop = jbwm_get_property(d, w, a, &n); 27 | if (lprop) { // See if client has a preferred desktop (as on restart) 28 | if (n) // is valid 29 | vdesk = (uint8_t)lprop[0]; // Set vdesk to property value 30 | XFree(lprop); 31 | } 32 | // Set the property in any case to ensure it exists henceforth. 33 | XChangeProperty(d, w, a, XA_CARDINAL, 8, PropModeReplace, 34 | (unsigned char *)&vdesk, 1); 35 | JBWM_LOG("wm_desktop(w: %d): vdesk is %d\n", (int) w, vdesk); 36 | return vdesk; 37 | } 38 | static inline uint8_t get_vdesk(struct JBWMClient * c) 39 | { 40 | return wm_desktop(c->screen->xlib->display, c->window, c->screen->vdesk); 41 | } 42 | __attribute__((nonnull)) 43 | static Window get_parent(struct JBWMClient * c) 44 | { 45 | enum { 46 | CFP = CopyFromParent, 47 | CW_VM = CWOverrideRedirect | CWEventMask, 48 | WA_EM = SubstructureRedirectMask | SubstructureNotifyMask | 49 | ButtonPressMask | EnterWindowMask 50 | }; 51 | union JBWMRectangle * g; 52 | g = &c->size; 53 | return XCreateWindow(c->screen->xlib->display, c->screen->xlib->root, 54 | g->x, g->y, g->width, g->height, c->opt.border, CFP, CFP, 55 | NULL, CW_VM, &(XSetWindowAttributes){ 56 | .event_mask = WA_EM, 57 | .override_redirect=true 58 | }); 59 | } 60 | static inline void reparent_window(Display * d, Window parent, Window window) 61 | { 62 | XAddToSaveSet(d, window); 63 | XReparentWindow(d, window, parent, 0, 0); 64 | XMapWindow(d, window); 65 | } 66 | static inline void reparent(struct JBWMClient * c) 67 | { 68 | JBWM_LOG("reparent()"); 69 | jbwm_new_shaped_client(c); 70 | reparent_window(c->screen->xlib->display, c->parent = get_parent(c), c->window); 71 | // Required by wm-spec: 72 | jbwm_set_frame_extents(c); 73 | } 74 | // Allocate the client structure with some defaults set 75 | static struct JBWMClient * get_JBWMClient(const Window w, 76 | struct JBWMScreen * s) 77 | { 78 | struct JBWMClient * c = calloc(1, sizeof(struct JBWMClient)); 79 | c->screen=s; 80 | c->window=w; 81 | c->opt.border = 1; 82 | return c; 83 | } 84 | // Grab input and setup ewmh hints for client window 85 | static void do_grabs(Display * d, const Window w) 86 | { 87 | // jbwm_ewmh_set_allowed_actions must come before jbwm_grab_buttons. 88 | jbwm_ewmh_set_allowed_actions(d, w); 89 | XSelectInput(d, w, EnterWindowMask | PropertyChangeMask 90 | | ColormapChangeMask); 91 | // keys to grab: 92 | jbwm_grab_button(d, w, JBWM_KEYMASK_GRAB);//jbwm_get_grab_mask()); 93 | } 94 | void jbwm_new_client(struct JBWMScreen * s, 95 | struct JBWMClient ** head_client, 96 | struct JBWMClient ** current_client, 97 | Window const w) 98 | { 99 | struct JBWMClient * c = get_JBWMClient(w, s); 100 | JBWM_LOG("jbwm_new_client(..., w: %d)", (int)w); 101 | /* Prepend client. */ 102 | c->next=*head_client; 103 | *head_client=c; 104 | do_grabs(s->xlib->display, w); 105 | jbwm_set_client_geometry(c); 106 | jbwm_handle_mwm_hints(c); 107 | reparent(c); 108 | c->vdesk = get_vdesk(c); 109 | jbwm_snap_client(c, head_client); 110 | jbwm_restore_client(c); 111 | jbwm_select_client(c, current_client); 112 | if(c->screen->vdesk!=c->vdesk) 113 | jbwm_hide_client(c); 114 | } 115 | -------------------------------------------------------------------------------- /new.h: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #ifndef JBWM_NEW_H 6 | #define JBWM_NEW_H 7 | #include 8 | struct JBWMClient; 9 | struct JBWMScreen; 10 | void jbwm_new_client(struct JBWMScreen * s, struct JBWMClient **head_client, 11 | struct JBWMClient ** current_client, Window const w); 12 | #endif//!JBWM_NEW_H 13 | -------------------------------------------------------------------------------- /pixel_t.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #ifndef JBWM_PIXEL_T_H 3 | #define JBWM_PIXEL_T_H 4 | #include 5 | typedef uint32_t jbwm_pixel_t; 6 | #endif//!JBWM_PIXEL_T_H 7 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alisabedard/jbwm/8cfef121a598d3d0629bdb591544e5347f82ef4f/screenshot.png -------------------------------------------------------------------------------- /select.c: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #include "select.h" 6 | #include 7 | #include 8 | #include "client.h" 9 | #include "ewmh.h" 10 | #include "ewmh_state.h" 11 | #include "atom.h" 12 | #include "JBWMClient.h" 13 | #include "util.h" 14 | #define WM_STATE(a) EWMH_ATOM(WM_STATE_##a) 15 | static inline jbwm_pixel_t get_bg(struct JBWMClient * c) 16 | { 17 | return c->screen->pixels.bg; 18 | } 19 | static void set_state_not_focused(struct JBWMClient * c) 20 | { 21 | Display *d=c->screen->xlib->display; 22 | XSetWindowBorder(d, c->parent, get_bg(c)); 23 | jbwm_ewmh_remove_state(d, c->window, XInternAtom(d, 24 | "_NET_WM_STATE_FOCUSED",false)); 25 | } 26 | static void set_border(struct JBWMClient * c) 27 | { 28 | struct JBWMPixels * p = &c->screen->pixels; 29 | XSetWindowBorder(c->screen->xlib->display, c->parent, 30 | c->opt.sticky ? p->fc : p->fg); 31 | } 32 | static void set_focused(struct JBWMClient * c) 33 | { 34 | Display * d = c->screen->xlib->display; 35 | XInstallColormap(d, c->cmap); 36 | const Window w = c->window; 37 | XSetInputFocus(d, w, RevertToPointerRoot, CurrentTime); 38 | jbwm_ewmh_add_state(d, w, jbwm_atoms[JBWM_NET_WM_STATE_FOCUSED]); 39 | } 40 | static void set_active_window_property(struct JBWMClient * c) 41 | { 42 | /* Store the window id as a static variable here in case 43 | * client c is freed before the X server handles the event. 44 | * If the property is read after the client is freed, it will 45 | * cause a segmentation fault. */ 46 | static Window w; 47 | Display *d; 48 | w = c->window; 49 | d=c->screen->xlib->display; 50 | XChangeProperty(d, c->screen->xlib->root, 51 | jbwm_atoms[JBWM_NET_ACTIVE_WINDOW], XA_WINDOW, 32, 52 | PropModeReplace, (unsigned char *)&w, 1); 53 | } 54 | void jbwm_select_client(struct JBWMClient * target, 55 | struct JBWMClient ** current_client) 56 | { 57 | struct JBWMClient * prev; 58 | prev = *current_client; 59 | set_border(target); 60 | set_focused(target); 61 | set_active_window_property(target); 62 | *current_client = target; 63 | if (prev != target) { 64 | if (prev) 65 | set_state_not_focused(prev); 66 | } 67 | } 68 | 69 | -------------------------------------------------------------------------------- /select.h: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #ifndef JBWM_SELECT_H 6 | #define JBWM_SELECT_H 7 | struct JBWMClient; 8 | // Set client as that receiving focus 9 | void jbwm_select_client(struct JBWMClient * target, 10 | struct JBWMClient ** current_client); 11 | #endif//!JBWM_SELECT_H 12 | -------------------------------------------------------------------------------- /shape.c: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #include "shape.h" 6 | #include 7 | #include "JBWMClient.h" 8 | #include "log.h" 9 | // Declared with pure attribute, as value may not change between calls. 10 | __attribute__((pure)) 11 | static bool is_shaped(Display * dpy, const Window win) 12 | { 13 | int s, d; 14 | unsigned int u; 15 | return XShapeQueryExtents(dpy, win, &s, &d, &d, 16 | &u, &u, &d, &d, &d, &u, &u) && s; 17 | } 18 | void jbwm_set_shape(struct JBWMClient * c) 19 | { 20 | if(c->opt.shaped) { 21 | JBWM_LOG("XShapeCombineShape: %d", (int)c->window); 22 | Display * d = c->screen->xlib->display; 23 | XFlush(d); 24 | XShapeCombineShape(d, c->parent, ShapeBounding, 25 | 1, 1, c->window, ShapeBounding, ShapeSet); 26 | } 27 | } 28 | void jbwm_new_shaped_client(struct JBWMClient * c) 29 | { 30 | if (is_shaped(c->screen->xlib->display, c->window)) { 31 | JBWM_LOG("Window %d is shaped", (int)c->window); 32 | struct JBWMClientOptions * o = &c->opt; 33 | o->no_title_bar = o->shaped = true; 34 | o->border = 0; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /shape.h: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #ifndef JBWM_SHAPE_H 6 | #define JBWM_SHAPE_H 7 | struct JBWMClient; 8 | void jbwm_new_shaped_client(struct JBWMClient * c); 9 | void jbwm_set_shape(struct JBWMClient * c); 10 | #endif//!JBWM_SHAPE_H 11 | -------------------------------------------------------------------------------- /snap.c: -------------------------------------------------------------------------------- 1 | /* jbwm - Minimalist Window Manager for X */ 2 | /* Copyright 2008-2020, Alisa Bedard */ 3 | /* Copyright 1999-2015, Ciaran Anscomb */ 4 | /* See README for license and other details. */ 5 | #include "snap.h" 6 | /***/ 7 | #include "config.h" 8 | #include "JBWMClient.h" 9 | #include "JBWMPoint.h" 10 | #include "JBWMSize.h" 11 | #include 12 | /***/ 13 | #ifdef JBWM_DEBUG_ABSMIN 14 | #include 15 | #endif/* JBWM_DEBUG_ABSMIN */ 16 | __attribute__ ((const, warn_unused_result)) 17 | static inline int16_t sborder(const int16_t xy, const int16_t edge) 18 | { 19 | int32_t r; 20 | #if defined(__i386__) || defined(__x86_64__) 21 | __asm__( 22 | "movw %%bx, %%ax\n\t" /* copy xy */ 23 | "addw %%cx, %%ax\n\t" /* xy + edge, preserve cx for later */ 24 | "movw %%ax, %%dx\n\t" /* copy result */ 25 | "negw %%ax\n\t" /* negate copy */ 26 | "cmovlw %%dx, %%ax\n\t" /* if negative copy, restore src - abs */ 27 | "negw %%cx\n\t" /* -edge */ 28 | "cmpw %1, %%ax\n\t" /* note reversed at&t operation order */ 29 | "cmovgew %%bx,%%cx\n\t" /* result is xy if >= */ 30 | : "=c" (r) 31 | : "i" (JBWM_SNAP), "b" (xy), "c" (edge) 32 | : "%ax", "%dx" /* scratch */ 33 | ); 34 | #else/* Portable version: */ 35 | r = abs(xy + edge) < JBWM_SNAP ? -edge : xy; 36 | #endif 37 | return r; 38 | } 39 | __attribute__((const)) 40 | static inline int16_t sborderdir(int16_t xy, int16_t const min, 41 | int16_t const max){ 42 | xy=sborder(xy,min); 43 | xy=sborder(xy,max); 44 | return xy; 45 | } 46 | void jbwm_snap_border(struct JBWMClient * c) 47 | { 48 | struct JBWMScreen *scr = c->screen; 49 | union JBWMRectangle * g = &(c->size); 50 | const struct JBWMSize s = {scr->xlib->width, 51 | scr->xlib->height}; 52 | const uint8_t b = c->opt.border << 1; 53 | /* snap to screen border */ 54 | g->x=sborderdir(g->x,0,g->width-s.width+b); 55 | g->y=sborderdir(g->y,(c->opt.no_title_bar^1)*-scr->font_height, 56 | g->height - s.height + b); 57 | } 58 | /* Definition of this as an inline function guarantees no side-effects 59 | * and minimizes over-expansion (the full expansion of jbwm_snap_dim 60 | * is approximately a dozen lines). */ 61 | __attribute__ ((const, warn_unused_result)) 62 | static inline int16_t absmin(int16_t const a, int16_t const b) 63 | { 64 | int16_t r; 65 | #if defined(__i386__) || defined(__x86_64__) 66 | __asm__( 67 | "movw %%ax, %%bx\n\t" /* save */ 68 | "negw %%ax\n\t" /* negate */ 69 | "cmovlw %%bx, %%ax\n\t" /* restore saved if negative */ 70 | "movw %%cx, %%dx\n\t" /* save */ 71 | "negw %%cx\n\t" /* negate */ 72 | "cmovlw %%dx, %%cx\n\t" /* restore saved if negative */ 73 | "cmpw %%ax, %%cx\n\t" /* abs(b)y-=font_height; 127 | geo->height+=font_height; 128 | } 129 | } 130 | /* Don't use for struct JBWMClient withing this function, as 131 | * c and ci may alias each other. Qualifier is fine for struct 132 | * JBWMRectangle. This is performance critical, scaling O(n) 133 | * relative to the number of windows, so leave iterative in definition to 134 | * avoid further overhead. */ 135 | static union JBWMPoint snap_search(struct JBWMClient * c, 136 | struct JBWMClient ** head_client) 137 | { 138 | union JBWMPoint d; 139 | union JBWMRectangle s = c->size; 140 | struct JBWMScreen *scr=c->screen; 141 | bool const ctb = !c->opt.no_title_bar; 142 | uint8_t const fh = scr->font_height; 143 | adjust_for_titlebar(&s,fh,ctb); 144 | d.x=d.y=JBWM_SNAP; 145 | for (struct JBWMClient * ci = *head_client; 146 | ci; ci = ci->next) { 147 | if ((ci != c) && (ci->screen == scr) 148 | && (ci->vdesk == c->vdesk)) { 149 | union JBWMRectangle gi = ci->size; 150 | bool const citb = !ci->opt.no_title_bar; 151 | adjust_for_titlebar(&gi,fh,citb); 152 | if(snap_cond(s.y, s.height, gi.y, gi.height)) 153 | d.x = jbwm_snap_dim(s.x, s.width, 154 | gi.x, gi.width, d.x); 155 | if(snap_cond(s.x, s.width, gi.x, gi.width)) 156 | d.y = jbwm_snap_dim(s.y, s.height, 157 | gi.y, gi.height, d.y); 158 | } 159 | } 160 | return d; 161 | } 162 | static inline void snap_dir(int16_t *out, int16_t diff){ 163 | #if defined(__i386__) || defined(__x86_64__) 164 | __asm__ ( 165 | "movw %%bx, %%ax\n\t" 166 | "negw %%ax\n\t" 167 | "cmovlw %%bx, %%ax\n\t" /* abs(bx) to ax */ 168 | "movw %%cx,%%dx\n\t" 169 | "addw %%bx,%%dx\n\t" 170 | "cmpw %1, %%ax\n\t" 171 | "cmovlw %%dx, %%cx\n\t" 172 | : "=c" (*out) 173 | : "i" (JBWM_SNAP), "b" (diff), "c" (*out) 174 | : "%ax","%dx" 175 | ); 176 | #else /* portable */ 177 | if(abs(diff)size.array[0],d.array[0]); 187 | snap_dir(&c->size.array[1],d.array[1]); 188 | } 189 | -------------------------------------------------------------------------------- /snap.h: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #ifndef JBWM_SNAP_H 6 | #define JBWM_SNAP_H 7 | struct JBWMClient; 8 | void jbwm_snap_border(struct JBWMClient * c) 9 | __attribute__((nonnull)); 10 | void jbwm_snap_client(struct JBWMClient * c, struct JBWMClient ** head_client); 11 | #endif//JBWM_SNAP_H 12 | -------------------------------------------------------------------------------- /snap_algorithm: -------------------------------------------------------------------------------- 1 | (abs((abs((abs((abs(d) < abs(cixy + ciwh - cxy) ? (d) : (cixy + ciwh - cxy))) < abs(cixy + ciwh - cxy - cwh) ? ((abs(d) < abs(cixy + ciwh - cxy) ? (d) : (cixy + ciwh - cxy))) : (cixy + ciwh - cxy - cwh))) < abs(cixy - cxy - cwh) ? ((abs((abs(d) < abs(cixy + ciwh - cxy) ? (d) : (cixy + ciwh - cxy))) < abs(cixy + ciwh - cxy - cwh) ? ((abs(d) < abs(cixy + ciwh - cxy) ? (d) : (cixy + ciwh - cxy))) : (cixy + ciwh - cxy - cwh))) : (cixy - cxy - cwh))) < abs(cixy - cxy) ? ((abs((abs((abs(d) < abs(cixy + ciwh - cxy) ? (d) : (cixy + ciwh - cxy))) < abs(cixy + ciwh - cxy - cwh) ? ((abs(d) < abs(cixy + ciwh - cxy) ? (d) : (cixy + ciwh - cxy))) : (cixy + ciwh - cxy - cwh))) < abs(cixy - cxy - cwh) ? ((abs((abs(d) < abs(cixy + ciwh - cxy) ? (d) : (cixy + ciwh - cxy))) < abs(cixy + ciwh - cxy - cwh) ? ((abs(d) < abs(cixy + ciwh - cxy) ? (d) : (cixy + ciwh - cxy))) : (cixy + ciwh - cxy - cwh))) : (cixy - cxy - cwh))) : (cixy - cxy)) 2 | -------------------------------------------------------------------------------- /sz: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export CFLAGS="-Os -DNDEBUG" 3 | make clean 4 | make -j8 5 | strip jbwm 6 | ls -l jbwm >> sz.log 7 | tail sz.log 8 | -------------------------------------------------------------------------------- /title_bar.c: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2019, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #include "title_bar.h" 6 | #include "config.h" 7 | #include "draw.h" 8 | #include "ewmh.h" 9 | #include "ewmh_state.h" 10 | #include "font.h" 11 | #include "atom.h" 12 | #include "move_resize.h" 13 | #include "util.h" 14 | #include "wm_state.h" 15 | #include 16 | #include 17 | #include 18 | #ifdef JBWM_USE_XFT 19 | #include 20 | #endif//JBWM_USE_XFT 21 | #include 22 | static inline int8_t set_shaded(struct JBWMClient * c) { 23 | c->old_size.height = c->size.height; 24 | c->size.height = 1; 25 | return IconicState; 26 | } 27 | static inline int8_t set_not_shaded(struct JBWMClient * c) 28 | { 29 | c->size.height = c->old_size.height; 30 | return NormalState; 31 | } 32 | static inline bool can_shade(struct JBWMClient * c) 33 | { 34 | // Honor mwm minimize hint. Abort if fullscreen. 35 | return !c->opt.no_shade && !c->opt.fullscreen; 36 | } 37 | // This implements window shading, a substitute for iconification. 38 | void jbwm_toggle_shade(struct JBWMClient * c) 39 | { 40 | if (can_shade(c)){ 41 | Display *d; 42 | const bool s = c->opt.shaded = !c->opt.shaded; 43 | const int8_t state = (s ? set_shaded : set_not_shaded)(c); 44 | d=c->screen->xlib->display; 45 | (state == IconicState ? jbwm_ewmh_add_state : jbwm_ewmh_remove_state) 46 | (d, c->window, jbwm_atoms[JBWM_NET_WM_STATE_SHADED]); 47 | jbwm_move_resize(c); 48 | jbwm_set_wm_state(c, state); 49 | } 50 | } 51 | static inline uint16_t mv(Display * const d, Window const w, 52 | uint8_t const font_height, uint16_t x) { 53 | if (w){ 54 | XMoveWindow(d, w, x -= font_height, 0); 55 | } 56 | return x; 57 | } 58 | // Return of width allows chain-calling 59 | static uint16_t move_buttons(Display * d, 60 | struct JBWMClientTitleBar * t, 61 | const uint16_t width, uint8_t const font_height) 62 | { 63 | mv(d, t->stick, font_height, 64 | mv(d, t->shade, font_height, 65 | mv(d, t->resize, font_height, width))); 66 | return width; 67 | } 68 | static inline Window get_win(Display * d, const Window p, 69 | const jbwm_pixel_t bg, uint8_t const font_height) 70 | { 71 | return XCreateSimpleWindow(d, p, 0, 0, font_height, font_height, 0, 0, bg); 72 | } 73 | static void add_buttons(struct JBWMClient * c, 74 | const struct JBWMPixels * p, const Window t) 75 | { 76 | struct JBWMClientOptions * o = &c->opt; 77 | Display * d = c->screen->xlib->display; 78 | uint8_t const h = c->screen->font_height; 79 | c->tb.close = o->no_close ? 0 : get_win(d, t, p->close, h); 80 | c->tb.resize = o->no_resize ? 0: get_win(d, t, p->resize, h); 81 | c->tb.shade = o->no_shade ? 0 : get_win(d, t, p->shade, h); 82 | c->tb.stick = get_win(d, t, p->stick, h); 83 | } 84 | static void configure_title_bar(Display * d, const Window t) 85 | { 86 | XSelectInput(d, t, ExposureMask); 87 | XMapRaised(d, t); 88 | XMapSubwindows(d, t); 89 | jbwm_grab_button(d, t, None); 90 | } 91 | static Window new_title_bar(struct JBWMClient * c) 92 | { 93 | struct JBWMScreen *s = c->screen; 94 | const struct JBWMPixels * p = &s->pixels; 95 | Display * d = s->xlib->display; 96 | const Window t = c->tb.win = get_win(d, c->parent, p->bg, 97 | s->font_height); 98 | add_buttons(c, p, t); 99 | configure_title_bar(d, t); 100 | return t; 101 | } 102 | // Free result with XFree if not NULL 103 | static inline char * jbwm_get_title(Display * d, const Window w) 104 | { 105 | return jbwm_get_property(d, w, XA_WM_NAME, &(uint16_t){0}); 106 | } 107 | static void draw_title(struct JBWMClient * c) 108 | { 109 | char *name; 110 | name = jbwm_get_title(c->screen->xlib->display, c->window); 111 | if (name) { 112 | jbwm_draw_string(c->screen, c->tb.win, c->screen->font_height+4, 113 | jbwm_get_font_ascent(), name, strlen(name)); 114 | XFree(name); 115 | } 116 | } 117 | static void remove_title_bar(struct JBWMClient * c) 118 | { 119 | ++(c->ignore_unmap); 120 | XDestroyWindow(c->screen->xlib->display, c->tb.win); 121 | c->tb.win = 0; 122 | } 123 | static inline void resize_title_bar(Display * d, const Window win, 124 | struct JBWMClientTitleBar * tb, const uint16_t new_width, 125 | uint8_t const font_height) { 126 | // Expand/Contract the title bar width as necessary: 127 | if (tb) 128 | XResizeWindow(d, win, move_buttons(d, tb, new_width, font_height), 129 | font_height); 130 | #ifdef DEBUG 131 | else 132 | abort(); 133 | #endif//DEBUG 134 | } 135 | void jbwm_update_title_bar(struct JBWMClient * c) 136 | { 137 | if (!c->opt.shaped){ 138 | Window w; 139 | w = c->tb.win; 140 | if (c->opt.fullscreen && w) { 141 | remove_title_bar(c); 142 | }else{ 143 | if (!w) 144 | w = new_title_bar(c); 145 | { 146 | Display *d; 147 | struct JBWMScreen *s = c->screen; 148 | d = s->xlib->display; 149 | resize_title_bar(d, w, &c->tb, c->size.width,s->font_height); 150 | XClearWindow(d, w); 151 | } 152 | draw_title(c); 153 | if (c->opt.no_title_bar) 154 | remove_title_bar(c); 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /title_bar.h: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #ifndef JBWM_TITLE_BAR_H 6 | #define JBWM_TITLE_BAR_H 7 | struct JBWMClient; 8 | void jbwm_toggle_shade(struct JBWMClient * c); 9 | void jbwm_update_title_bar(struct JBWMClient * c); 10 | #endif /* JBWM_TITLE_BAR_H */ 11 | -------------------------------------------------------------------------------- /util.c: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2019, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #include "util.h" 6 | #include 7 | #include 8 | #include 9 | void jbwm_error(const char * msg) 10 | { 11 | perror(msg); 12 | exit(1); 13 | } 14 | jbwm_pixel_t jbwm_get_pixel(Display * dpy, 15 | const uint8_t screen, const char * name) 16 | { 17 | jbwm_pixel_t r; 18 | if (name) { // sanitize input to avoid segfault 19 | XColor c, d; 20 | XAllocNamedColor(dpy, DefaultColormap(dpy, screen), 21 | name, &c, &d); 22 | r = c.pixel; 23 | } else 24 | r = 0; 25 | return r; 26 | } 27 | void *jbwm_get_property(Display * dpy, Window w, 28 | Atom property, uint16_t * num_items) 29 | { 30 | unsigned char * value; 31 | long unsigned int n; 32 | XGetWindowProperty(dpy, w, property, 0, 1024, false, 33 | AnyPropertyType, &property, &(int){0}, &n, 34 | &(unsigned long){0}, &value); 35 | if (property == None) { 36 | // Requested property not found 37 | XFree(value); 38 | value = NULL; 39 | } 40 | *num_items = n; 41 | return value; 42 | } 43 | void jbwm_grab_button(Display * d, const Window w, 44 | const unsigned int mask) 45 | { 46 | XGrabButton(d, AnyButton, mask, w, false, 47 | ButtonPressMask | ButtonReleaseMask, GrabModeAsync, 48 | GrabModeSync, None, None); 49 | } 50 | #ifdef DEBUG 51 | void jbwm_print_atom(Display * d, const Atom a, const char * src, 52 | const uint16_t line) 53 | { 54 | char *an = XGetAtomName(d, a); 55 | fprintf(stderr, "\t%s:%d %s(%lu)\n", src, line, an, a); 56 | XFree(an); 57 | } 58 | #endif//DEBUG 59 | -------------------------------------------------------------------------------- /util.h: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #ifndef JBWM_UTIL_H 6 | #define JBWM_UTIL_H 7 | #include 8 | #include 9 | #include "pixel_t.h" 10 | void jbwm_error(const char * msg) __attribute__((noreturn)); 11 | jbwm_pixel_t jbwm_get_pixel(Display * dpy, const uint8_t screen, 12 | const char * name); 13 | // Free the result with XFree 14 | void * jbwm_get_property(Display * dpy, const Window w, 15 | Atom property, uint16_t * num_items) 16 | __attribute__((warn_unused_result,nonnull)); 17 | void jbwm_grab_button(Display * d, const Window w, 18 | const unsigned int mask) __attribute__((nonnull(1))); 19 | #ifdef DEBUG 20 | void jbwm_print_atom(Display * d, const Atom a, const char * src, 21 | const uint16_t line); 22 | #else//!DEBUG 23 | #define jbwm_print_atom(d, a, s, l) 24 | #endif//DEBUG 25 | #endif//!JBWM_UTIL_H 26 | -------------------------------------------------------------------------------- /vdesk.c: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #include "vdesk.h" 6 | #include "client.h" 7 | #include "config.h" 8 | #include "draw.h" 9 | #include "ewmh.h" 10 | #include "font.h" 11 | #include "log.h" 12 | #include "atom.h" 13 | #include "JBWMClient.h" 14 | #include "JBWMScreen.h" 15 | #include "util.h" 16 | #include // keep 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #ifdef JBWM_USE_XOSD 24 | #include 25 | #endif//JBWM_USE_XOSD 26 | static void check_visibility(struct JBWMClient * c, 27 | const uint8_t v) 28 | { 29 | if (c) { 30 | if (c->vdesk == v || c->opt.sticky) { 31 | // allow moving windows by sticking 32 | c->vdesk = v; 33 | jbwm_restore_client(c); 34 | } else 35 | jbwm_hide_client(c); 36 | check_visibility(c->next, v); 37 | } 38 | } 39 | #ifndef JBWM_USE_XOSD 40 | static void *delayed_clear_thread(void *data) { 41 | Display *d; 42 | struct JBWMScreen * s = (struct JBWMScreen *)data; 43 | d=s->xlib->display; 44 | JBWM_LOG("pausing"); 45 | sleep(1); 46 | XClearWindow(d, s->xlib->root); 47 | XFlush(d); // must run before thread terminates 48 | JBWM_LOG("window cleared"); 49 | return NULL; 50 | } 51 | static void delayed_clear(struct JBWMScreen *s){ 52 | pthread_t thread; 53 | int r; 54 | r = pthread_create(&thread, NULL, delayed_clear_thread, (void*)s); 55 | assert(!r); 56 | JBWM_LOG("thread launched"); 57 | } 58 | #endif//!JBWM_USE_XOSD 59 | #ifdef JBWM_USE_XOSD 60 | static xosd *osd; 61 | static void clean_osd(void){ 62 | JBWM_LOG("xosd_destroy"); 63 | xosd_destroy(osd); 64 | } 65 | #endif//JBWM_USE_XOSD 66 | static void show_desktop(struct JBWMScreen *s){ 67 | #ifdef JBWM_USE_XOSD 68 | char buf[4]; // accomodate up to "255", plus '-', plus NUL 69 | if (!osd){ 70 | osd = xosd_create(1); 71 | xosd_set_timeout(osd, 1); 72 | xosd_set_colour(osd, "white"); 73 | xosd_set_font(osd, "variable"); 74 | xosd_set_shadow_offset(osd, 2); 75 | xosd_set_align(osd, XOSD_center); 76 | xosd_set_pos(osd, XOSD_middle); 77 | xosd_set_outline_colour(osd, "black"); 78 | xosd_set_outline_offset(osd, 1); 79 | // set up cleanup routine at exit 80 | atexit(clean_osd); 81 | } 82 | snprintf(buf, sizeof(buf), "%d", s->vdesk); 83 | xosd_display(osd, 0, XOSD_string, buf); 84 | #else//!JBWM_USE_XOSD 85 | enum { BORDER = 4 }; 86 | Display *d; 87 | char buf[4]; // accomodate up to "255", plus '-', plus NUL 88 | uint8_t nul_index; 89 | Window const r = s->xlib->root; 90 | d=s->xlib->display; 91 | XClearWindow(d, r); 92 | nul_index = snprintf(buf, sizeof(buf), "%d", s->vdesk); 93 | jbwm_draw_string(s, r, BORDER, BORDER+jbwm_get_font_ascent(), 94 | buf, nul_index); 95 | delayed_clear(s); 96 | #endif//JBWM_USE_XOSD 97 | } 98 | uint8_t jbwm_set_vdesk(struct JBWMScreen *s, 99 | struct JBWMClient *head, uint8_t v) 100 | { 101 | Display *d; 102 | check_visibility(head, v); 103 | s->vdesk = v; 104 | d=s->xlib->display; 105 | // The data (v) must be a 32 bit type. 106 | XChangeProperty(d, s->xlib->root, jbwm_atoms[JBWM_NET_CURRENT_DESKTOP], 107 | XA_CARDINAL, 8, PropModeReplace, (unsigned char *)&v, 1); 108 | show_desktop(s); 109 | return v; 110 | } 111 | -------------------------------------------------------------------------------- /vdesk.h: -------------------------------------------------------------------------------- 1 | // jbwm - Minimalist Window Manager for X 2 | // Copyright 2008-2020, Alisa Bedard 3 | // Copyright 1999-2015, Ciaran Anscomb 4 | // See README for license and other details. 5 | #ifndef JBWM_VDESK_H 6 | #define JBWM_VDESK_H 7 | #include 8 | #include 9 | struct JBWMClient; 10 | struct JBWMScreen; 11 | /* Require the screen parameter here in case the head is NULL. */ 12 | uint8_t jbwm_set_vdesk(struct JBWMScreen *s, 13 | struct JBWMClient *head, uint8_t v); 14 | #endif//!JBWM_VDESK_H 15 | -------------------------------------------------------------------------------- /vimrc: -------------------------------------------------------------------------------- 1 | syn on 2 | colo industry 3 | set background=dark 4 | set shiftwidth=4 5 | set expandtab 6 | set softtabstop=4 7 | autocmd FileType make setlocal noexpandtab 8 | autocmd FileType make setlocal shiftwidth=8 9 | autocmd FileType make setlocal softtabstop=8 10 | set visualbell 11 | set colorcolumn=80 12 | set helpheight=15 13 | "set guifont=Monospace\ 10 14 | set menuitems=10 15 | set linespace=1 16 | set guifont=-*-lucidatypewriter-medium-*-*-*-14-*-*-*-*-*-*-* 17 | set guioptions=c 18 | set autoread 19 | set mouse=a 20 | set smartindent 21 | autocmd BufEnter *.c setf cpp 22 | autocmd FileType c,cpp :setf cpp 23 | autocmd FileType c,cpp :set cindent 24 | set autoread 25 | set cinoptions=>1s,e0,n0,f0,{0,}0,^0,L0,:0,=s,l1,b0,g0,h0,N0,p0,t0,i1s,+0, 26 | \c1s,C0,/0,(1s,u1s,U1,w1,W1s,k0,m1,M0,j1,J1,)100,*100,#0 27 | -------------------------------------------------------------------------------- /wm_state.c: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #include "wm_state.h" 3 | #include "ewmh.h" 4 | #include "ewmh_state.h" 5 | #include "atom.h" 6 | #include "log.h" 7 | #include "util.h" 8 | #include 9 | #include 10 | // Returns 0 on failure. 11 | static Status xmsg(Display * d, const Window w, 12 | const Atom a, const long x) 13 | { 14 | JBWM_LOG("xmsg"); 15 | XClientMessageEvent e = { .type = ClientMessage, .window = w, 16 | .message_type = a, .format = 32 }; 17 | // Split initialization to avoid old gcc warnings. 18 | { // * l scope 19 | long * l = e.data.l; 20 | l[0] = x; 21 | l[1] = CurrentTime; 22 | } 23 | return XSendEvent(d, w, false, NoEventMask, (void*)&e); 24 | } 25 | static Atom get_atom(Display * d, 26 | Atom * a, const char * name) 27 | { 28 | return *a ? *a : (*a = XInternAtom(d, name, false)); 29 | } 30 | #define ATOM_GETTER(func, atom) Atom func(Display * d) \ 31 | {\ 32 | static Atom a;\ 33 | return get_atom(d, &a, atom);\ 34 | } 35 | static ATOM_GETTER(get_wm_protocols, "WM_PROTOCOLS") 36 | static ATOM_GETTER(get_wm_delete_window, "WM_DELETE_WINDOW") 37 | ATOM_GETTER(jbwm_get_wm_state, "WM_STATE") 38 | void jbwm_set_wm_state(const struct JBWMClient * c, int8_t state) 39 | { 40 | const Window w = c->window; 41 | Display * d = c->screen->xlib->display; 42 | XChangeProperty(d, w, jbwm_get_wm_state(d), XA_CARDINAL, 8, 43 | PropModeReplace, (unsigned char *) &state, 1); 44 | (state == IconicState ? jbwm_ewmh_add_state : jbwm_ewmh_remove_state) 45 | (d, w, jbwm_atoms[JBWM_NET_WM_STATE_HIDDEN]); 46 | } 47 | static bool find_delete_proto(const int i, const Atom * p, 48 | Display * d) 49 | { 50 | return (i < 0) ? false : p[i] == get_wm_delete_window(d) ? true 51 | : find_delete_proto(i - 1, p, d); 52 | } 53 | static bool has_delete_proto(const Window w, Display * d) 54 | { 55 | bool found = false; 56 | { // * p, i scope 57 | Atom * p; 58 | int i; 59 | if (XGetWMProtocols(d, w, &p, &i)) { 60 | found = find_delete_proto(i, p, d); 61 | XFree(p); 62 | } 63 | } 64 | return found; 65 | } 66 | void jbwm_send_wm_delete(struct JBWMClient * c) 67 | { 68 | const Window w = c->window; 69 | Display * d = c->screen->xlib->display; 70 | if (c->opt.remove) 71 | // this allows a second click to force a kill 72 | XKillClient(d, w); 73 | else { 74 | c->opt.remove = true; 75 | if (has_delete_proto(w, d)) 76 | xmsg(d, w, get_wm_protocols(d), 77 | get_wm_delete_window(d)); 78 | else // client does not support protocol, force kill: 79 | XKillClient(d, w); 80 | } 81 | // Unmap early in case window does not disappear immediately. 82 | XUnmapWindow(d, c->parent); 83 | XFlush(d); // Do everything now. 84 | } 85 | -------------------------------------------------------------------------------- /wm_state.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020, Alisa Bedard 2 | #ifndef JBWM_WM_STATE_H 3 | #define JBWM_WM_STATE_H 4 | #include 5 | #include "JBWMClient.h" 6 | // Return WM_STATE atom 7 | Atom jbwm_get_wm_state(Display * d); 8 | // Send WM_DELETE message to the client 9 | void jbwm_send_wm_delete(struct JBWMClient * c) 10 | __attribute__((nonnull)); 11 | // Set WM_STATE property 12 | void jbwm_set_wm_state(const struct JBWMClient * c, int8_t state); 13 | #endif//!JBWM_WM_STATE_H 14 | -------------------------------------------------------------------------------- /xeph: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | DIM="1000x700" 3 | DPY=":1" 4 | exec Xephyr -screen $DIM -listen tcp -resizeable -host-cursor $DPY 5 | -------------------------------------------------------------------------------- /xft.mk: -------------------------------------------------------------------------------- 1 | jbwm_cflags+=-DJBWM_USE_XFT 2 | jbwm_cflags+=`pkg-config --cflags xft` 3 | jbwm_ldflags+=`pkg-config --libs xft` 4 | -------------------------------------------------------------------------------- /xosd.mk: -------------------------------------------------------------------------------- 1 | jbwm_cflags+=-DJBWM_USE_XOSD 2 | jbwm_ldflags+=-lxosd 3 | --------------------------------------------------------------------------------