nsxiv0f714bc
Handle window resize events properly
+63 −32
4 files changed
| @@ -65,6 +65,9 @@ int img_load(img_t *img, const char *filename) { | |||
| 65 | 65 | imlib_context_set_image(im); | |
| 66 | 66 | ||
| 67 | 67 | img->re = 0; | |
| 68 | + | img->checkpan = 0; | |
| 69 | + | img->zoomed = 0; | |
| 70 | + | ||
| 68 | 71 | img->w = imlib_image_get_width(); | |
| 69 | 72 | img->h = imlib_image_get_height(); | |
| 70 | 73 | ||
| @@ -101,32 +104,32 @@ void img_render(img_t *img, win_t *win) { | |||
| 101 | 104 | if (!img || !win || !imlib_context_get_image()) | |
| 102 | 105 | return; | |
| 103 | 106 | ||
| 104 | − | if (!img->re) { | |
| 105 | − | /* rendered for the first time */ | |
| 106 | − | img->re = 1; | |
| 107 | − | ||
| 107 | + | if ((!img->re || !img->zoomed) && SCALE_MODE != SCALE_ZOOM) { | |
| 108 | 108 | /* set zoom level to fit image into window */ | |
| 109 | − | if (SCALE_MODE != SCALE_ZOOM) { | |
| 110 | − | zw = (float) win->w / (float) img->w; | |
| 111 | − | zh = (float) win->h / (float) img->h; | |
| 112 | − | img->zoom = MIN(zw, zh); | |
| 109 | + | zw = (float) win->w / (float) img->w; | |
| 110 | + | zh = (float) win->h / (float) img->h; | |
| 111 | + | img->zoom = MIN(zw, zh); | |
| 113 | 112 | ||
| 114 | − | if (img->zoom < zoom_min) | |
| 115 | − | img->zoom = zoom_min; | |
| 116 | − | else if (img->zoom > zoom_max) | |
| 117 | − | img->zoom = zoom_max; | |
| 113 | + | if (img->zoom < zoom_min) | |
| 114 | + | img->zoom = zoom_min; | |
| 115 | + | else if (img->zoom > zoom_max) | |
| 116 | + | img->zoom = zoom_max; | |
| 118 | 117 | ||
| 119 | − | if (SCALE_MODE == SCALE_DOWN && img->zoom > 1.0) | |
| 120 | − | img->zoom = 1.0; | |
| 121 | − | } | |
| 118 | + | if (SCALE_MODE == SCALE_DOWN && img->zoom > 1.0) | |
| 119 | + | img->zoom = 1.0; | |
| 120 | + | } | |
| 122 | 121 | ||
| 122 | + | if (!img->re) { | |
| 123 | + | /* rendered for the first time */ | |
| 124 | + | img->re = 1; | |
| 123 | 125 | /* center image in window */ | |
| 124 | 126 | img->x = (win->w - img->w * img->zoom) / 2; | |
| 125 | 127 | img->y = (win->h - img->h * img->zoom) / 2; | |
| 126 | − | } else if (img->cp) { | |
| 127 | − | /* only useful after zooming */ | |
| 128 | + | } | |
| 129 | + | ||
| 130 | + | if (img->checkpan) { | |
| 128 | 131 | img_check_pan(img, win); | |
| 129 | − | img->cp = 0; | |
| 132 | + | img->checkpan = 0; | |
| 130 | 133 | } | |
| 131 | 134 | ||
| 132 | 135 | /* calculate source and destination offsets */ | |
| @@ -174,7 +177,8 @@ int img_zoom(img_t *img, float z) { | |||
| 174 | 177 | img->x -= (img->w * z - img->w * img->zoom) / 2; | |
| 175 | 178 | img->y -= (img->h * z - img->h * img->zoom) / 2; | |
| 176 | 179 | img->zoom = z; | |
| 177 | − | img->cp = 1; | |
| 180 | + | img->checkpan = 1; | |
| 181 | + | img->zoomed = 1; | |
| 178 | 182 | return 1; | |
| 179 | 183 | } else { | |
| 180 | 184 | return 0; | |
| @@ -37,7 +37,8 @@ typedef enum pandir_e { | |||
| 37 | 37 | typedef struct img_s { | |
| 38 | 38 | float zoom; | |
| 39 | 39 | unsigned char re; | |
| 40 | − | unsigned char cp; | |
| 40 | + | unsigned char checkpan; | |
| 41 | + | unsigned char zoomed; | |
| 41 | 42 | int x; | |
| 42 | 43 | int y; | |
| 43 | 44 | int w; | |
| @@ -18,6 +18,7 @@ | |||
| 18 | 18 | ||
| 19 | 19 | #include <stdlib.h> | |
| 20 | 20 | #include <stdio.h> | |
| 21 | + | #include <sys/select.h> | |
| 21 | 22 | ||
| 22 | 23 | #include <X11/Xlib.h> | |
| 23 | 24 | #include <X11/Xutil.h> | |
| @@ -45,14 +46,34 @@ const char **filenames; | |||
| 45 | 46 | unsigned int filecnt; | |
| 46 | 47 | unsigned int fileidx; | |
| 47 | 48 | ||
| 49 | + | unsigned char timeout; | |
| 50 | + | ||
| 48 | 51 | #define TITLE_LEN 256 | |
| 49 | 52 | char win_title[TITLE_LEN]; | |
| 50 | 53 | ||
| 51 | 54 | void run() { | |
| 55 | + | int xfd; | |
| 56 | + | fd_set fds; | |
| 57 | + | struct timeval t; | |
| 52 | 58 | XEvent ev; | |
| 53 | 59 | ||
| 54 | − | while (!XNextEvent(win.env.dpy, &ev)) { | |
| 55 | − | if (handler[ev.type]) | |
| 60 | + | timeout = 0; | |
| 61 | + | ||
| 62 | + | while (1) { | |
| 63 | + | if (timeout) { | |
| 64 | + | t.tv_sec = 0; | |
| 65 | + | t.tv_usec = 250; | |
| 66 | + | xfd = ConnectionNumber(win.env.dpy); | |
| 67 | + | FD_ZERO(&fds); | |
| 68 | + | FD_SET(xfd, &fds); | |
| 69 | + | ||
| 70 | + | if (!XPending(win.env.dpy) && !select(xfd + 1, &fds, 0, 0, &t)) { | |
| 71 | + | img_render(&img, &win); | |
| 72 | + | timeout = 0; | |
| 73 | + | } | |
| 74 | + | } | |
| 75 | + | ||
| 76 | + | if (!XNextEvent(win.env.dpy, &ev) && handler[ev.type]) | |
| 56 | 77 | handler[ev.type](&ev); | |
| 57 | 78 | } | |
| 58 | 79 | } | |
| @@ -175,14 +196,18 @@ void on_keypress(XEvent *ev) { | |||
| 175 | 196 | if (changed) { | |
| 176 | 197 | img_render(&img, &win); | |
| 177 | 198 | update_title(); | |
| 199 | + | timeout = 0; | |
| 178 | 200 | } | |
| 179 | 201 | } | |
| 180 | 202 | ||
| 181 | 203 | void on_configurenotify(XEvent *ev) { | |
| 182 | 204 | if (!ev) | |
| 183 | 205 | return; | |
| 184 | − | ||
| 185 | − | win_configure(&win, &ev->xconfigure); | |
| 206 | + | ||
| 207 | + | if (win_configure(&win, &ev->xconfigure)) { | |
| 208 | + | img.checkpan = 1; | |
| 209 | + | timeout = 1; | |
| 210 | + | } | |
| 186 | 211 | } | |
| 187 | 212 | ||
| 188 | 213 | void update_title() { | |
| @@ -102,19 +102,20 @@ void win_set_title(win_t *win, const char *title) { | |||
| 102 | 102 | XSetIconName(win->env.dpy, win->xwin, title); | |
| 103 | 103 | } | |
| 104 | 104 | ||
| 105 | − | int win_configure(win_t *win, XConfigureEvent *cev) { | |
| 105 | + | int win_configure(win_t *win, XConfigureEvent *c) { | |
| 106 | 106 | int changed; | |
| 107 | 107 | ||
| 108 | 108 | if (!win) | |
| 109 | 109 | return 0; | |
| 110 | 110 | ||
| 111 | − | changed = win->x != cev->x || win->y != cev->y || | |
| 112 | − | win->w != cev->width || win->h != cev->height; | |
| 113 | − | win->x = cev->x; | |
| 114 | − | win->y = cev->y; | |
| 115 | − | win->w = cev->width; | |
| 116 | − | win->h = cev->height; | |
| 117 | − | win->bw = cev->border_width; | |
| 111 | + | changed = win->w != c->width || win->h != c->height; | |
| 112 | + | ||
| 113 | + | win->x = c->x; | |
| 114 | + | win->y = c->y; | |
| 115 | + | win->w = c->width; | |
| 116 | + | win->h = c->height; | |
| 117 | + | win->bw = c->border_width; | |
| 118 | + | ||
| 118 | 119 | return changed; | |
| 119 | 120 | } | |
| 120 | 121 | ||