added mouse-based resizals
This commit is contained in:
		
							parent
							
								
									5ed16faecb
								
							
						
					
					
						commit
						b9da4b082e
					
				
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @ -3,7 +3,7 @@ | |||||||
| 
 | 
 | ||||||
| include config.mk | include config.mk | ||||||
| 
 | 
 | ||||||
| WMSRC = bar.c client.c cmd.c draw.c event.c key.c util.c wm.c | WMSRC = bar.c client.c cmd.c draw.c event.c kb.c mouse.c util.c wm.c | ||||||
| WMOBJ = ${WMSRC:.c=.o} | WMOBJ = ${WMSRC:.c=.o} | ||||||
| MENSRC = menu.c draw.c util.c | MENSRC = menu.c draw.c util.c | ||||||
| MENOBJ = ${MENSRC:.c=.o} | MENOBJ = ${MENSRC:.c=.o} | ||||||
|  | |||||||
							
								
								
									
										10
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								README
									
									
									
									
									
								
							| @ -5,14 +5,6 @@ gridwm is an extremly fast, small, and automatic X11 window manager.  It | |||||||
| arranges all windows in a grid. | arranges all windows in a grid. | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| Configuration |  | ||||||
| ------------- |  | ||||||
| You have to edit the source code for configuration, this WM is intended to |  | ||||||
| provide sane defaults, if something doesn't fits your needs, edit config.h and |  | ||||||
| maybe key.c. To change the status output edit that status variable definition |  | ||||||
| in wm.c. |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| Requirements | Requirements | ||||||
| ------------ | ------------ | ||||||
| In order to build gridwm you need the Xlib header files. | In order to build gridwm you need the Xlib header files. | ||||||
| @ -46,6 +38,6 @@ This will start gridwm on display :1 of the host foo.bar. | |||||||
| Configuration | Configuration | ||||||
| ------------- | ------------- | ||||||
| The configuration of gridwm is done by customizing the config.h source file. To | The configuration of gridwm is done by customizing the config.h source file. To | ||||||
| customize the key bindings edit key.c. To change the status output, edit the | customize the key bindings edit kb.c. To change the status output, edit the | ||||||
| status command definition in wm.c. | status command definition in wm.c. | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										32
									
								
								client.c
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								client.c
									
									
									
									
									
								
							| @ -10,6 +10,8 @@ | |||||||
| #include "util.h" | #include "util.h" | ||||||
| #include "wm.h" | #include "wm.h" | ||||||
| 
 | 
 | ||||||
|  | #define CLIENT_MASK		(StructureNotifyMask | PropertyChangeMask | EnterWindowMask) | ||||||
|  | 
 | ||||||
