diff --git a/clients/window.c b/clients/window.c index e4cfff98..489c35ac 100644 --- a/clients/window.c +++ b/clients/window.c @@ -1274,72 +1274,35 @@ frame_redraw_handler(struct widget *widget, void *data) cairo_destroy(cr); } -static int -frame_get_pointer_location(struct frame *frame, int32_t x, int32_t y) -{ - struct widget *widget = frame->widget; - int vlocation, hlocation, location; - const int grip_size = 8; - struct theme *t = widget->window->display->theme; - - if (x < t->margin) - hlocation = WINDOW_EXTERIOR; - else if (t->margin <= x && x < t->margin + grip_size) - hlocation = WINDOW_RESIZING_LEFT; - else if (x < widget->allocation.width - t->margin - grip_size) - hlocation = WINDOW_INTERIOR; - else if (x < widget->allocation.width - t->margin) - hlocation = WINDOW_RESIZING_RIGHT; - else - hlocation = WINDOW_EXTERIOR; - - if (y < t->margin) - vlocation = WINDOW_EXTERIOR; - else if (t->margin <= y && y < t->margin + grip_size) - vlocation = WINDOW_RESIZING_TOP; - else if (y < widget->allocation.height - t->margin - grip_size) - vlocation = WINDOW_INTERIOR; - else if (y < widget->allocation.height - t->margin) - vlocation = WINDOW_RESIZING_BOTTOM; - else - vlocation = WINDOW_EXTERIOR; - - location = vlocation | hlocation; - if (location & WINDOW_EXTERIOR) - location = WINDOW_EXTERIOR; - if (location == WINDOW_INTERIOR && y < t->margin + 50) - location = WINDOW_TITLEBAR; - else if (location == WINDOW_INTERIOR) - location = WINDOW_CLIENT_AREA; - - return location; -} - static int frame_get_pointer_image_for_location(struct frame *frame, struct input *input) { + struct theme *t = frame->widget->window->display->theme; int location; - location = frame_get_pointer_location(frame, input->sx, input->sy); + location = theme_get_location(t, input->sx, input->sy, + frame->widget->allocation.width, + frame->widget->allocation.height); + switch (location) { - case WINDOW_RESIZING_TOP: + case THEME_LOCATION_RESIZING_TOP: return WL_CURSOR_TOP; - case WINDOW_RESIZING_BOTTOM: + case THEME_LOCATION_RESIZING_BOTTOM: return WL_CURSOR_BOTTOM; - case WINDOW_RESIZING_LEFT: + case THEME_LOCATION_RESIZING_LEFT: return WL_CURSOR_LEFT; - case WINDOW_RESIZING_RIGHT: + case THEME_LOCATION_RESIZING_RIGHT: return WL_CURSOR_RIGHT; - case WINDOW_RESIZING_TOP_LEFT: + case THEME_LOCATION_RESIZING_TOP_LEFT: return WL_CURSOR_TOP_LEFT; - case WINDOW_RESIZING_TOP_RIGHT: + case THEME_LOCATION_RESIZING_TOP_RIGHT: return WL_CURSOR_TOP_RIGHT; - case WINDOW_RESIZING_BOTTOM_LEFT: + case THEME_LOCATION_RESIZING_BOTTOM_LEFT: return WL_CURSOR_BOTTOM_LEFT; - case WINDOW_RESIZING_BOTTOM_RIGHT: + case THEME_LOCATION_RESIZING_BOTTOM_RIGHT: return WL_CURSOR_BOTTOM_RIGHT; - case WINDOW_EXTERIOR: - case WINDOW_TITLEBAR: + case THEME_LOCATION_EXTERIOR: + case THEME_LOCATION_TITLEBAR: default: return WL_CURSOR_LEFT_PTR; } @@ -1407,11 +1370,13 @@ frame_button_handler(struct widget *widget, struct display *display = window->display; int location; - location = frame_get_pointer_location(frame, input->sx, input->sy); + location = theme_get_location(display->theme, input->sx, input->sy, + frame->widget->allocation.width, + frame->widget->allocation.height); if (window->display->shell && button == BTN_LEFT && state == 1) { switch (location) { - case WINDOW_TITLEBAR: + case THEME_LOCATION_TITLEBAR: if (!window->shell_surface) break; input_set_pointer_image(input, time, WL_CURSOR_DRAGGING); @@ -1420,14 +1385,14 @@ frame_button_handler(struct widget *widget, input_get_seat(input), display->serial); break; - case WINDOW_RESIZING_TOP: - case WINDOW_RESIZING_BOTTOM: - case WINDOW_RESIZING_LEFT: - case WINDOW_RESIZING_RIGHT: - case WINDOW_RESIZING_TOP_LEFT: - case WINDOW_RESIZING_TOP_RIGHT: - case WINDOW_RESIZING_BOTTOM_LEFT: - case WINDOW_RESIZING_BOTTOM_RIGHT: + case THEME_LOCATION_RESIZING_TOP: + case THEME_LOCATION_RESIZING_BOTTOM: + case THEME_LOCATION_RESIZING_LEFT: + case THEME_LOCATION_RESIZING_RIGHT: + case THEME_LOCATION_RESIZING_TOP_LEFT: + case THEME_LOCATION_RESIZING_TOP_RIGHT: + case THEME_LOCATION_RESIZING_BOTTOM_LEFT: + case THEME_LOCATION_RESIZING_BOTTOM_RIGHT: if (!window->shell_surface) break; input_ungrab(input); diff --git a/shared/cairo-util.c b/shared/cairo-util.c index 9fd2e493..649ed985 100644 --- a/shared/cairo-util.c +++ b/shared/cairo-util.c @@ -427,3 +427,43 @@ theme_render_frame(struct theme *t, cairo_show_text(cr, title); } } + +enum theme_location +theme_get_location(struct theme *t, int x, int y, int width, int height) +{ + int vlocation, hlocation, location; + const int grip_size = 8; + + if (x < t->margin) + hlocation = THEME_LOCATION_EXTERIOR; + else if (t->margin <= x && x < t->margin + grip_size) + hlocation = THEME_LOCATION_RESIZING_LEFT; + else if (x < width - t->margin - grip_size) + hlocation = THEME_LOCATION_INTERIOR; + else if (x < width - t->margin) + hlocation = THEME_LOCATION_RESIZING_RIGHT; + else + hlocation = THEME_LOCATION_EXTERIOR; + + if (y < t->margin) + vlocation = THEME_LOCATION_EXTERIOR; + else if (t->margin <= y && y < t->margin + grip_size) + vlocation = THEME_LOCATION_RESIZING_TOP; + else if (y < height - t->margin - grip_size) + vlocation = THEME_LOCATION_INTERIOR; + else if (y < height - t->margin) + vlocation = THEME_LOCATION_RESIZING_BOTTOM; + else + vlocation = THEME_LOCATION_EXTERIOR; + + location = vlocation | hlocation; + if (location & THEME_LOCATION_EXTERIOR) + location = THEME_LOCATION_EXTERIOR; + if (location == THEME_LOCATION_INTERIOR && + y < t->margin + t->titlebar_height) + location = THEME_LOCATION_TITLEBAR; + else if (location == THEME_LOCATION_INTERIOR) + location = THEME_LOCATION_CLIENT_AREA; + + return location; +} diff --git a/shared/cairo-util.h b/shared/cairo-util.h index 6dda7cfb..2fec389a 100644 --- a/shared/cairo-util.h +++ b/shared/cairo-util.h @@ -65,4 +65,23 @@ theme_render_frame(struct theme *t, cairo_t *cr, int width, int height, const char *title, uint32_t flags); +enum theme_location { + THEME_LOCATION_INTERIOR = 0, + THEME_LOCATION_RESIZING_TOP = 1, + THEME_LOCATION_RESIZING_BOTTOM = 2, + THEME_LOCATION_RESIZING_LEFT = 4, + THEME_LOCATION_RESIZING_TOP_LEFT = 5, + THEME_LOCATION_RESIZING_BOTTOM_LEFT = 6, + THEME_LOCATION_RESIZING_RIGHT = 8, + THEME_LOCATION_RESIZING_TOP_RIGHT = 9, + THEME_LOCATION_RESIZING_BOTTOM_RIGHT = 10, + THEME_LOCATION_RESIZING_MASK = 15, + THEME_LOCATION_EXTERIOR = 16, + THEME_LOCATION_TITLEBAR = 17, + THEME_LOCATION_CLIENT_AREA = 18, +}; + +enum theme_location +theme_get_location(struct theme *t, int x, int y, int width, int height); + #endif diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c index 36270d14..a2f392b1 100644 --- a/src/xwayland/window-manager.c +++ b/src/xwayland/window-manager.c @@ -779,6 +779,8 @@ weston_wm_handle_button(struct weston_wm *wm, xcb_generic_event_t *event) struct weston_shell_interface *shell_interface = &wm->server->compositor->shell_interface; struct weston_wm_window *window; + enum theme_location location; + struct theme *t = wm->theme; fprintf(stderr, "XCB_BUTTON_%s (detail %d)\n", button->response_type == XCB_BUTTON_PRESS ? @@ -786,9 +788,22 @@ weston_wm_handle_button(struct weston_wm *wm, xcb_generic_event_t *event) window = hash_table_lookup(wm->window_hash, button->event); if (button->response_type == XCB_BUTTON_PRESS && - button->detail == 1) - shell_interface->move(window->shsurf, - wm->server->compositor->seat); + button->detail == 1) { + location = theme_get_location(t, + button->event_x, + button->event_y, + window->width, + window->height); + + switch (location) { + case THEME_LOCATION_TITLEBAR: + shell_interface->move(window->shsurf, + wm->server->compositor->seat); + break; + default: + break; + } + } } static int