Fix some memory safety issues
7e0661619255acae0e853029e4c773054b49bf28
1 parent
53030e41
swm.c
+13 -5
| 1861 | 1861 | if (!locked && cursor_mode != CURSOR_NORMAL && cursor_mode != CURSOR_PRESSED) { |
|
| 1862 | 1862 | if (cursor_mode == CURSOR_RESIZE) |
|
| 1863 | 1863 | client_set_resizing(grabc, 0); |
|
| 1864 | 1864 | wlr_cursor_set_xcursor(cursor, cursor_mgr, "default"); |
|
| 1865 | 1865 | cursor_mode = CURSOR_NORMAL; |
|
| 1866 | - | /* Move the window to the workspace on its new display. */ |
|
| 1866 | + | /* Move the window to the workspace on its new display. The |
|
| 1867 | + | * cursor can sit outside every output (on a layout edge or in a |
|
| 1868 | + | * gap); keep the window on its current display in that case. */ |
|
| 1867 | 1869 | selmon = point_to_monitor(cursor->x, cursor->y); |
|
| 1868 | - | set_monitor(grabc, selmon, 0); |
|
| 1870 | + | set_monitor(grabc, selmon ? selmon : grabc->mon, 0); |
|
| 1869 | 1871 | remember_client(grabc); |
|
| 1870 | 1872 | grabc = nullptr; |
|
| 1871 | 1873 | return; |
|
| 1872 | 1874 | } |
|
| 1873 | 1875 | cursor_mode = CURSOR_NORMAL; |
| 2130 | 2132 | client_get_geometry(c, &geom); |
|
| 2131 | 2133 | swm_box_reconcile_commit( |
|
| 2132 | 2134 | (struct swm_box *)&c->geom, geom.width, geom.height, c->bw, c->resize_edges |
|
| 2133 | 2135 | ); |
|
| 2134 | 2136 | } |
|
| 2135 | - | if (c->resize) { |
|
| 2137 | + | if (c->resize && c->mon) { |
|
| 2136 | 2138 | uint32_t resize_serial = c->resize; |
|
| 2137 | 2139 | int latest = resize_serial <= c->surface.xdg->current.configure_serial; |
|
| 2138 | 2140 | ||
| 2139 | 2141 | apply_bounds(c, &c->mon->w); |
|
| 2140 | 2142 | resize_apply(c); |
|
| 2141 | 2143 | ||
| 2142 | 2144 | if (latest) |
|
| 2143 | 2145 | c->resize = 0; |
|
| 2144 | 2146 | else |
|
| 2145 | 2147 | c->geom = c->pending_geom; |
|
| 2148 | + | } else if (c->resize) { |
|
| 2149 | + | /* The client lost its display with a resize in flight; settle the |
|
| 2150 | + | * resize once a display is available again. */ |
|
| 2146 | 2151 | } else { |
|
| 2147 | 2152 | resize(c, c->geom, c->is_floating && !c->is_fullscreen); |
|
| 2148 | 2153 | } |
|
| 2149 | 2154 | if (!c->resize) |
|
| 2150 | 2155 | c->resize_edges = WLR_EDGE_NONE; |
| 2767 | 2772 | ||
| 2768 | 2773 | /* Return the nearest enabled display in the requested direction. */ |
|
| 2769 | 2774 | monitor_t *direction_to_monitor(enum wlr_direction dir) { |
|
| 2770 | 2775 | struct wlr_output *next; |
|
| 2771 | 2776 | ||
| 2777 | + | if (!selmon) |
|
| 2778 | + | return nullptr; |
|
| 2779 | + | ||
| 2772 | 2780 | if (!wlr_output_layout_get(output_layout, selmon->wlr_output)) |
|
| 2773 | 2781 | return selmon; |
|
| 2774 | 2782 | ||
| 2775 | 2783 | if ((next = wlr_output_layout_adjacent_output( |
|
| 2776 | 2784 | output_layout, dir, selmon->wlr_output, selmon->m.x, selmon->m.y |
| 2898 | 2906 | ||
| 2899 | 2907 | /* Select the next enabled display and focus its top window. */ |
|
| 2900 | 2908 | void focus_monitor(const arg_t *arg) { |
|
| 2901 | 2909 | int i = 0, nmons = wl_list_length(&mons); |
|
| 2902 | 2910 | ||
| 2903 | - | if (nmons) { |
|
| 2911 | + | if (selmon && nmons) { |
|
| 2904 | 2912 | do /* Skip disabled displays. */ |
|
| 2905 | 2913 | selmon = direction_to_monitor(arg->i); |
|
| 2906 | 2914 | while (!selmon->wlr_output->enabled && i++ < nmons); |
|
| 2907 | 2915 | } |
|
| 2908 | 2916 | focus_client(focus_top(selmon), 1); |
| 6011 | 6019 | wlr_xwayland_surface_configure( |
|
| 6012 | 6020 | c->surface.xwayland, event->x, event->y, event->width, event->height |
|
| 6013 | 6021 | ); |
|
| 6014 | 6022 | return; |
|
| 6015 | 6023 | } |
|
| 6016 | - | if ((c->is_floating && c != grabc) || !c->mon->ws || !c->mon->ws->lt->arrange) { |
|
| 6024 | + | if ((c->is_floating && c != grabc) || !c->mon || !c->mon->ws || !c->mon->ws->lt->arrange) { |
|
| 6017 | 6025 | resize( |
|
| 6018 | 6026 | c, |
|
| 6019 | 6027 | (struct wlr_box){ .x = event->x - c->bw, |
|
| 6020 | 6028 | .y = event->y - c->bw, |
|
| 6021 | 6029 | .width = event->width + c->bw * 2, |
util.c
+3 -0
| 30 | 30 | size_t env_expand(char *output, size_t capacity, const char *input) { |
|
| 31 | 31 | const char *value; |
|
| 32 | 32 | size_t i = 0, len, out = 0, start; |
|
| 33 | 33 | char name[MAX_ENV_SIZE]; |
|
| 34 | 34 | ||
| 35 | + | if (!capacity) |
|
| 36 | + | return 0; |
|
| 37 | + | ||
| 35 | 38 | while (input[i]) { |
|
| 36 | 39 | if (input[i] != '$') { |
|
| 37 | 40 | if (out + 1 >= capacity) |
|
| 38 | 41 | return 0; |
|
| 39 | 42 | output[out++] = input[i]; |