| void | void | ||||||
| update_name(Client *c) | update_name(Client *c) | ||||||
| { | { | ||||||
| @ -70,7 +72,7 @@ manage(Window w, XWindowAttributes *wa) | |||||||
| 	c->r[RFloat].height = wa->height; | 	c->r[RFloat].height = wa->height; | ||||||
| 	c->border = wa->border_width; | 	c->border = wa->border_width; | ||||||
| 	XSetWindowBorderWidth(dpy, c->win, 0); | 	XSetWindowBorderWidth(dpy, c->win, 0); | ||||||
| 	XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | EnterWindowMask); | 	XSelectInput(dpy, c->win, CLIENT_MASK); | ||||||
| 	XGetTransientForHint(dpy, c->win, &c->trans); | 	XGetTransientForHint(dpy, c->win, &c->trans); | ||||||
| 	if(!XGetWMNormalHints(dpy, c->win, &c->size, &msize) || !c->size.flags) | 	if(!XGetWMNormalHints(dpy, c->win, &c->size, &msize) || !c->size.flags) | ||||||
| 		c->size.flags = PSize; | 		c->size.flags = PSize; | ||||||
| @ -95,9 +97,34 @@ manage(Window w, XWindowAttributes *wa) | |||||||
| 	c->snext = stack; | 	c->snext = stack; | ||||||
| 	stack = c; | 	stack = c; | ||||||
| 	XMapWindow(dpy, c->win); | 	XMapWindow(dpy, c->win); | ||||||
|  | 	XGrabButton(dpy, AnyButton, Mod1Mask, c->win, False, ButtonPressMask, | ||||||
|  | 			GrabModeAsync, GrabModeSync, None, None); | ||||||
| 	focus(c); | 	focus(c); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void | ||||||
|  | resize(Client *c) | ||||||
|  | { | ||||||
|  | 	XConfigureEvent e; | ||||||
|  | 
 | ||||||
|  | 	XMoveResizeWindow(dpy, c->win, c->r[RFloat].x, c->r[RFloat].y, | ||||||
|  | 			c->r[RFloat].width, c->r[RFloat].height); | ||||||
|  | 	e.type = ConfigureNotify; | ||||||
|  | 	e.event = c->win; | ||||||
|  | 	e.window = c->win; | ||||||
|  | 	e.x = c->r[RFloat].x; | ||||||
|  | 	e.y = c->r[RFloat].y; | ||||||
|  | 	e.width = c->r[RFloat].width; | ||||||
|  | 	e.height = c->r[RFloat].height; | ||||||
|  | 	e.border_width = c->border; | ||||||
|  | 	e.above = None; | ||||||
|  | 	e.override_redirect = False; | ||||||
|  | 	XSelectInput(dpy, c->win, CLIENT_MASK & ~StructureNotifyMask); | ||||||
|  | 	XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&e); | ||||||
|  | 	XSelectInput(dpy, c->win, CLIENT_MASK); | ||||||
|  | 	XFlush(dpy); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static int | static int | ||||||
| dummy_error_handler(Display *dpy, XErrorEvent *error) | dummy_error_handler(Display *dpy, XErrorEvent *error) | ||||||
| { | { | ||||||
| @ -112,6 +139,7 @@ unmanage(Client *c) | |||||||
| 	XGrabServer(dpy); | 	XGrabServer(dpy); | ||||||
| 	XSetErrorHandler(dummy_error_handler); | 	XSetErrorHandler(dummy_error_handler); | ||||||
| 
 | 
 | ||||||
|  | 	XUngrabButton(dpy, AnyButton, AnyModifier, c->win); | ||||||
| 	XUnmapWindow(dpy, c->win); | 	XUnmapWindow(dpy, c->win); | ||||||
| 	XDestroyWindow(dpy, c->title); | 	XDestroyWindow(dpy, c->title); | ||||||
| 
 | 
 | ||||||
| @ -126,7 +154,7 @@ unmanage(Client *c) | |||||||
| 	XFlush(dpy); | 	XFlush(dpy); | ||||||
| 	XSetErrorHandler(error_handler); | 	XSetErrorHandler(error_handler); | ||||||
| 	XUngrabServer(dpy); | 	XUngrabServer(dpy); | ||||||
| 	flush_events(EnterWindowMask); | 	discard_events(EnterWindowMask); | ||||||
| 	if(stack) | 	if(stack) | ||||||
| 		focus(stack); | 		focus(stack); | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										30
									
								
								event.c
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								event.c
									
									
									
									
									
								
							| @ -12,6 +12,7 @@ | |||||||
| #include "wm.h" | #include "wm.h" | ||||||
| 
 | 
 | ||||||
| /* local functions */ | /* local functions */ | ||||||
|  | static void buttonpress(XEvent *e); | ||||||
| static void configurerequest(XEvent *e); | static void configurerequest(XEvent *e); | ||||||
| static void destroynotify(XEvent *e); | static void destroynotify(XEvent *e); | ||||||
| static void enternotify(XEvent *e); | static void enternotify(XEvent *e); | ||||||
| @ -23,6 +24,7 @@ static void propertynotify(XEvent *e); | |||||||
| static void unmapnotify(XEvent *e); | static void unmapnotify(XEvent *e); | ||||||
| 
 | 
 | ||||||
| void (*handler[LASTEvent]) (XEvent *) = { | void (*handler[LASTEvent]) (XEvent *) = { | ||||||
|  | 	[ButtonPress] = buttonpress, | ||||||
| 	[ConfigureRequest] = configurerequest, | 	[ConfigureRequest] = configurerequest, | ||||||
| 	[DestroyNotify] = destroynotify, | 	[DestroyNotify] = destroynotify, | ||||||
| 	[EnterNotify] = enternotify, | 	[EnterNotify] = enternotify, | ||||||
| @ -36,7 +38,7 @@ void (*handler[LASTEvent]) (XEvent *) = { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| unsigned int | unsigned int | ||||||
| flush_events(long even_mask) | discard_events(long even_mask) | ||||||
| { | { | ||||||
| 	XEvent ev; | 	XEvent ev; | ||||||
| 	unsigned int n = 0; | 	unsigned int n = 0; | ||||||
| @ -44,6 +46,29 @@ flush_events(long even_mask) | |||||||
| 	return n; | 	return n; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void | ||||||
|  | buttonpress(XEvent *e) | ||||||
|  | { | ||||||
|  | 	XButtonPressedEvent *ev = &e->xbutton; | ||||||
|  | 	Client *c; | ||||||
|  | 
 | ||||||
|  | 	if((c = getclient(ev->window))) { | ||||||
|  | 		switch(ev->button) { | ||||||
|  | 		default: | ||||||
|  | 			break; | ||||||
|  | 		case Button1: | ||||||
|  | 			mmove(c); | ||||||
|  | 			break; | ||||||
|  | 		case Button2: | ||||||
|  | 			XLowerWindow(dpy, c->win); | ||||||
|  | 			break; | ||||||
|  | 		case Button3: | ||||||
|  | 			mresize(c); | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void | static void | ||||||
| configurerequest(XEvent *e) | configurerequest(XEvent *e) | ||||||
| { | { | ||||||
| @ -51,9 +76,8 @@ configurerequest(XEvent *e) | |||||||
| 	XWindowChanges wc; | 	XWindowChanges wc; | ||||||
| 	Client *c; | 	Client *c; | ||||||
| 
 | 
 | ||||||
| 	c = getclient(ev->window); |  | ||||||
| 	ev->value_mask &= ~CWSibling; | 	ev->value_mask &= ~CWSibling; | ||||||
| 	if(c) { | 	if((c = getclient(ev->window))) { | ||||||
| 		if(ev->value_mask & CWX) | 		if(ev->value_mask & CWX) | ||||||
| 			c->r[RFloat].x = ev->x; | 			c->r[RFloat].x = ev->x; | ||||||
| 		if(ev->value_mask & CWY) | 		if(ev->value_mask & CWY) | ||||||
|  | |||||||
							
								
								
									
										100
									
								
								mouse.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								mouse.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,100 @@ | |||||||
|  | /*
 | ||||||
|  |  * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> | ||||||
|  |  * (C)opyright MMVI Kris Maglione <fbsdaemon@gmail.com> | ||||||
|  |  * See LICENSE file for license details. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | 
 | ||||||
|  | #include "wm.h" | ||||||
|  | 
 | ||||||
|  | #define ButtonMask      (ButtonPressMask | ButtonReleaseMask) | ||||||
|  | #define MouseMask       (ButtonMask | PointerMotionMask) | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | mmatch(Client *c, int x1, int y1, int x2, int y2) | ||||||
|  | { | ||||||
|  | 	c->r[RFloat].width = abs(x1 - x2); | ||||||
|  | 	c->r[RFloat].height = abs(y1 - y2); | ||||||
|  | 	c->r[RFloat].width -= | ||||||
|  | 		(c->r[RFloat].width - c->size.base_width) % c->size.width_inc; | ||||||
|  | 	c->r[RFloat].height -= | ||||||
|  | 		(c->r[RFloat].height - c->size.base_height) % c->size.height_inc; | ||||||
|  | 	if(c->size.min_width && c->r[RFloat].width < c->size.min_width) | ||||||
|  | 		c->r[RFloat].width = c->size.min_width; | ||||||
|  | 	if(c->size.min_height && c->r[RFloat].height < c->size.min_height) | ||||||
|  | 		c->r[RFloat].height = c->size.min_height; | ||||||
|  | 	if(c->size.max_width && c->r[RFloat].width > c->size.max_width) | ||||||
|  | 		c->r[RFloat].width = c->size.max_width; | ||||||
|  | 	if(c->size.max_height && c->r[RFloat].height > c->size.max_height) | ||||||
|  | 		c->r[RFloat].height = c->size.max_height; | ||||||
|  | 	c->r[RFloat].x = (x1 <= x2) ? x1 : x1 - c->r[RFloat].width; | ||||||
|  | 	c->r[RFloat].y = (y1 <= y2) ? y1 : y1 - c->r[RFloat].height; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | mresize(Client *c) | ||||||
|  | { | ||||||
|  | 	XEvent ev; | ||||||
|  | 	int old_cx, old_cy; | ||||||
|  | 
 | ||||||
|  | 	old_cx = c->r[RFloat].x; | ||||||
|  | 	old_cy = c->r[RFloat].y; | ||||||
|  | 	if(XGrabPointer(dpy, c->win, False, MouseMask, GrabModeAsync, GrabModeAsync, | ||||||
|  | 				None, cursor[CurResize], CurrentTime) != GrabSuccess) | ||||||
|  | 		return; | ||||||
|  | 	XGrabServer(dpy); | ||||||
|  | 	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, | ||||||
|  | 			c->r[RFloat].width, c->r[RFloat].height); | ||||||
|  | 	for(;;) { | ||||||
|  | 		XMaskEvent(dpy, MouseMask, &ev); | ||||||
|  | 		switch(ev.type) { | ||||||
|  | 		default: break; | ||||||
|  | 		case MotionNotify: | ||||||
|  | 			XUngrabServer(dpy); | ||||||
|  | 			mmatch(c, old_cx, old_cy, ev.xmotion.x, ev.xmotion.y); | ||||||
|  | 			resize(c); | ||||||
|  | 			XGrabServer(dpy); | ||||||
|  | 			break; | ||||||
|  | 		case ButtonRelease: | ||||||
|  | 			XUngrabPointer(dpy, CurrentTime); | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | mmove(Client *c) | ||||||
|  | { | ||||||
|  | 	XEvent ev; | ||||||
|  | 	int x1, y1, old_cx, old_cy, di; | ||||||
|  | 	unsigned int dui; | ||||||
|  | 	Window dummy; | ||||||
|  | 
 | ||||||
|  | 	old_cx = c->r[RFloat].x; | ||||||
|  | 	old_cy = c->r[RFloat].y; | ||||||
|  | 	if(XGrabPointer(dpy, c->win, False, MouseMask, GrabModeAsync, GrabModeAsync, | ||||||
|  | 				None, cursor[CurMove], CurrentTime) != GrabSuccess) | ||||||
|  | 		return; | ||||||
|  | 	XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui); | ||||||
|  | 	XGrabServer(dpy); | ||||||
|  | 	for(;;) { | ||||||
|  | 		XMaskEvent(dpy, MouseMask, &ev); | ||||||
|  | 		switch (ev.type) { | ||||||
|  | 		default: break; | ||||||
|  | 		case MotionNotify: | ||||||
|  | 			XUngrabServer(dpy); | ||||||
|  | 			c->r[RFloat].x = old_cx + (ev.xmotion.x - x1); | ||||||
|  | 			c->r[RFloat].y = old_cy + (ev.xmotion.y - y1); | ||||||
|  | 			resize(c); | ||||||
|  | 			XGrabServer(dpy); | ||||||
|  | 			break; | ||||||
|  | 		case ButtonRelease: | ||||||
|  | 			XUngrabServer(dpy); | ||||||
|  | 			XUngrabPointer(dpy, CurrentTime); | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										26
									
								
								wm.h
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								wm.h
									
									
									
									
									
								
							| @ -11,6 +11,22 @@ | |||||||
| 
 | 
 | ||||||
| #define WM_PROTOCOL_DELWIN 1 | #define WM_PROTOCOL_DELWIN 1 | ||||||
| 
 | 
 | ||||||
|  | typedef struct Client Client; | ||||||
|  | typedef struct Key Key; | ||||||
|  | typedef enum Align Align; | ||||||
|  | 
 | ||||||
|  | enum Align { | ||||||
|  | 	NORTH = 0x01, | ||||||
|  | 	EAST  = 0x02, | ||||||
|  | 	SOUTH = 0x04, | ||||||
|  | 	WEST  = 0x08, | ||||||
|  | 	NEAST = NORTH | EAST, | ||||||
|  | 	NWEST = NORTH | WEST, | ||||||
|  | 	SEAST = SOUTH | EAST, | ||||||
|  | 	SWEST = SOUTH | WEST, | ||||||
|  | 	CENTER = NEAST | SWEST | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| /* atoms */ | /* atoms */ | ||||||
| enum { WMProtocols, WMDelete, WMLast }; | enum { WMProtocols, WMDelete, WMLast }; | ||||||
| enum { NetSupported, NetWMName, NetLast }; | enum { NetSupported, NetWMName, NetLast }; | ||||||
| @ -21,9 +37,6 @@ enum { CurNormal, CurResize, CurMove, CurInput, CurLast }; | |||||||
| /* rects */ | /* rects */ | ||||||
| enum { RFloat, RGrid, RLast }; | enum { RFloat, RGrid, RLast }; | ||||||
| 
 | 
 | ||||||
| typedef struct Client Client; |  | ||||||
| typedef struct Key Key; |  | ||||||
| 
 |  | ||||||
| struct Client { | struct Client { | ||||||
| 	char name[256]; | 	char name[256]; | ||||||
| 	char tag[256]; | 	char tag[256]; | ||||||
| @ -75,14 +88,19 @@ extern Client *getclient(Window w); | |||||||
| extern void focus(Client *c); | extern void focus(Client *c); | ||||||
| extern void update_name(Client *c); | extern void update_name(Client *c); | ||||||
| extern void draw_client(Client *c); | extern void draw_client(Client *c); | ||||||
|  | extern void resize(Client *c); | ||||||
| 
 | 
 | ||||||
| /* event.c */ | /* event.c */ | ||||||
| extern unsigned int flush_events(long even_mask); | extern unsigned int discard_events(long even_mask); | ||||||
| 
 | 
 | ||||||
| /* key.c */ | /* key.c */ | ||||||
| extern void update_keys(); | extern void update_keys(); | ||||||
| extern void keypress(XEvent *e); | extern void keypress(XEvent *e); | ||||||
| 
 | 
 | ||||||
|  | /* mouse.c */ | ||||||
|  | extern void mresize(Client *c); | ||||||
|  | extern void mmove(Client *c); | ||||||
|  | 
 | ||||||
| /* wm.c */ | /* wm.c */ | ||||||
| extern int error_handler(Display *dpy, XErrorEvent *error); | extern int error_handler(Display *dpy, XErrorEvent *error); | ||||||
| extern void send_message(Window w, Atom a, long value); | extern void send_message(Window w, Atom a, long value); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user