Compare commits

...
Sign in to create a new pull request.

15 commits

Author SHA1 Message Date
Jonathan Hodgson
73ba8c61bf Pushing dwm changes 2024-02-15 11:20:43 +00:00
Jonathan Hodgson
3deebe7302 Adds screenshot bindings to f10
On my new laptop, I have decided to keep the f keys as f keys which
requires hitting the fn key to get additional functions such as
play/pause etc. I did this because I often found myself hitting mute
(for example) by mistake. However, I don't use f10 for anything else so
rather than pushing fn+f10 (prt sc on my keyboard), I just want to push
f10. The shift / ctrl modifiers were implemented.
2022-02-03 10:47:02 +00:00
Jonathan Hodgson
42d54181e2 Add act on last keyboard shortcuts 2022-02-03 10:11:01 +00:00
Jonathan Hodgson
cb0a34b6b8 Merge branch 'master' of ssh://git.jonathanh.co.uk:2222/jab2870/dwm 2021-08-17 12:42:15 +01:00
Jonathan Hodgson
2a06bfb40a Adds screenrecord 2021-08-17 12:42:12 +01:00
Jonathan Hodgson
2718671c22 Makes pause button play / pause 2021-08-16 08:56:38 +01:00
Jonathan Hodgson
730577a008 Adds win+left or win+right to switch tag
This involved the patch from here:

https://lists.suckless.org/dev/1104/7590.html

I use this on the pinephone with win+left and win+right bound to a swipe
left or right on the bottom edge of the screen
2021-04-05 09:26:18 +01:00
Jonathan Hodgson
3dbeed51c5 Makes a double tap of the power button toggle the keyboard 2021-03-31 21:22:11 +01:00
Jonathan Hodgson
6866a4a4ea Changes functionality of power button
A single push will turn off the screen

A double push or a push and hold will open the power menu, allowing you
to turn off, restart, logout or suspend (CRUST)
2021-02-25 14:57:02 +00:00
Jonathan Hodgson
47ffe2fbdb Fixes keybindings for power button 2021-02-22 22:06:13 +00:00
Jonathan Hodgson
3b11aab6f2 Makes double press of power button bring up power menu 2021-02-22 21:58:43 +00:00
Jonathan Hodgson
c0a50b817c Applies the multikey patch
This allows me to have the same key do different things based on the
number of times it is pushed.

This is going to be useful on the pinephone so I can have double click
or click and hold on the limited number of physical buttons
2021-02-22 21:53:08 +00:00
Jonathan Hodgson
449d90b2e3 Adds power menu and removes unused binding 2021-02-10 21:28:36 +00:00
Jonathan Hodgson
e11fb64dad Changes onboard to svkbd 2021-02-10 21:24:23 +00:00
Jonathan Hodgson
2824ffb4cf Run launcher shell script instead of rofi
This shell script currently just picks between rofi and dmenu although
may do more later on
2021-02-07 20:56:02 +00:00
3 changed files with 239 additions and 84 deletions

View file

