diff options
-rw-r--r-- | client/pool-buffer.c | 46 | ||||
-rw-r--r-- | include/pool-buffer.h | 2 | ||||
-rw-r--r-- | include/sway/criteria.h | 1 | ||||
-rw-r--r-- | include/sway/tree/view.h | 2 | ||||
-rw-r--r-- | include/swaylock/swaylock.h | 3 | ||||
-rw-r--r-- | sway/criteria.c | 18 | ||||
-rw-r--r-- | sway/desktop/xdg_shell.c | 12 | ||||
-rw-r--r-- | sway/sway.5.scd | 5 | ||||
-rw-r--r-- | sway/tree/view.c | 10 | ||||
-rw-r--r-- | swaylock/main.c | 56 | ||||
-rw-r--r-- | swaylock/password.c | 102 | ||||
-rw-r--r-- | swaylock/render.c | 4 |
12 files changed, 185 insertions, 76 deletions
diff --git a/client/pool-buffer.c b/client/pool-buffer.c index 1f54a77c..52438303 100644 --- a/client/pool-buffer.c +++ b/client/pool-buffer.c | |||
@@ -1,37 +1,56 @@ | |||
1 | #define _XOPEN_SOURCE 500 | 1 | #define _XOPEN_SOURCE 500 |
2 | #include <assert.h> | 2 | #include <assert.h> |
3 | #include <cairo/cairo.h> | 3 | #include <cairo/cairo.h> |
4 | #include <fcntl.h> | ||
5 | #include <pango/pangocairo.h> | ||
4 | #include <stdio.h> | 6 | #include <stdio.h> |
5 | #include <stdlib.h> | 7 | #include <stdlib.h> |
6 | #include <string.h> | 8 | #include <string.h> |
7 | #include <sys/mman.h> | 9 | #include <sys/mman.h> |
8 | #include <pango/pangocairo.h> | ||
9 | #include <unistd.h> | 10 | #include <unistd.h> |
10 | #include <wayland-client.h> | 11 | #include <wayland-client.h> |
11 | #include "config.h" | 12 | #include "config.h" |
12 | #include "pool-buffer.h" | 13 | #include "pool-buffer.h" |
13 | 14 | ||
15 | static bool set_cloexec(int fd) { | ||
16 | long flags = fcntl(fd, F_GETFD); | ||
17 | if (flags == -1) { | ||
18 | return false; | ||
19 | } | ||
20 | |||
21 | if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) { | ||
22 | return false; | ||
23 | } | ||
24 | |||
25 | return true; | ||
26 | } | ||
27 | |||
14 | static int create_pool_file(size_t size, char **name) { | 28 | static int create_pool_file(size_t size, char **name) { |
15 | static const char template[] = "sway-client-XXXXXX"; | 29 | static const char template[] = "sway-client-XXXXXX"; |
16 | const char *path = getenv("XDG_RUNTIME_DIR"); | 30 | const char *path = getenv("XDG_RUNTIME_DIR"); |
17 | if (!path) { | 31 | if (path == NULL) { |
32 | fprintf(stderr, "XDG_RUNTIME_DIR is not set\n"); | ||
18 | return -1; | 33 | return -1; |
19 | } | 34 | } |
20 | 35 | ||
21 | int ts = (path[strlen(path) - 1] == '/'); | 36 | size_t name_size = strlen(template) + 1 + strlen(path) + 1; |
22 | 37 | *name = malloc(name_size); | |
23 | *name = malloc( | 38 | if (*name == NULL) { |
24 | strlen(template) + | 39 | fprintf(stderr, "allocation failed\n"); |
25 | strlen(path) + | 40 | return -1; |
26 | (ts ? 0 : 1) + 1); | 41 | } |
27 | sprintf(*name, "%s%s%s", path, ts ? "" : "/", template); | 42 | snprintf(*name, name_size, "%s/%s", path, template); |
28 | 43 | ||
29 | int fd = mkstemp(*name); | 44 | int fd = mkstemp(*name); |
30 | |||
31 | if (fd < 0) { | 45 | if (fd < 0) { |
32 | return -1; | 46 | return -1; |
33 | } | 47 | } |
34 | 48 | ||
49 | if (!set_cloexec(fd)) { | ||
50 | close(fd); | ||
51 | return -1; | ||
52 | } | ||
53 | |||
35 | if (ftruncate(fd, size) < 0) { | 54 | if (ftruncate(fd, size) < 0) { |
36 | close(fd); | 55 | close(fd); |
37 | return -1; | 56 | return -1; |
@@ -53,7 +72,7 @@ static struct pool_buffer *create_buffer(struct wl_shm *shm, | |||
53 | struct pool_buffer *buf, int32_t width, int32_t height, | 72 | struct pool_buffer *buf, int32_t width, int32_t height, |
54 | uint32_t format) { | 73 | uint32_t format) { |
55 | uint32_t stride = width * 4; | 74 | uint32_t stride = width * 4; |
56 | uint32_t size = stride * height; | 75 | size_t size = stride * height; |
57 | 76 | ||
58 | char *name; | 77 | char *name; |
59 | int fd = create_pool_file(size, &name); | 78 | int fd = create_pool_file(size, &name); |
@@ -68,8 +87,10 @@ static struct pool_buffer *create_buffer(struct wl_shm *shm, | |||
68 | free(name); | 87 | free(name); |
69 | fd = -1; | 88 | fd = -1; |
70 | 89 | ||
90 | buf->size = size; | ||
71 | buf->width = width; | 91 | buf->width = width; |
72 | buf->height = height; | 92 | buf->height = height; |
93 | buf->data = data; | ||
73 | buf->surface = cairo_image_surface_create_for_data(data, | 94 | buf->surface = cairo_image_surface_create_for_data(data, |
74 | CAIRO_FORMAT_ARGB32, width, height, stride); | 95 | CAIRO_FORMAT_ARGB32, width, height, stride); |
75 | buf->cairo = cairo_create(buf->surface); | 96 | buf->cairo = cairo_create(buf->surface); |
@@ -92,6 +113,9 @@ void destroy_buffer(struct pool_buffer *buffer) { | |||
92 | if (buffer->pango) { | 113 | if (buffer->pango) { |
93 | g_object_unref(buffer->pango); | 114 | g_object_unref(buffer->pango); |
94 | } | 115 | } |
116 | if (buffer->data) { | ||
117 | munmap(buffer->data, buffer->size); | ||
118 | } | ||
95 | memset(buffer, 0, sizeof(struct pool_buffer)); | 119 | memset(buffer, 0, sizeof(struct pool_buffer)); |
96 | } | 120 | } |
97 | 121 | ||
diff --git a/include/pool-buffer.h b/include/pool-buffer.h index 856f7c8c..54f5be06 100644 --- a/include/pool-buffer.h +++ b/include/pool-buffer.h | |||
@@ -12,6 +12,8 @@ struct pool_buffer { | |||
12 | cairo_t *cairo; | 12 | cairo_t *cairo; |
13 | PangoContext *pango; | 13 | PangoContext *pango; |
14 | uint32_t width, height; | 14 | uint32_t width, height; |
15 | void *data; | ||
16 | size_t size; | ||
15 | bool busy; | 17 | bool busy; |
16 | }; | 18 | }; |
17 | 19 | ||
diff --git a/include/sway/criteria.h b/include/sway/criteria.h index 74da132c..bd3ca0ac 100644 --- a/include/sway/criteria.h +++ b/include/sway/criteria.h | |||
@@ -18,6 +18,7 @@ struct criteria { | |||
18 | char *target; // workspace or output name for `assign` criteria | 18 | char *target; // workspace or output name for `assign` criteria |
19 | 19 | ||
20 | pcre *title; | 20 | pcre *title; |
21 | pcre *shell; | ||
21 | pcre *app_id; | 22 | pcre *app_id; |
22 | pcre *class; | 23 | pcre *class; |
23 | pcre *instance; | 24 | pcre *instance; |
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 0fb8f1b3..a8bf4955 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h | |||
@@ -201,7 +201,7 @@ const char *view_get_window_role(struct sway_view *view); | |||
201 | 201 | ||
202 | uint32_t view_get_window_type(struct sway_view *view); | 202 | uint32_t view_get_window_type(struct sway_view *view); |
203 | 203 | ||
204 | const char *view_get_type(struct sway_view *view); | 204 | const char *view_get_shell(struct sway_view *view); |
205 | 205 | ||
206 | void view_configure(struct sway_view *view, double ox, double oy, int width, | 206 | void view_configure(struct sway_view *view, double ox, double oy, int width, |
207 | int height); | 207 | int height); |
diff --git a/include/swaylock/swaylock.h b/include/swaylock/swaylock.h index dae823b8..2931fd61 100644 --- a/include/swaylock/swaylock.h +++ b/include/swaylock/swaylock.h | |||
@@ -56,6 +56,7 @@ struct swaylock_surface { | |||
56 | struct zwlr_layer_surface_v1 *layer_surface; | 56 | struct zwlr_layer_surface_v1 *layer_surface; |
57 | struct pool_buffer buffers[2]; | 57 | struct pool_buffer buffers[2]; |
58 | struct pool_buffer *current_buffer; | 58 | struct pool_buffer *current_buffer; |
59 | bool frame_pending, dirty; | ||
59 | uint32_t width, height; | 60 | uint32_t width, height; |
60 | int32_t scale; | 61 | int32_t scale; |
61 | char *output_name; | 62 | char *output_name; |
@@ -74,5 +75,7 @@ void swaylock_handle_key(struct swaylock_state *state, | |||
74 | xkb_keysym_t keysym, uint32_t codepoint); | 75 | xkb_keysym_t keysym, uint32_t codepoint); |
75 | void render_frame(struct swaylock_surface *surface); | 76 | void render_frame(struct swaylock_surface *surface); |
76 | void render_frames(struct swaylock_state *state); | 77 | void render_frames(struct swaylock_state *state); |
78 | void damage_surface(struct swaylock_surface *surface); | ||
79 | void damage_state(struct swaylock_state *state); | ||
77 | 80 | ||
78 | #endif | 81 | #endif |
diff --git a/sway/criteria.c b/sway/criteria.c index 4295cacc..dec5fed7 100644 --- a/sway/criteria.c +++ b/sway/criteria.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | bool criteria_is_empty(struct criteria *criteria) { | 14 | bool criteria_is_empty(struct criteria *criteria) { |
15 | return !criteria->title | 15 | return !criteria->title |
16 | && !criteria->shell | ||
16 | && !criteria->app_id | 17 | && !criteria->app_id |
17 | && !criteria->class | 18 | && !criteria->class |
18 | && !criteria->instance | 19 | && !criteria->instance |
@@ -29,6 +30,7 @@ bool criteria_is_empty(struct criteria *criteria) { | |||
29 | 30 | ||
30 | void criteria_destroy(struct criteria *criteria) { | 31 | void criteria_destroy(struct criteria *criteria) { |
31 | pcre_free(criteria->title); | 32 | pcre_free(criteria->title); |
33 | pcre_free(criteria->shell); | ||
32 | pcre_free(criteria->app_id); | 34 | pcre_free(criteria->app_id); |
33 | pcre_free(criteria->class); | 35 | pcre_free(criteria->class); |
34 | pcre_free(criteria->instance); | 36 | pcre_free(criteria->instance); |
@@ -53,6 +55,13 @@ static bool criteria_matches_view(struct criteria *criteria, | |||
53 | } | 55 | } |
54 | } | 56 | } |
55 | 57 | ||
58 | if (criteria->shell) { | ||
59 | const char *shell = view_get_shell(view); | ||
60 | if (!shell || regex_cmp(shell, criteria->shell) != 0) { | ||
61 | return false; | ||
62 | } | ||
63 | } | ||
64 | |||
56 | if (criteria->app_id) { | 65 | if (criteria->app_id) { |
57 | const char *app_id = view_get_app_id(view); | 66 | const char *app_id = view_get_app_id(view); |
58 | if (!app_id || regex_cmp(app_id, criteria->app_id) != 0) { | 67 | if (!app_id || regex_cmp(app_id, criteria->app_id) != 0) { |
@@ -206,6 +215,7 @@ enum criteria_token { | |||
206 | T_FLOATING, | 215 | T_FLOATING, |
207 | T_ID, | 216 | T_ID, |
208 | T_INSTANCE, | 217 | T_INSTANCE, |
218 | T_SHELL, | ||
209 | T_TILING, | 219 | T_TILING, |
210 | T_TITLE, | 220 | T_TITLE, |
211 | T_URGENT, | 221 | T_URGENT, |
@@ -229,6 +239,8 @@ static enum criteria_token token_from_name(char *name) { | |||
229 | return T_ID; | 239 | return T_ID; |
230 | } else if (strcmp(name, "instance") == 0) { | 240 | } else if (strcmp(name, "instance") == 0) { |
231 | return T_INSTANCE; | 241 | return T_INSTANCE; |
242 | } else if (strcmp(name, "shell") == 0) { | ||
243 | return T_SHELL; | ||
232 | } else if (strcmp(name, "title") == 0) { | 244 | } else if (strcmp(name, "title") == 0) { |
233 | return T_TITLE; | 245 | return T_TITLE; |
234 | } else if (strcmp(name, "urgent") == 0) { | 246 | } else if (strcmp(name, "urgent") == 0) { |
@@ -271,6 +283,9 @@ static char *get_focused_prop(enum criteria_token token) { | |||
271 | case T_INSTANCE: | 283 | case T_INSTANCE: |
272 | value = view_get_instance(view); | 284 | value = view_get_instance(view); |
273 | break; | 285 | break; |
286 | case T_SHELL: | ||
287 | value = view_get_shell(view); | ||
288 | break; | ||
274 | case T_TITLE: | 289 | case T_TITLE: |
275 | value = view_get_class(view); | 290 | value = view_get_class(view); |
276 | break; | 291 | break; |
@@ -332,6 +347,9 @@ static bool parse_token(struct criteria *criteria, char *name, char *value) { | |||
332 | case T_TITLE: | 347 | case T_TITLE: |
333 | generate_regex(&criteria->title, effective_value); | 348 | generate_regex(&criteria->title, effective_value); |
334 | break; | 349 | break; |
350 | case T_SHELL: | ||
351 | generate_regex(&criteria->shell, effective_value); | ||
352 | break; | ||
335 | case T_APP_ID: | 353 | case T_APP_ID: |
336 | generate_regex(&criteria->app_id, effective_value); | 354 | generate_regex(&criteria->app_id, effective_value); |
337 | break; | 355 | break; |
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 9a0d282b..b2b95fa0 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c | |||
@@ -3,13 +3,14 @@ | |||
3 | #include <stdlib.h> | 3 | #include <stdlib.h> |
4 | #include <wayland-server.h> | 4 | #include <wayland-server.h> |
5 | #include <wlr/types/wlr_xdg_shell.h> | 5 | #include <wlr/types/wlr_xdg_shell.h> |
6 | #include <wlr/util/edges.h> | ||
7 | #include "log.h" | ||
8 | #include "sway/input/input-manager.h" | ||
9 | #include "sway/input/seat.h" | ||
10 | #include "sway/server.h" | ||
6 | #include "sway/tree/container.h" | 11 | #include "sway/tree/container.h" |
7 | #include "sway/tree/layout.h" | 12 | #include "sway/tree/layout.h" |
8 | #include "sway/server.h" | ||
9 | #include "sway/tree/view.h" | 13 | #include "sway/tree/view.h" |
10 | #include "sway/input/seat.h" | ||
11 | #include "sway/input/input-manager.h" | ||
12 | #include "log.h" | ||
13 | 14 | ||
14 | static const struct sway_view_child_impl popup_impl; | 15 | static const struct sway_view_child_impl popup_impl; |
15 | 16 | ||
@@ -248,7 +249,8 @@ void handle_xdg_shell_surface(struct wl_listener *listener, void *data) { | |||
248 | wlr_log(L_DEBUG, "New xdg_shell toplevel title='%s' app_id='%s'", | 249 | wlr_log(L_DEBUG, "New xdg_shell toplevel title='%s' app_id='%s'", |
249 | xdg_surface->toplevel->title, xdg_surface->toplevel->app_id); | 250 | xdg_surface->toplevel->title, xdg_surface->toplevel->app_id); |
250 | wlr_xdg_surface_ping(xdg_surface); | 251 | wlr_xdg_surface_ping(xdg_surface); |
251 | wlr_xdg_toplevel_set_maximized(xdg_surface, true); | 252 | wlr_xdg_toplevel_set_tiled(xdg_surface, WLR_EDGE_LEFT | WLR_EDGE_RIGHT | |
253 | WLR_EDGE_TOP | WLR_EDGE_BOTTOM); | ||
252 | 254 | ||
253 | struct sway_xdg_shell_view *xdg_shell_view = | 255 | struct sway_xdg_shell_view *xdg_shell_view = |
254 | calloc(1, sizeof(struct sway_xdg_shell_view)); | 256 | calloc(1, sizeof(struct sway_xdg_shell_view)); |
diff --git a/sway/sway.5.scd b/sway/sway.5.scd index 25a5eef5..e6bc5a1e 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd | |||
@@ -560,6 +560,11 @@ The following attributes may be matched with: | |||
560 | value is \_\_focused\_\_, then the window instance must be the same as that | 560 | value is \_\_focused\_\_, then the window instance must be the same as that |
561 | of the currently focused window. | 561 | of the currently focused window. |
562 | 562 | ||
563 | *shell* | ||
564 | Compare value against the window shell, such as "xdg\_shell" or "xwayland". | ||
565 | Can be a regular expression. If value is \_\_focused\_\_, then the shell | ||
566 | must be the same as that of the currently focused window. | ||
567 | |||
563 | *tiling* | 568 | *tiling* |
564 | Matches tiling windows. | 569 | Matches tiling windows. |
565 | 570 | ||
diff --git a/sway/tree/view.c b/sway/tree/view.c index 812d7740..d91182ed 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -107,7 +107,7 @@ uint32_t view_get_window_type(struct sway_view *view) { | |||
107 | return 0; | 107 | return 0; |
108 | } | 108 | } |
109 | 109 | ||
110 | const char *view_get_type(struct sway_view *view) { | 110 | const char *view_get_shell(struct sway_view *view) { |
111 | switch(view->type) { | 111 | switch(view->type) { |
112 | case SWAY_VIEW_XDG_SHELL_V6: | 112 | case SWAY_VIEW_XDG_SHELL_V6: |
113 | return "xdg_shell_v6"; | 113 | return "xdg_shell_v6"; |
@@ -654,10 +654,12 @@ static size_t parse_title_format(struct sway_view *view, char *buffer) { | |||
654 | return title ? strlen(title) : 0; | 654 | return title ? strlen(title) : 0; |
655 | } | 655 | } |
656 | const char *title = view_get_title(view); | 656 | const char *title = view_get_title(view); |
657 | const char *app_id = view_get_app_id(view); | ||
657 | const char *class = view_get_class(view); | 658 | const char *class = view_get_class(view); |
658 | const char *instance = view_get_instance(view); | 659 | const char *instance = view_get_instance(view); |
659 | const char *shell = view_get_type(view); | 660 | const char *shell = view_get_shell(view); |
660 | size_t title_len = title ? strlen(title) : 0; | 661 | size_t title_len = title ? strlen(title) : 0; |
662 | size_t app_id_len = app_id ? strlen(app_id) : 0; | ||
661 | size_t class_len = class ? strlen(class) : 0; | 663 | size_t class_len = class ? strlen(class) : 0; |
662 | size_t instance_len = instance ? strlen(instance) : 0; | 664 | size_t instance_len = instance ? strlen(instance) : 0; |
663 | size_t shell_len = shell ? strlen(shell) : 0; | 665 | size_t shell_len = shell ? strlen(shell) : 0; |
@@ -675,6 +677,10 @@ static size_t parse_title_format(struct sway_view *view, char *buffer) { | |||
675 | lenient_strcat(buffer, title); | 677 | lenient_strcat(buffer, title); |
676 | len += title_len; | 678 | len += title_len; |
677 | format += 6; | 679 | format += 6; |
680 | } else if (strncmp(next, "%app_id", 7) == 0) { | ||
681 | lenient_strcat(buffer, app_id); | ||
682 | len += app_id_len; | ||
683 | format += 7; | ||
678 | } else if (strncmp(next, "%class", 6) == 0) { | 684 | } else if (strncmp(next, "%class", 6) == 0) { |
679 | lenient_strcat(buffer, class); | 685 | lenient_strcat(buffer, class); |
680 | len += class_len; | 686 | len += class_len; |
diff --git a/swaylock/main.c b/swaylock/main.c index f89f2849..591df7b4 100644 --- a/swaylock/main.c +++ b/swaylock/main.c | |||
@@ -131,14 +131,58 @@ static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { | |||
131 | .closed = layer_surface_closed, | 131 | .closed = layer_surface_closed, |
132 | }; | 132 | }; |
133 | 133 | ||
134 | static void handle_wl_output_geometry(void *data, struct wl_output *output, int32_t x, | 134 | static const struct wl_callback_listener surface_frame_listener; |
135 | int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, | 135 | |
136 | const char *make, const char *model, int32_t transform) { | 136 | static void surface_frame_handle_done(void *data, struct wl_callback *callback, |
137 | uint32_t time) { | ||
138 | struct swaylock_surface *surface = data; | ||
139 | |||
140 | wl_callback_destroy(callback); | ||
141 | surface->frame_pending = false; | ||
142 | |||
143 | if (surface->dirty) { | ||
144 | // Schedule a frame in case the surface is damaged again | ||
145 | struct wl_callback *callback = wl_surface_frame(surface->surface); | ||
146 | wl_callback_add_listener(callback, &surface_frame_listener, surface); | ||
147 | surface->frame_pending = true; | ||
148 | |||
149 | render_frame(surface); | ||
150 | surface->dirty = false; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | static const struct wl_callback_listener surface_frame_listener = { | ||
155 | .done = surface_frame_handle_done, | ||
156 | }; | ||
157 | |||
158 | void damage_surface(struct swaylock_surface *surface) { | ||
159 | surface->dirty = true; | ||
160 | if (surface->frame_pending) { | ||
161 | return; | ||
162 | } | ||
163 | |||
164 | struct wl_callback *callback = wl_surface_frame(surface->surface); | ||
165 | wl_callback_add_listener(callback, &surface_frame_listener, surface); | ||
166 | surface->frame_pending = true; | ||
167 | wl_surface_commit(surface->surface); | ||
168 | } | ||
169 | |||
170 | void damage_state(struct swaylock_state *state) { | ||
171 | struct swaylock_surface *surface; | ||
172 | wl_list_for_each(surface, &state->surfaces, link) { | ||
173 | damage_surface(surface); | ||
174 | } | ||
175 | } | ||
176 | |||
177 | static void handle_wl_output_geometry(void *data, struct wl_output *output, | ||
178 | int32_t x, int32_t y, int32_t width_mm, int32_t height_mm, | ||
179 | int32_t subpixel, const char *make, const char *model, | ||
180 | int32_t transform) { | ||
137 | // Who cares | 181 | // Who cares |
138 | } | 182 | } |
139 | 183 | ||
140 | static void handle_wl_output_mode(void *data, struct wl_output *output, uint32_t flags, | 184 | static void handle_wl_output_mode(void *data, struct wl_output *output, |
141 | int32_t width, int32_t height, int32_t refresh) { | 185 | uint32_t flags, int32_t width, int32_t height, int32_t refresh) { |
142 | // Who cares | 186 | // Who cares |
143 | } | 187 | } |
144 | 188 | ||
@@ -151,7 +195,7 @@ static void handle_wl_output_scale(void *data, struct wl_output *output, | |||
151 | struct swaylock_surface *surface = data; | 195 | struct swaylock_surface *surface = data; |
152 | surface->scale = factor; | 196 | surface->scale = factor; |
153 | if (surface->state->run_display) { | 197 | if (surface->state->run_display) { |
154 | render_frames(surface->state); | 198 | damage_surface(surface); |
155 | } | 199 | } |
156 | } | 200 | } |
157 | 201 | ||
diff --git a/swaylock/password.c b/swaylock/password.c index 1ad5cd81..6d493309 100644 --- a/swaylock/password.c +++ b/swaylock/password.c | |||
@@ -93,58 +93,58 @@ static void append_ch(struct swaylock_password *pw, uint32_t codepoint) { | |||
93 | void swaylock_handle_key(struct swaylock_state *state, | 93 | void swaylock_handle_key(struct swaylock_state *state, |
94 | xkb_keysym_t keysym, uint32_t codepoint) { | 94 | xkb_keysym_t keysym, uint32_t codepoint) { |
95 | switch (keysym) { | 95 | switch (keysym) { |
96 | case XKB_KEY_KP_Enter: /* fallthrough */ | 96 | case XKB_KEY_KP_Enter: /* fallthrough */ |
97 | case XKB_KEY_Return: | 97 | case XKB_KEY_Return: |
98 | state->auth_state = AUTH_STATE_VALIDATING; | 98 | state->auth_state = AUTH_STATE_VALIDATING; |
99 | render_frames(state); | 99 | damage_state(state); |
100 | wl_display_roundtrip(state->display); | 100 | wl_display_roundtrip(state->display); |
101 | if (attempt_password(&state->password)) { | 101 | if (attempt_password(&state->password)) { |
102 | state->run_display = false; | 102 | state->run_display = false; |
103 | break; | ||
104 | } | ||
105 | state->auth_state = AUTH_STATE_INVALID; | ||
106 | render_frames(state); | ||
107 | break; | 103 | break; |
108 | case XKB_KEY_Delete: | 104 | } |
109 | case XKB_KEY_BackSpace: | 105 | state->auth_state = AUTH_STATE_INVALID; |
110 | if (backspace(&state->password)) { | 106 | damage_state(state); |
111 | state->auth_state = AUTH_STATE_BACKSPACE; | 107 | break; |
112 | } else { | 108 | case XKB_KEY_Delete: |
113 | state->auth_state = AUTH_STATE_CLEAR; | 109 | case XKB_KEY_BackSpace: |
114 | } | 110 | if (backspace(&state->password)) { |
115 | render_frames(state); | 111 | state->auth_state = AUTH_STATE_BACKSPACE; |
116 | break; | 112 | } else { |
117 | case XKB_KEY_Escape: | ||
118 | clear_password_buffer(&state->password); | ||
119 | state->auth_state = AUTH_STATE_CLEAR; | 113 | state->auth_state = AUTH_STATE_CLEAR; |
120 | render_frames(state); | 114 | } |
121 | break; | 115 | damage_state(state); |
122 | case XKB_KEY_Caps_Lock: | 116 | break; |
123 | /* The state is getting active after this | 117 | case XKB_KEY_Escape: |
124 | * so we need to manually toggle it */ | 118 | clear_password_buffer(&state->password); |
125 | state->xkb.caps_lock = !state->xkb.caps_lock; | 119 | state->auth_state = AUTH_STATE_CLEAR; |
126 | state->auth_state = AUTH_STATE_INPUT_NOP; | 120 | damage_state(state); |
127 | render_frames(state); | 121 | break; |
128 | break; | 122 | case XKB_KEY_Caps_Lock: |
129 | case XKB_KEY_Shift_L: | 123 | /* The state is getting active after this |
130 | case XKB_KEY_Shift_R: | 124 | * so we need to manually toggle it */ |
131 | case XKB_KEY_Control_L: | 125 | state->xkb.caps_lock = !state->xkb.caps_lock; |
132 | case XKB_KEY_Control_R: | 126 | state->auth_state = AUTH_STATE_INPUT_NOP; |
133 | case XKB_KEY_Meta_L: | 127 | damage_state(state); |
134 | case XKB_KEY_Meta_R: | 128 | break; |
135 | case XKB_KEY_Alt_L: | 129 | case XKB_KEY_Shift_L: |
136 | case XKB_KEY_Alt_R: | 130 | case XKB_KEY_Shift_R: |
137 | case XKB_KEY_Super_L: | 131 | case XKB_KEY_Control_L: |
138 | case XKB_KEY_Super_R: | 132 | case XKB_KEY_Control_R: |
139 | state->auth_state = AUTH_STATE_INPUT_NOP; | 133 | case XKB_KEY_Meta_L: |
140 | render_frames(state); | 134 | case XKB_KEY_Meta_R: |
141 | break; | 135 | case XKB_KEY_Alt_L: |
142 | default: | 136 | case XKB_KEY_Alt_R: |
143 | if (codepoint) { | 137 | case XKB_KEY_Super_L: |
144 | append_ch(&state->password, codepoint); | 138 | case XKB_KEY_Super_R: |
145 | state->auth_state = AUTH_STATE_INPUT; | 139 | state->auth_state = AUTH_STATE_INPUT_NOP; |
146 | render_frames(state); | 140 | damage_state(state); |
147 | } | 141 | break; |
148 | break; | 142 | default: |
143 | if (codepoint) { | ||
144 | append_ch(&state->password, codepoint); | ||
145 | state->auth_state = AUTH_STATE_INPUT; | ||
146 | damage_state(state); | ||
147 | } | ||
148 | break; | ||
149 | } | 149 | } |
150 | } | 150 | } |
diff --git a/swaylock/render.c b/swaylock/render.c index 05236dea..2032ddcf 100644 --- a/swaylock/render.c +++ b/swaylock/render.c | |||
@@ -23,6 +23,10 @@ void render_frame(struct swaylock_surface *surface) { | |||
23 | 23 | ||
24 | surface->current_buffer = get_next_buffer(state->shm, | 24 | surface->current_buffer = get_next_buffer(state->shm, |
25 | surface->buffers, buffer_width, buffer_height); | 25 | surface->buffers, buffer_width, buffer_height); |
26 | if (surface->current_buffer == NULL) { | ||
27 | return; | ||
28 | } | ||
29 | |||
26 | cairo_t *cairo = surface->current_buffer->cairo; | 30 | cairo_t *cairo = surface->current_buffer->cairo; |
27 | cairo_identity_matrix(cairo); | 31 | cairo_identity_matrix(cairo); |
28 | 32 | ||