Overhauled window drawing
- Draw onto pixmap as before, but use the same size for the pixmap as for the window, allocate new pixmap after configure requests - Use XCopyArea() instead of XSetWindowBackgroundPixmap(), which now requires handling of Expose events
This commit is contained in:
		
							parent
							
								
									65d5d44696
								
							
						
					
					
						commit
						4a5d5d26aa
					
				
							
								
								
									
										24
									
								
								main.c
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								main.c
									
									
									
									
									
								
							| @ -420,7 +420,7 @@ void run(void) { | |||||||
| 	fd_set fds; | 	fd_set fds; | ||||||
| 	struct timeval timeout; | 	struct timeval timeout; | ||||||
| 	XEvent ev, nextev; | 	XEvent ev, nextev; | ||||||
| 	unsigned int qlen; | 	bool discard; | ||||||
| 
 | 
 | ||||||
| 	redraw(); | 	redraw(); | ||||||
| 
 | 
 | ||||||
| @ -453,10 +453,20 @@ void run(void) { | |||||||
| 
 | 
 | ||||||
| 		do { | 		do { | ||||||
| 			XNextEvent(win.env.dpy, &ev); | 			XNextEvent(win.env.dpy, &ev); | ||||||
| 			qlen = XEventsQueued(win.env.dpy, QueuedAlready); | 			discard = false; | ||||||
| 			if (qlen > 0) | 			if (XEventsQueued(win.env.dpy, QueuedAlready) > 0) { | ||||||
| 				XPeekEvent(win.env.dpy, &nextev); | 				XPeekEvent(win.env.dpy, &nextev); | ||||||
| 		} while (qlen > 0 && ev.type == nextev.type); | 				switch (ev.type) { | ||||||
|  | 					case ConfigureNotify: | ||||||
|  | 						discard = ev.type == nextev.type; | ||||||
|  | 						break; | ||||||
|  | 					case KeyPress: | ||||||
|  | 						discard = (nextev.type == KeyPress || nextev.type == KeyRelease) | ||||||
|  | 						          && ev.xkey.keycode == nextev.xkey.keycode; | ||||||
|  | 						break; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} while (discard); | ||||||
| 
 | 
 | ||||||
| 		switch (ev.type) { | 		switch (ev.type) { | ||||||
| 			/* handle events */ | 			/* handle events */ | ||||||
| @ -482,9 +492,11 @@ void run(void) { | |||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
|  | 			case Expose: | ||||||
|  | 				win_expose(&win, &ev.xexpose); | ||||||
|  | 				break; | ||||||
| 			case KeyPress: | 			case KeyPress: | ||||||
| 				if (qlen == 0 || ev.xkey.keycode != nextev.xkey.keycode) | 				on_keypress(&ev.xkey); | ||||||
| 					on_keypress(&ev.xkey); |  | ||||||
| 				break; | 				break; | ||||||
| 			case MotionNotify: | 			case MotionNotify: | ||||||
| 				if (mode == MODE_IMAGE) { | 				if (mode == MODE_IMAGE) { | ||||||
|  | |||||||
							
								
								
									
										39
									
								
								window.c
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								window.c
									
									
									
									
									
								
							| @ -188,8 +188,9 @@ void win_open(win_t *win) { | |||||||
| 	if (win->xwin == None) | 	if (win->xwin == None) | ||||||
| 		die("could not create window"); | 		die("could not create window"); | ||||||
| 	 | 	 | ||||||
| 	XSelectInput(e->dpy, win->xwin, StructureNotifyMask | KeyPressMask | | 	XSelectInput(e->dpy, win->xwin, | ||||||
| 	             ButtonPressMask | ButtonReleaseMask | PointerMotionMask); | 	             ExposureMask | ButtonReleaseMask | ButtonPressMask | | ||||||
|  | 	             KeyPressMask | PointerMotionMask | StructureNotifyMask); | ||||||
| 
 | 
 | ||||||
| 	carrow = XCreateFontCursor(e->dpy, XC_left_ptr); | 	carrow = XCreateFontCursor(e->dpy, XC_left_ptr); | ||||||
| 	chand = XCreateFontCursor(e->dpy, XC_fleur); | 	chand = XCreateFontCursor(e->dpy, XC_fleur); | ||||||
| @ -246,10 +247,15 @@ void win_close(win_t *win) { | |||||||
| bool win_configure(win_t *win, XConfigureEvent *c) { | bool win_configure(win_t *win, XConfigureEvent *c) { | ||||||
| 	bool changed; | 	bool changed; | ||||||
| 
 | 
 | ||||||
| 	if (win == NULL) | 	if (win == NULL || c == NULL) | ||||||
| 		return false; | 		return false; | ||||||
| 	 | 	 | ||||||
| 	changed = win->w != c->width || win->h + win->barh != c->height; | 	if ((changed = win->w != c->width || win->h + win->barh != c->height)) { | ||||||
|  | 		if (win->pm != None) { | ||||||
|  | 			XFreePixmap(win->env.dpy, win->pm); | ||||||
|  | 			win->pm = None; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	win->x = c->x; | 	win->x = c->x; | ||||||
| 	win->y = c->y; | 	win->y = c->y; | ||||||
| @ -260,6 +266,15 @@ bool win_configure(win_t *win, XConfigureEvent *c) { | |||||||
| 	return changed; | 	return changed; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void win_expose(win_t *win, XExposeEvent *e) { | ||||||
|  | 	if (win == NULL || win->xwin == None || e == NULL) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	if (win->pm != None) | ||||||
|  | 		XCopyArea(win->env.dpy, win->pm, win->xwin, gc, | ||||||
|  | 		          e->x, e->y, e->width, e->height, e->x, e->y); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| bool win_moveresize(win_t *win, int x, int y, unsigned int w, unsigned int h) { | bool win_moveresize(win_t *win, int x, int y, unsigned int w, unsigned int h) { | ||||||
| 	if (win == NULL || win->xwin == None) | 	if (win == NULL || win->xwin == None) | ||||||
| 		return false; | 		return false; | ||||||
| @ -323,19 +338,20 @@ void win_toggle_bar(win_t *win) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void win_clear(win_t *win) { | void win_clear(win_t *win) { | ||||||
|  | 	int h; | ||||||
| 	win_env_t *e; | 	win_env_t *e; | ||||||
| 
 | 
 | ||||||
| 	if (win == NULL || win->xwin == None) | 	if (win == NULL || win->xwin == None) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
|  | 	h = win->h + win->barh; | ||||||
| 	e = &win->env; | 	e = &win->env; | ||||||
| 
 | 
 | ||||||
| 	if (win->pm != None) | 	if (win->pm == None) | ||||||
| 		XFreePixmap(e->dpy, win->pm); | 		win->pm = XCreatePixmap(e->dpy, win->xwin, win->w, h, e->depth); | ||||||
| 	win->pm = XCreatePixmap(e->dpy, win->xwin, e->scrw, e->scrh, e->depth); |  | ||||||
| 
 | 
 | ||||||
| 	XSetForeground(e->dpy, gc, win->fullscreen ? win->fscol : win->bgcol); | 	XSetForeground(e->dpy, gc, win->fullscreen ? win->fscol : win->bgcol); | ||||||
| 	XFillRectangle(e->dpy, win->pm, gc, 0, 0, e->scrw, e->scrh); | 	XFillRectangle(e->dpy, win->pm, gc, 0, 0, win->w, h); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void win_draw_bar(win_t *win) { | void win_draw_bar(win_t *win) { | ||||||
| @ -397,12 +413,13 @@ void win_draw(win_t *win) { | |||||||
| 	if (win->barh > 0) | 	if (win->barh > 0) | ||||||
| 		win_draw_bar(win); | 		win_draw_bar(win); | ||||||
| 
 | 
 | ||||||
| 	XSetWindowBackgroundPixmap(win->env.dpy, win->xwin, win->pm); | 	XCopyArea(win->env.dpy, win->pm, win->xwin, gc, | ||||||
| 	XClearWindow(win->env.dpy, win->xwin); | 	          0, 0, win->w, win->h + win->barh, 0, 0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void win_draw_rect(win_t *win, Pixmap pm, int x, int y, int w, int h, | void win_draw_rect(win_t *win, Pixmap pm, int x, int y, int w, int h, | ||||||
| 		bool fill, int lw, unsigned long col) { |                    bool fill, int lw, unsigned long col) | ||||||
|  | { | ||||||
| 	XGCValues gcval; | 	XGCValues gcval; | ||||||
| 
 | 
 | ||||||
| 	if (win == NULL || pm == None) | 	if (win == NULL || pm == None) | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								window.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								window.h
									
									
									
									
									
								
							| @ -66,6 +66,7 @@ void win_open(win_t*); | |||||||
| void win_close(win_t*); | void win_close(win_t*); | ||||||
| 
 | 
 | ||||||
| bool win_configure(win_t*, XConfigureEvent*); | bool win_configure(win_t*, XConfigureEvent*); | ||||||
|  | void win_expose(win_t*, XExposeEvent*); | ||||||
| bool win_moveresize(win_t*, int, int, unsigned int, unsigned int); | bool win_moveresize(win_t*, int, int, unsigned int, unsigned int); | ||||||
| 
 | 
 | ||||||
| void win_toggle_fullscreen(win_t*); | void win_toggle_fullscreen(win_t*); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Bert Münnich
						Bert Münnich