@ -37,7 +37,7 @@ static const Rule rules[] = {
{ "xterm-256color", NULL, NULL, 0, 0, 1, 1, 0, 0, -1 }, { "xterm-256color", NULL, NULL, 0, 0, 1, 1, 0, 0, -1 },
{ "Thunderbird", NULL, NULL, 1 << 8 , 0, 0, 0, 0, 0, -1 }, { "Thunderbird", NULL, NULL, 1 << 8 , 0, 0, 0, 0, 0, -1 },
{ NULL, NULL, "noswallow", 0, 0, 0, 1, 0, 0, -1 }, { NULL, NULL, "noswallow", 0, 0, 0, 1, 0, 0, -1 },
{ "Onboard", NULL, NULL, 0, 1, 0, 1, 0, 1, -1 }, { "svkbd", NULL, NULL, 0, 1, 0, 1, 0, 1, -1 },
{ "Onboard-settings", NULL, NULL, 0, 0, 0, 0, 0, 0, -1 } { "Onboard-settings", NULL, NULL, 0, 0, 0, 0, 0, 0, -1 }
}; };
@ -63,32 +63,27 @@ static const Layout layouts[] = {
/* key definitions */ /* key definitions */
#define MODKEY Mod4Mask #define MODKEY Mod4Mask
#define TAGKEYS(KEY,TAG) \ #define TAGKEYS(KEY,TAG) \
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \ { MODKEY, KEY, 0, view, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ { MODKEY|ControlMask, KEY, 0, toggleview, {.ui = 1 << TAG} }, \
{ MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ { MODKEY|ShiftMask, KEY, 0, tag, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, { MODKEY|ControlMask|ShiftMask, KEY, 0, toggletag, {.ui = 1 << TAG} },
/* helper for spawning shell commands in the pre dwm-5.0 fashion */ /* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
/* commands */ /* commands */
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
static const char *dmenucmd[] = { "rofi", "-show", "drun", "-modi", "drun", "-theme", "themes/launchpad.rasi", NULL }; static const char *dmenucmd[] = { "launcher", NULL };
//static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; //static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
static const char *termcmd[] = { "folder-shell", NULL }; static const char *termcmd[] = { "folder-shell", NULL };
static const char *lfcmd[] = { "folder-shell", "lf", NULL };
static const char *fullscreenshot[] = { "screenshot", NULL }; static const char *fullscreenshot[] = { "screenshot", NULL };
static const char *activescreenshot[] = { "screenshot", "window", NULL }; static const char *activescreenshot[] = { "screenshot", "window", NULL };
static const char *selectscreenshot[] = { "screenshot", "select", NULL }; static const char *selectscreenshot[] = { "screenshot", "select", NULL };
static const char *greenclip[] = { "rofi", "-modi", "clipboard:greenclip print", "-show", "clipboard", "-run-command", "{cmd}", NULL }; static const char *selectscreenrecord[] = { "screenrecord", "select", NULL };
static const char *qutebrowser[] = { "qutebrowser", NULL };
static const char *surf[] = { "tabbed", "-c", "surf", "-e", NULL };
static const char *chromium[] = { "chromium", NULL }; static const char *chromium[] = { "chromium", NULL };
static const char *bigchromium[] = { "chromium", "--force-device-scale-factor=2", NULL };
static const char *firefox[] = { "firefox-developer-edition", NULL }; static const char *firefox[] = { "firefox-developer-edition", NULL };
static const char *date[] = { "datetime", NULL }; static const char *date[] = { "datetime", NULL };
@ -101,7 +96,6 @@ static const char *playpause[] = { "playerctl", "play-pause", NULL };
static const char *logout[] = { "rofi-shutdown", NULL }; static const char *logout[] = { "rofi-shutdown", NULL };
static const char *offlineArchWiki[] = { "offline-aw", NULL };
static const char *manPages[] = { "man-page-pdf", NULL }; static const char *manPages[] = { "man-page-pdf", NULL };
static const char *ports[] = { "ports", NULL }; static const char *ports[] = { "ports", NULL };
@ -119,75 +113,117 @@ static const char *volumeToggle[] = { "volume", "toggle", NULL };
static const char *brightnessUp[] = { "brightness", "up", NULL }; static const char *brightnessUp[] = { "brightness", "up", NULL };
static const char *brightnessDown[] = { "brightness", "down", NULL }; static const char *brightnessDown[] = { "brightness", "down", NULL };
static const char *setBackgroundRandom[] = { "rofi-background", "--earth", NULL };
static const char *backgroundDetails[] = { "background", "--only-notify", NULL };
static const char *unity_hud[] = { "hud-menu.py" }; static const char *lockScreen[] = { "screenlock", "--suspend", NULL };
static const char *powerMenu[] = { "rofi-shutdown", NULL };
static const char *toggleKeyboard[] = { "toggleKeyboard", NULL };
static const char *actOnLast[] = { "actOnLast", NULL };
static const char *actOnLastDefault[] = { "actOnLast", "--first", NULL };
static const char *dunstClose[] = { "dunstctl", "close", NULL };
static const char *dunstOpenLast[] = { "dunstctl", "history-pop", NULL };
#include "movestack.c" #include "movestack.c"
#define MULTIKEY_THRESHOLD_MS_PRESS 200
#define MULTIKEY_THRESHOLD_MS_HOLD 700
static Key keys[] = { static Key keys[] = {
/* modifier key function argument */ /* modifier key count function argument */
{ MODKEY, XK_p, spawn, {.v = dmenucmd } }, { MODKEY, XK_Return, 0, spawn, {.v = termcmd } },
{ MODKEY, XK_Return, spawn, {.v = termcmd } }, //{ MODKEY|ShiftMask, XK_Return, 0, zoom, {0} },
{ MODKEY|ControlMask, XK_Return, spawn, {.v = lfcmd } },
{ MODKEY, XK_b, togglebar, {0} }, { MODKEY, XK_Tab, 0, toggleAttachBelow, {0} },
{ MODKEY, XK_j, focusstack, {.i = +1 } }, { MODKEY|ShiftMask, XK_Tab, 0, spawn, {.v = dunstOpenLast} },
{ MODKEY, XK_k, focusstack, {.i = -1 } },
{ MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } }, { MODKEY, XK_space, 0, spawn, {.v = dunstClose} },
{ MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } },
{ MODKEY, XK_i, incnmaster, {.i = +1 } }, { MODKEY|ShiftMask, XK_a, 0, spawn, {.v = screenlayout } },
{ MODKEY|ShiftMask, XK_i, incnmaster, {.i = -1 } },
{ MODKEY, XK_h, setmfact, {.f = -0.05} }, { MODKEY, XK_b, 0, togglebar, {0} },
{ MODKEY, XK_l, setmfact, {.f = +0.05} }, { MODKEY|ShiftMask, XK_b, 0, spawn, {.v = battery} },
{ MODKEY|ShiftMask, XK_l, spawn, {.v = logout} },
{ MODKEY|ShiftMask, XK_Return, zoom, {0} }, { MODKEY, XK_c, 0, spawn, {.v = firefox } },
{ MODKEY, XK_Tab, toggleAttachBelow, {0} }, { MODKEY|ShiftMask, XK_c, 0, spawn, {.v = chromium } },
{ MODKEY, XK_q, killclient, {0} },
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, { MODKEY, XK_d, 0, spawn, {.v = pass } },
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, { MODKEY|ShiftMask, XK_d, 0, spawn, {.v = date } },
{ MODKEY|ShiftMask, XK_t, setlayout, {.v = &layouts[3]} },
{ MODKEY, XK_f, setlayout, {.v = &layouts[4]} }, { MODKEY, XK_f, 0, setlayout, {.v = &layouts[4]} },
{ MODKEY|ShiftMask, XK_f, setlayout, {.v = &layouts[5]} }, { MODKEY|ShiftMask, XK_f, 0, setlayout, {.v = &layouts[5]} },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} }, { MODKEY, XK_h, 0, setmfact, {.f = -0.05} },
{ MODKEY, XK_0, view, {.ui = ~0 } },
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, { MODKEY, XK_i, 0, incnmaster, {.i = +1 } },
{ MODKEY, XK_comma, focusmon, {.i = -1 } }, { MODKEY|ShiftMask, XK_i, 0, incnmaster, {.i = -1 } },
{ MODKEY, XK_period, focusmon, {.i = +1 } },
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, { MODKEY, XK_j, 0, focusstack, {.i = +1 } },
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, { MODKEY|ShiftMask, XK_j, 0, movestack, {.i = +1 } },
{ 0, XK_Print, spawn, {.v = fullscreenshot } },
{ ControlMask, XK_Print, spawn, {.v = activescreenshot } }, { MODKEY, XK_k, 0, focusstack, {.i = -1 } },
{ ShiftMask, XK_Print, spawn, {.v = selectscreenshot } }, { MODKEY|ShiftMask, XK_k, 0, movestack, {.i = -1 } },
{ 0, XF86XK_AudioPlay, spawn, {.v = playpause } },
{ MODKEY|ShiftMask, XK_d, spawn, {.v = date } }, { MODKEY, XK_l, 0, setmfact, {.f = +0.05} },
{ MODKEY|ShiftMask, XK_b, spawn, {.v = battery} }, { MODKEY|ShiftMask, XK_l, 0, spawn, {.v = logout} },
{ MODKEY|ShiftMask, XK_Insert, spawn, {.v = greenclip } },
//Applications { MODKEY, XK_m, 0, setlayout, {.v = &layouts[2]} },
{ MODKEY|ShiftMask, XK_q, spawn, {.v = qutebrowser } }, { MODKEY|ShiftMask, XK_m, 0, spawn, {.v = manPages } },
{ MODKEY , XK_s, spawn, {.v = surf } },
{ MODKEY, XK_c, spawn, {.v = firefox } }, { MODKEY, XK_o, 0, spawn, {.v = actOnLast } },
{ MODKEY|ShiftMask, XK_c, spawn, {.v = chromium } }, { MODKEY|ShiftMask, XK_o, 0, spawn, {.v = actOnLastDefault } },
//Dmenu / Rofi
{ MODKEY, XK_u, spawn, {.v = unicode } }, { MODKEY, XK_p, 0, spawn, {.v = dmenucmd } },
{ MODKEY, XK_y, spawn, {.v = youtube } }, { MODKEY|ShiftMask, XK_p, 0, spawn, {.v = ports } },
{ MODKEY, XK_a, spawn, {.v = offlineArchWiki } },
{ MODKEY|ShiftMask, XK_a, spawn, {.v = screenlayout } }, { MODKEY, XK_q, 0, killclient, {0} },
{ MODKEY|ShiftMask, XK_m, spawn, {.v = manPages } },
{ MODKEY|ShiftMask, XK_p, spawn, {.v = ports } }, { MODKEY|ShiftMask, XK_r, 0, quit, {0} },
{ MODKEY, XK_w, spawn, {.v = whichproject } },
{ MODKEY|ShiftMask, XK_w, spawn, {.v = project } }, { MODKEY, XK_t, 0, setlayout, {.v = &layouts[0]} },
{ MODKEY, XK_d, spawn, {.v = pass } }, { MODKEY|ShiftMask, XK_t, 0, setlayout, {.v = &layouts[3]} },
{ MODKEY, XK_x, spawn, {.v = unity_hud } },
//Background { MODKEY, XK_u, 0, spawn, {.v = unicode } },
{ MODKEY, XK_e, spawn, {.v = setBackgroundRandom } },
{ MODKEY|ControlMask, XK_e, spawn, {.v = backgroundDetails } }, { MODKEY, XK_w, 0, spawn, {.v = whichproject } },
//Special keys { MODKEY|ShiftMask, XK_w, 0, spawn, {.v = project } },
{ 0, XF86XK_AudioRaiseVolume, spawn, {.v = volumeUp } },
{ 0, XF86XK_AudioLowerVolume, spawn, {.v = volumeDown } }, { MODKEY, XK_y, 0, spawn, {.v = youtube } },
{ 0, XF86XK_AudioMute, spawn, {.v = volumeToggle } },
{ 0, XF86XK_MonBrightnessUp, spawn, {.v = brightnessUp } }, { MODKEY, XK_comma, 0, focusmon, {.i = -1 } },
{ 0, XF86XK_MonBrightnessDown, spawn, {.v = brightnessDown } }, { MODKEY|ShiftMask, XK_comma, 0, tagmon, {.i = -1 } },
{ MODKEY, XK_period, 0, focusmon, {.i = +1 } },
{ MODKEY|ShiftMask, XK_period, 0, tagmon, {.i = +1 } },
{ 0, XK_Print, 0, spawn, {.v = fullscreenshot } },
{ ControlMask, XK_Print, 0, spawn, {.v = activescreenshot } },
{ ShiftMask, XK_Print, 0, spawn, {.v = selectscreenshot } },
{ 0, XK_F10, 0, spawn, {.v = fullscreenshot } },
{ ControlMask, XK_F10, 0, spawn, {.v = activescreenshot } },
{ ShiftMask, XK_F10, 0, spawn, {.v = selectscreenshot } },
{ 0, XF86XK_AudioPlay, 0, spawn, {.v = playpause } },
{ 0, XF86XK_AudioPause, 0, spawn, {.v = playpause } },
{ 0, XF86XK_AudioRaiseVolume, 0, spawn, {.v = volumeUp } },
{ 0, XF86XK_AudioLowerVolume, 0, spawn, {.v = volumeDown } },
{ 0, XF86XK_AudioMute, 0, spawn, {.v = volumeToggle } },
{ 0, XF86XK_MonBrightnessUp, 0, spawn, {.v = brightnessUp } },
{ 0, XF86XK_MonBrightnessDown, 0, spawn, {.v = brightnessDown } },
{ MODKEY, XK_Right, 0, shiftview, {.i = 1 } },
{ MODKEY, XK_Left, 0, shiftview, {.i = -1 } },
// On the pinephone, I want a single press of the power button to put the phone in sleep mode.
// I want a double press to toggle the keyboard
// I want a hold press to bring up the power menu
// TODO: Make a command for screen lock
{ 0, XF86XK_PowerOff, 1, spawn, {.v = lockScreen } },
{ 0, XF86XK_PowerOff, 2, spawn, {.v = toggleKeyboard } },
{ 0, XF86XK_PowerOff, 3, spawn, {.v = powerMenu } },
TAGKEYS( XK_1, 0) TAGKEYS( XK_1, 0)
TAGKEYS( XK_2, 1) TAGKEYS( XK_2, 1)
TAGKEYS( XK_3, 2) TAGKEYS( XK_3, 2)
@ -197,7 +233,9 @@ static Key keys[] = {
TAGKEYS( XK_7, 6) TAGKEYS( XK_7, 6)
TAGKEYS( XK_8, 7) TAGKEYS( XK_8, 7)
TAGKEYS( XK_9, 8) TAGKEYS( XK_9, 8)
{ MODKEY|ShiftMask, XK_r, quit, {0} },
{ MODKEY, XK_0, 0, view, {.ui = ~0 } },
{ MODKEY|ShiftMask, XK_0, 0, tag, {.ui = ~0 } },
}; };
/* button definitions */ /* button definitions */

View file

@ -22,7 +22,7 @@ FREETYPEINC = /usr/include/freetype2
# includes and libs # includes and libs
INCS = -I${X11INC} -I${FREETYPEINC} INCS = -I${X11INC} -I${FREETYPEINC}
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lX11-xcb -lxcb -lxcb-res LIBS = -L${X11LIB} -lrt -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lX11-xcb -lxcb -lxcb-res
# flags # flags
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}

