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:
		
							
								
								
									
										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*);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user