Skip to content

Commit

Permalink
Add move/resize mouse mask support
Browse files Browse the repository at this point in the history
  • Loading branch information
JLErvin committed May 3, 2020
1 parent 5ab590c commit 181b019
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 13 deletions.
16 changes: 11 additions & 5 deletions client.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ static struct command c[] = {
{ "unmanage", IPCUnmanage, true, 1, fn_str },
{ "decorate_new", IPCDecorate, true, 1, fn_bool },
{ "name_desktop", IPCNameDesktop, false, 2, fn_int_str },
{ "move_mask", IPCMoveMask, true, 1, fn_str },
{ "resize_mask", IPCResizeMask, true, 1, fn_str },
};

static void
Expand Down Expand Up @@ -106,11 +108,15 @@ fn_str(long *data, bool b, int i, char **argv)
{
UNUSED(b);
// lord forgive me for I have sinned
if (strcmp(argv[i-1], "Dialog") == 0) data[i] = Dialog;
else if (strcmp(argv[i-1], "Toolbar") == 0) data[i] = Toolbar;
else if (strcmp(argv[i-1], "Menu") == 0) data[i] = Menu;
else if (strcmp(argv[i-1], "Splash") == 0) data[i] = Dialog;
else if (strcmp(argv[i-1], "Utility") == 0) data[i] = Utility;
if (strcmp(argv[i-1], "Dialog") == 0) data[i+b] = Dialog;
else if (strcmp(argv[i-1], "Toolbar") == 0) data[i+b] = Toolbar;
else if (strcmp(argv[i-1], "Menu") == 0) data[i+b] = Menu;
else if (strcmp(argv[i-1], "Splash") == 0) data[i+b] = Splash;
else if (strcmp(argv[i-1], "Utility") == 0) data[i+b] = Utility;
else if (strcmp(argv[i-1], "Mod1") == 0) data[i+b] = Mod1Mask;
else if (strcmp(argv[i-1], "Mod2") == 0) data[i+b] = Mod2Mask;
else if (strcmp(argv[i-1], "Mod3") == 0) data[i+b] = Mod3Mask;
else if (strcmp(argv[i-1], "Mod4") == 0) data[i+b] = Mod4Mask;
}