125
dwm.c
View file

@ -30,6 +30,7 @@
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <time.h>
#include <X11/cursorfont.h> #include <X11/cursorfont.h>
#include <X11/keysym.h> #include <X11/keysym.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
@ -40,6 +41,7 @@
#include <X11/extensions/Xinerama.h> #include <X11/extensions/Xinerama.h>
#endif /* XINERAMA */ #endif /* XINERAMA */
#include <X11/Xft/Xft.h> #include <X11/Xft/Xft.h>
#include <X11/XKBlib.h>
#include <X11/Xlib-xcb.h> #include <X11/Xlib-xcb.h>
#include <xcb/res.h> #include <xcb/res.h>
@ -106,6 +108,7 @@ struct Client {
typedef struct { typedef struct {
unsigned int mod; unsigned int mod;
KeySym keysym; KeySym keysym;
unsigned int npresses;
void (*func)(const Arg *); void (*func)(const Arg *);
const Arg arg; const Arg arg;
} Key; } Key;
@ -187,6 +190,10 @@ static void grabbuttons(Client *c, int focused);
static void grabkeys(void); static void grabkeys(void);
static void incnmaster(const Arg *arg); static void incnmaster(const Arg *arg);
static void keypress(XEvent *e); static void keypress(XEvent *e);
static void keypresstimerdispatch(int msduration, int data);
static void keypresstimerdone(union sigval timer_data);
static void keypresstimerdonesync(int idx);
static void keyrelease(XEvent *e);
static void killclient(const Arg *arg); static void killclient(const Arg *arg);
static void manage(Window w, XWindowAttributes *wa); static void manage(Window w, XWindowAttributes *wa);
static void mappingnotify(XEvent *e); static void mappingnotify(XEvent *e);
@ -214,6 +221,7 @@ static void setlayout(const Arg *arg);
static void setmfact(const Arg *arg); static void setmfact(const Arg *arg);
static void setup(void); static void setup(void);
static void seturgent(Client *c, int urg); static void seturgent(Client *c, int urg);
static void shiftview(const Arg *arg);
static void showhide(Client *c); static void showhide(Client *c);
static void sigchld(int unused); static void sigchld(int unused);
static void spawn(const Arg *arg); static void spawn(const Arg *arg);
@ -273,13 +281,14 @@ static void (*handler[LASTEvent]) (XEvent *) = {
[Expose] = expose, [Expose] = expose,
[FocusIn] = focusin, [FocusIn] = focusin,
[KeyPress] = keypress, [KeyPress] = keypress,
[KeyRelease] = keyrelease,
[MappingNotify] = mappingnotify, [MappingNotify] = mappingnotify,
[MapRequest] = maprequest, [MapRequest] = maprequest,
[MotionNotify] = motionnotify, [MotionNotify] = motionnotify,
[PropertyNotify] = propertynotify, [PropertyNotify] = propertynotify,
[UnmapNotify] = unmapnotify [UnmapNotify] = unmapnotify
}; };
static Atom wmatom[WMLast], netatom[NetLast]; static Atom timeratom, wmatom[WMLast], netatom[NetLast];
static int running = 1; static int running = 1;
static Cur *cursor[CurLast]; static Cur *cursor[CurLast];
static Clr **scheme; static Clr **scheme;
@ -290,6 +299,10 @@ static Window root, wmcheckwin;
static xcb_connection_t *xcon; static xcb_connection_t *xcon;
static int multikeypendingindex = -1;
static timer_t multikeypendingtimer = NULL;
static int multikeyup = 1;
/* configuration, allows nested code to access above variables */ /* configuration, allows nested code to access above variables */
#include "config.h" #include "config.h"
@ -604,6 +617,11 @@ clientmessage(XEvent *e)
XClientMessageEvent *cme = &e->xclient; XClientMessageEvent *cme = &e->xclient;
Client *c = wintoclient(cme->window); Client *c = wintoclient(cme->window);
if (cme->message_type == timeratom) {
keypresstimerdonesync(cme->data.s[0]);
return;
}
if (!c) if (!c)
return; return;
if (cme->message_type == netatom[NetWMState]) { if (cme->message_type == netatom[NetWMState]) {
@ -1070,11 +1088,88 @@ keypress(XEvent *e) {
ev = &e->xkey; ev = &e->xkey;
keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
for (i = 0; i < LENGTH(keys); i++) for (i = 0; i < LENGTH(keys); i++){
if (keysym == keys[i].keysym if (keysym == keys[i].keysym
&& CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
&& keys[i].func) && keys[i].func){
keys[i].func(&(keys[i].arg)); // E.g. Normal functionality case - npresses 0 == keydown immediate fn
if (keys[i].npresses == 0) {
keys[i].func(&(keys[i].arg));
break;
}
// Multikey functionality - find index of key, set global, & dispatch
if (
(multikeypendingindex == -1 && multikeyup && keys[i].npresses == 1) ||
(multikeypendingindex != -1 && keys[multikeypendingindex].npresses + 1 == keys[i].npresses)
) {
multikeyup = 0;
multikeypendingindex = i;
keypresstimerdispatch(MULTIKEY_THRESHOLD_MS_PRESS, i);
break;
}
}
}
}
void
keypresstimerdispatch(int msduration, int data)
{
struct sigevent timer_signal_event;
struct itimerspec timer_period;
// Clear out the old timer if any set,and dispatch new timer
if (multikeypendingtimer != NULL) timer_delete(multikeypendingtimer);
timer_signal_event.sigev_notify = SIGEV_THREAD;
timer_signal_event.sigev_notify_function = keypresstimerdone;
timer_signal_event.sigev_value.sival_int = data;
timer_signal_event.sigev_notify_attributes = NULL;
timer_create(CLOCK_MONOTONIC, &timer_signal_event, &multikeypendingtimer);
timer_period.it_value.tv_sec = 0;
timer_period.it_value.tv_nsec = msduration * 1000000;
timer_period.it_interval.tv_sec = 0;
timer_period.it_interval.tv_nsec = 0;
timer_settime(multikeypendingtimer, 0, &timer_period, NULL);
}
void
keypresstimerdone(union sigval timer_data)
{
XEvent ev;
memset(&ev, 0, sizeof ev);
ev.xclient.type = ClientMessage;
ev.xclient.window = root;
ev.xclient.message_type = timeratom;
ev.xclient.format = 16;
ev.xclient.data.s[0] = ((short) timer_data.sival_int);
XSendEvent(dpy, root, False, SubstructureRedirectMask, &ev);
XSync(dpy, False);
}
void
keypresstimerdonesync(int idx)
{
int i, maxidx;
if (keys[idx].npresses == 1 && !multikeyup) {
// Dispatch hold key
maxidx = -1;
for (i = 0; i < LENGTH(keys); i++)
if (keys[i].keysym == keys[idx].keysym) maxidx = i;
if (maxidx != -1)
keypresstimerdispatch(
MULTIKEY_THRESHOLD_MS_HOLD - MULTIKEY_THRESHOLD_MS_PRESS,
maxidx
);
} else if (keys[idx].func) {
// Run the actual keys' fn
keys[idx].func(&(keys[idx].arg));
multikeypendingindex = -1;
}
}
void
keyrelease(XEvent *e)
{
multikeyup = 1;
} }
void void
@ -1779,6 +1874,26 @@ seturgent(Client *c, int urg)
XFree(wmh); XFree(wmh);
} }
/** Function to shift the current view to the left/right
*
* @param: "arg->i" stores the number of tags to shift right (positive value)
* or left (negative value)
*/
void
shiftview(const Arg *arg) {
Arg shifted;
if(arg->i > 0) // left circular shift
shifted.ui = (selmon->tagset[selmon->seltags] << arg->i)
| (selmon->tagset[selmon->seltags] >> (LENGTH(tags) - arg->i));
else // right circular shift
shifted.ui = selmon->tagset[selmon->seltags] >> (- arg->i)
| selmon->tagset[selmon->seltags] << (LENGTH(tags) + arg->i);
view(&shifted);
}
void void
showhide(Client *c) showhide(Client *c)
{ {
@ -2439,6 +2554,7 @@ zoom(const Arg *arg)
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
XInitThreads();
if (argc == 2 && !strcmp("-v", argv[1])) if (argc == 2 && !strcmp("-v", argv[1]))
die("dwm-"VERSION); die("dwm-"VERSION);
else if (argc != 1) else if (argc != 1)
@ -2449,6 +2565,7 @@ main(int argc, char *argv[])
die("dwm: cannot open display"); die("dwm: cannot open display");
if (!(xcon = XGetXCBConnection(dpy))) if (!(xcon = XGetXCBConnection(dpy)))
die("dwm: cannot get xcb connection\n"); die("dwm: cannot get xcb connection\n");
XkbSetDetectableAutoRepeat(dpy, True, NULL);
checkotherwm(); checkotherwm();
setup(); setup();
#ifdef __OpenBSD__ #ifdef __OpenBSD__