/* This function works by setting a new atom globally on the root
Expand Down
2 changes: 2 additions & 0 deletions config.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,7 @@
#define MANAGE_UTILITY true

#define DECORATE_NEW true
#define MOVE_MASK Mod4Mask
#define RESIZE_MASK Mod1Mask

#endif
2 changes: 2 additions & 0 deletions ipc.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ enum IPCCommand
IPCUnmanage,
IPCConfig,
IPCDecorate,
IPCMoveMask,
IPCResizeMask,
IPCLast
};

Expand Down
2 changes: 1 addition & 1 deletion types.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct client {
};

struct config {
int b_width, i_width, t_height, top_gap, bot_gap, left_gap, right_gap, r_step, m_step;
int b_width, i_width, t_height, top_gap, bot_gap, left_gap, right_gap, r_step, m_step, move_mask, resize_mask;
unsigned long bf_color, bu_color, if_color, iu_color;
bool focus_new, edge_lock, t_center, smart_place, draw_text, json_status, decorate;
bool manage[WindowLast];
Expand Down
64 changes: 57 additions & 7 deletions wm.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <X11/Xproto.h>
#include <X11/Xutil.h>
#include <X11/extensions/Xinerama.h>
#include <X11/extensions/shape.h>
#include <X11/cursorfont.h>
#include <X11/Xft/Xft.h>

Expand Down Expand Up @@ -136,6 +137,8 @@ static void load_color(XftColor *dest_color, unsigned long raw_color);
static void load_config(char *conf_path);
static void manage_new_window(Window w, XWindowAttributes *wa);
static int manage_xsend_icccm(struct client *c, Atom atom);
static void grab_buttons(void);
static void ungrab_buttons(void);
static void refresh_config(void);
static void run(void);
static bool safe_to_focus(int ws);
Expand Down Expand Up @@ -353,8 +356,10 @@ client_decorations_create(struct client *c)
int h = c->geom.height + 2 * conf.i_width + conf.t_height;
int x = c->geom.x - conf.i_width - conf.b_width;
int y = c->geom.y - conf.i_width - conf.b_width - conf.t_height;

Window dec = XCreateSimpleWindow(display, root, x, y, w, h, conf.b_width,
conf.bu_color, conf.bf_color);

c->dec = dec;
c->decorated = true;
XSelectInput (display, c->dec, ExposureMask);
Expand Down Expand Up @@ -571,7 +576,7 @@ handle_button_press(XEvent *e)
XButtonPressedEvent *bev = &e->xbutton;
XEvent ev;
struct client *c;
int x, y, ocx, ocy, nx, ny, di;
int x, y, ocx, ocy, nx, ny, nw, nh, di, ocw, och;
unsigned int dui;
Window dummy;

Expand All @@ -584,6 +589,8 @@ handle_button_press(XEvent *e)
client_manage_focus(c);
ocx = c->geom.x;
ocy = c->geom.y;
ocw = c->geom.width;
och = c->geom.height;
if (XGrabPointer(display, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, None, move_cursor, CurrentTime) != GrabSuccess)
return;
do {
Expand All @@ -596,12 +603,21 @@ handle_button_press(XEvent *e)
break;
case MotionNotify:
LOGN("Handling motion notify event");
nx = ocx + (ev.xmotion.x - x);
ny = ocy + (ev.xmotion.y - y);
if (conf.edge_lock)
client_move_relative(c, nx - c->geom.x, ny - c->geom.y);
else
client_move_absolute(c, nx, ny);
if (ev.xbutton.state == (conf.move_mask|Button1Mask) || ev.xbutton.state == Button1Mask) {
nx = ocx + (ev.xmotion.x - x);
ny = ocy + (ev.xmotion.y - y);
if (conf.edge_lock)
client_move_relative(c, nx - c->geom.x, ny - c->geom.y);
else
client_move_absolute(c, nx, ny);
} else if (ev.xbutton.state == (conf.resize_mask|Button1Mask)) {
nw = ev.xmotion.x - x;
nh = ev.xmotion.y - y;
if (conf.edge_lock)
client_resize_relative(c, nw - c->geom.width + ocw, nh - c->geom.height + och);
else
client_resize_absolute(c, ocw + nw, och + nh);
}
break;
}
} while (ev.type != ButtonRelease);
Expand Down Expand Up @@ -1002,6 +1018,16 @@ ipc_config(long *d)
case IPCDecorate:
conf.decorate = d[2];
break;
case IPCMoveMask:
ungrab_buttons();
conf.move_mask = d[2];
grab_buttons();
break;
case IPCResizeMask:
ungrab_buttons();
conf.resize_mask = d[2];
grab_buttons();
break;
default:
break;
}
Expand Down Expand Up @@ -1207,6 +1233,8 @@ manage_new_window(Window w, XWindowAttributes *wa)

XMapWindow(display, c->window);
XSelectInput(display, c->window, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
XGrabButton(display, 1, conf.move_mask, c->window, True, ButtonPressMask|ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None);
XGrabButton(display, 1, conf.resize_mask, c->window, True, ButtonPressMask|ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None);
client_manage_focus(c);
}

Expand Down Expand Up @@ -1240,6 +1268,26 @@ manage_xsend_icccm(struct client *c, Atom atom)
return exists;
}

static void
grab_buttons(void)
{
for (int i = 0; i < WORKSPACE_NUMBER; i++)
for (struct client *tmp = c_list[i]; tmp != NULL; tmp = tmp->next) {
XGrabButton(display, 1, conf.move_mask, tmp->window, True, ButtonPressMask|ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None);
XGrabButton(display, 1, conf.resize_mask, tmp->window, True, ButtonPressMask|ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None);
}
}

static void
ungrab_buttons(void)
{
for (int i = 0; i < WORKSPACE_NUMBER; i++)
for (struct client *tmp = c_list[i]; tmp != NULL; tmp = tmp->next) {
XUngrabButton(display, 1, conf.move_mask, tmp->window);
XUngrabButton(display, 1, conf.resize_mask, tmp->window);
}
}

static void
client_move_absolute(struct client *c, int x, int y)
{
Expand Down Expand Up @@ -1763,6 +1811,8 @@ setup(void)
conf.manage[Splash] = MANAGE_SPLASH;
conf.manage[Utility] = MANAGE_UTILITY;
conf.decorate = DECORATE_NEW;
conf.move_mask = MOVE_MASK;
conf.resize_mask = RESIZE_MASK;

root = DefaultRootWindow(display);
screen = DefaultScreen(display);
Expand Down

0 comments on commit 181b019

Please sign in to comment.