diff options
-rw-r--r-- | backend/backend.c | 4 | ||||
-rw-r--r-- | backend/meson.build | 5 | ||||
-rw-r--r-- | backend/x11/backend.c | 4 | ||||
-rw-r--r-- | examples/tablet.c | 18 | ||||
-rw-r--r-- | include/rootston/config.h | 2 | ||||
-rw-r--r-- | include/wlr/render/interface.h | 4 | ||||
-rw-r--r-- | include/wlr/render/wlr_renderer.h | 16 | ||||
-rw-r--r-- | include/wlr/types/wlr_box.h | 2 | ||||
-rw-r--r-- | include/wlr/types/wlr_xdg_shell.h | 3 | ||||
-rw-r--r-- | include/wlr/types/wlr_xdg_shell_v6.h | 3 | ||||
-rw-r--r-- | include/wlr/util/region.h | 7 | ||||
-rw-r--r-- | meson.build | 64 | ||||
-rw-r--r-- | meson_options.txt | 1 | ||||
-rw-r--r-- | render/gles2/renderer.c | 8 | ||||
-rw-r--r-- | render/wlr_renderer.c | 41 | ||||
-rw-r--r-- | rootston/config.c | 9 | ||||
-rw-r--r-- | rootston/input.c | 2 | ||||
-rw-r--r-- | rootston/output.c | 49 | ||||
-rw-r--r-- | rootston/seat.c | 27 | ||||
-rw-r--r-- | types/wlr_xdg_shell.c | 4 | ||||
-rw-r--r-- | types/wlr_xdg_shell_v6.c | 4 | ||||
-rw-r--r-- | util/region.c | 49 |
22 files changed, 236 insertions, 90 deletions
diff --git a/backend/backend.c b/backend/backend.c index c67be617..02b0b9af 100644 --- a/backend/backend.c +++ b/backend/backend.c @@ -11,7 +11,9 @@ #include <wlr/backend/multi.h> #include <wlr/backend/session.h> #include <wlr/backend/wayland.h> +#ifdef WLR_HAS_X11_BACKEND #include <wlr/backend/x11.h> +#endif #include <wlr/util/log.h> void wlr_backend_init(struct wlr_backend *backend, @@ -94,6 +96,7 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_display *display) { } } +#ifdef WLR_HAS_X11_BACKEND const char *x11_display = getenv("DISPLAY"); if (x11_display) { struct wlr_backend *x11_backend = @@ -101,6 +104,7 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_display *display) { wlr_multi_backend_add(backend, x11_backend); return backend; } +#endif // Attempt DRM+libinput struct wlr_session *session = wlr_session_create(display); diff --git a/backend/meson.build b/backend/meson.build index c0ed76f1..a74ea024 100644 --- a/backend/meson.build +++ b/backend/meson.build @@ -24,7 +24,6 @@ backend_files = files( 'wayland/output.c', 'wayland/registry.c', 'wayland/wl_seat.c', - 'x11/backend.c', ) backend_deps = [ @@ -50,6 +49,10 @@ if conf_data.get('WLR_HAS_SYSTEMD', false) backend_deps += systemd endif +if conf_data.get('WLR_HAS_X11_BACKEND', false) + backend_files += files('x11/backend.c') +endif + if conf_data.get('WLR_HAS_ELOGIND', false) backend_files += files('session/logind.c') backend_deps += elogind diff --git a/backend/x11/backend.c b/backend/x11/backend.c index dd2c0a6e..36d72d9e 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -326,9 +326,6 @@ static void wlr_x11_backend_destroy(struct wlr_backend *backend) { wl_event_source_remove(x11->frame_timer); wlr_egl_finish(&x11->egl); - if (x11->xcb_conn) { - xcb_disconnect(x11->xcb_conn); - } if (x11->xlib_conn) { XCloseDisplay(x11->xlib_conn); } @@ -428,7 +425,6 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display, error_event: wl_event_source_remove(x11->event_source); error_x11: - xcb_disconnect(x11->xcb_conn); XCloseDisplay(x11->xlib_conn); free(x11); return NULL; diff --git a/examples/tablet.c b/examples/tablet.c index 65c559cb..9379fac3 100644 --- a/examples/tablet.c +++ b/examples/tablet.c @@ -49,7 +49,6 @@ static void handle_output_frame(struct output_state *output, struct timespec *ts wlr_renderer_begin(sample->renderer, wlr_output->width, wlr_output->height); wlr_renderer_clear(sample->renderer, (float[]){0.25f, 0.25f, 0.25f, 1}); - float matrix[9]; float distance = 0.8f * (1 - sample->distance); float tool_color[4] = { distance, distance, distance, 1 }; for (size_t i = 0; sample->button && i < 4; ++i) { @@ -61,12 +60,12 @@ static void handle_output_frame(struct output_state *output, struct timespec *ts float pad_height = sample->height_mm * scale; float left = width / 2.0f - pad_width / 2.0f; float top = height / 2.0f - pad_height / 2.0f; - struct wlr_box box = { + const struct wlr_box box = { .x = left, .y = top, .width = pad_width, .height = pad_height, }; - wlr_matrix_project_box(matrix, &box, 0, 0, wlr_output->transform_matrix); - wlr_render_colored_quad(sample->renderer, sample->pad_color, matrix); + wlr_render_rect(sample->renderer, &box, sample->pad_color, + wlr_output->transform_matrix); if (sample->proximity) { struct wlr_box box = { @@ -75,16 +74,17 @@ static void handle_output_frame(struct output_state *output, struct timespec *ts .width = 16 * (sample->pressure + 1), .height = 16 * (sample->pressure + 1), }; - wlr_matrix_project_box(matrix, &box, 0, sample->ring, - wlr_output->transform_matrix); - wlr_render_colored_quad(sample->renderer, tool_color, matrix); + float matrix[9]; + wlr_matrix_project_box(matrix, &box, WL_OUTPUT_TRANSFORM_NORMAL, + sample->ring, wlr_output->transform_matrix); + wlr_render_quad_with_matrix(sample->renderer, tool_color, matrix); + box.x += sample->x_tilt; box.y += sample->y_tilt; box.width /= 2; box.height /= 2; - wlr_matrix_project_box(matrix, &box, 0, 0, + wlr_render_rect(sample->renderer, &box, tool_color, wlr_output->transform_matrix); - wlr_render_colored_quad(sample->renderer, tool_color, matrix); } wlr_renderer_end(sample->renderer); diff --git a/include/rootston/config.h b/include/rootston/config.h index 9926d9c2..0a67ac1e 100644 --- a/include/rootston/config.h +++ b/include/rootston/config.h @@ -66,8 +66,10 @@ struct roots_config { struct wl_list bindings; struct wl_list keyboards; struct wl_list cursors; + char *config_path; char *startup_cmd; + bool debug_damage_tracking; }; /** diff --git a/include/wlr/render/interface.h b/include/wlr/render/interface.h index 7f25c0ff..d4cd35f8 100644 --- a/include/wlr/render/interface.h +++ b/include/wlr/render/interface.h @@ -27,9 +27,9 @@ struct wlr_renderer_impl { bool (*render_texture_with_matrix)(struct wlr_renderer *renderer, struct wlr_texture *texture, const float matrix[static 9], float alpha); - void (*render_quad)(struct wlr_renderer *renderer, + void (*render_quad_with_matrix)(struct wlr_renderer *renderer, const float color[static 4], const float matrix[static 9]); - void (*render_ellipse)(struct wlr_renderer *renderer, + void (*render_ellipse_with_matrix)(struct wlr_renderer *renderer, const float color[static 4], const float matrix[static 9]); const enum wl_shm_format *(*formats)( struct wlr_renderer *renderer, size_t *len); diff --git a/include/wlr/render/wlr_renderer.h b/include/wlr/render/wlr_renderer.h index 6f0d2ecc..5c78089e 100644 --- a/include/wlr/render/wlr_renderer.h +++ b/include/wlr/render/wlr_renderer.h @@ -36,14 +36,24 @@ bool wlr_render_texture(struct wlr_renderer *r, struct wlr_texture *texture, bool wlr_render_texture_with_matrix(struct wlr_renderer *r, struct wlr_texture *texture, const float matrix[static 9], float alpha); /** - * Renders a solid quad in the specified color. + * Renders a solid rectangle in the specified color. */ -void wlr_render_colored_quad(struct wlr_renderer *r, +void wlr_render_rect(struct wlr_renderer *r, const struct wlr_box *box, + const float color[static 4], const float projection[static 9]); +/** + * Renders a solid quadrangle in the specified color with the specified matrix. + */ +void wlr_render_quad_with_matrix(struct wlr_renderer *r, const float color[static 4], const float matrix[static 9]); /** * Renders a solid ellipse in the specified color. */ -void wlr_render_colored_ellipse(struct wlr_renderer *r, +void wlr_render_ellipse(struct wlr_renderer *r, const struct wlr_box *box, + const float color[static 4], const float projection[static 9]); +/** + * Renders a solid ellipse in the specified color with the specified matrix. + */ +void wlr_render_ellipse_with_matrix(struct wlr_renderer *r, const float color[static 4], const float matrix[static 9]); /** * Returns a list of pixel formats supported by this renderer. diff --git a/include/wlr/types/wlr_box.h b/include/wlr/types/wlr_box.h index fc86f0ac..0e586a18 100644 --- a/include/wlr/types/wlr_box.h +++ b/include/wlr/types/wlr_box.h @@ -27,7 +27,7 @@ void wlr_box_transform(const struct wlr_box *box, struct wlr_box *dest); /** - * Creates the smallest box that contains a rotated box. + * Creates the smallest box that contains the box rotated about its center. */ void wlr_box_rotated_bounds(const struct wlr_box *box, float rotation, struct wlr_box *dest); diff --git a/include/wlr/types/wlr_xdg_shell.h b/include/wlr/types/wlr_xdg_shell.h index 410663f7..fa808b60 100644 --- a/include/wlr/types/wlr_xdg_shell.h +++ b/include/wlr/types/wlr_xdg_shell.h @@ -40,6 +40,9 @@ struct wlr_xdg_popup { bool committed; struct wlr_xdg_surface *parent; struct wlr_seat *seat; + + // Position of the popup relative to the upper left corner of the window + // geometry of the parent surface struct wlr_box geometry; struct wl_list grab_link; // wlr_xdg_popup_grab::popups diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index 3bfb97a4..ae3986ed 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -40,6 +40,9 @@ struct wlr_xdg_popup_v6 { bool committed; struct wlr_xdg_surface_v6 *parent; struct wlr_seat *seat; + + // Position of the popup relative to the upper left corner of the window + // geometry of the parent surface struct wlr_box geometry; struct wl_list grab_link; // wlr_xdg_popup_grab_v6::popups diff --git a/include/wlr/util/region.h b/include/wlr/util/region.h index 7883af97..c0fe6063 100644 --- a/include/wlr/util/region.h +++ b/include/wlr/util/region.h @@ -26,4 +26,11 @@ void wlr_region_transform(pixman_region32_t *dst, pixman_region32_t *src, void wlr_region_expand(pixman_region32_t *dst, pixman_region32_t *src, int distance); +/* + * Builds the smallest possible region that contains the region rotated about + * the point (ox, oy). + */ +void wlr_region_rotated_bounds(pixman_region32_t *dst, pixman_region32_t *src, + float rotation, int ox, int oy); + #endif diff --git a/meson.build b/meson.build index c7ca038c..7740b416 100644 --- a/meson.build +++ b/meson.build @@ -58,14 +58,6 @@ libinput = dependency('libinput', version: '>=1.7.0') xkbcommon = dependency('xkbcommon') udev = dependency('libudev') pixman = dependency('pixman-1') -xcb = dependency('xcb') -xcb_composite = dependency('xcb-composite') -xcb_xfixes = dependency('xcb-xfixes') -xcb_image = dependency('xcb-image') -xcb_render = dependency('xcb-render') -xcb_icccm = dependency('xcb-icccm', required: false) -xcb_errors = dependency('xcb-errors', required: get_option('enable_xcb_errors') == 'true') -x11_xcb = dependency('x11-xcb') libcap = dependency('libcap', required: get_option('enable_libcap') == 'true') systemd = dependency('libsystemd', required: get_option('enable_systemd') == 'true') elogind = dependency('libelogind', required: get_option('enable_elogind') == 'true') @@ -75,14 +67,6 @@ exclude_headers = [] wlr_parts = [] wlr_deps = [] -if xcb_icccm.found() - conf_data.set('WLR_HAS_XCB_ICCCM', true) -endif - -if xcb_errors.found() and get_option('enable_xcb_errors') != 'false' - conf_data.set('WLR_HAS_XCB_ERRORS', true) -endif - if libcap.found() and get_option('enable_libcap') != 'false' conf_data.set('WLR_HAS_LIBCAP', true) wlr_deps += libcap @@ -97,6 +81,38 @@ if elogind.found() and get_option('enable_elogind') != 'false' conf_data.set('WLR_HAS_ELOGIND', true) endif +if get_option('enable_x11_backend') or get_option('enable_xwayland') + xcb = dependency('xcb') + xcb_composite = dependency('xcb-composite') + xcb_xfixes = dependency('xcb-xfixes') + xcb_image = dependency('xcb-image') + xcb_render = dependency('xcb-render') + x11_xcb = dependency('x11-xcb') + + xcb_icccm = dependency('xcb-icccm', required: false) + xcb_errors = dependency('xcb-errors', required: get_option('enable_xcb_errors') == 'true') + + if xcb_icccm.found() + conf_data.set('WLR_HAS_XCB_ICCCM', true) + endif + + if xcb_errors.found() and get_option('enable_xcb_errors') != 'false' + conf_data.set('WLR_HAS_XCB_ERRORS', true) + endif + + wlr_deps += [ + xcb, + xcb_composite, + x11_xcb, + ] +else + add_project_arguments('-DMESA_EGL_NO_X11_HEADERS', language: 'c') +endif + +if get_option('enable_x11_backend') + conf_data.set('WLR_HAS_X11_BACKEND', true) +endif + if get_option('enable_xwayland') subdir('xwayland') wlr_parts += [lib_wlr_xwayland] @@ -138,9 +154,6 @@ wlr_deps += [ xkbcommon, udev, pixman, - xcb, - xcb_composite, - x11_xcb, math, ] @@ -168,12 +181,13 @@ summary = [ '----------------', 'wlroots @0@'.format(meson.project_version()), '', - ' libcap: @0@'.format(conf_data.get('WLR_HAS_LIBCAP', false)), - ' systemd: @0@'.format(conf_data.get('WLR_HAS_SYSTEMD', false)), - ' elogind: @0@'.format(conf_data.get('WLR_HAS_ELOGIND', false)), - ' xwayland: @0@'.format(conf_data.get('WLR_HAS_XWAYLAND', false)), - ' xcb-icccm: @0@'.format(conf_data.get('WLR_HAS_XCB_ICCCM', false)), - ' xcb-errors: @0@'.format(conf_data.get('WLR_HAS_XCB_ERRORS', false)), + ' libcap: @0@'.format(conf_data.get('WLR_HAS_LIBCAP', false)), + ' systemd: @0@'.format(conf_data.get('WLR_HAS_SYSTEMD', false)), + ' elogind: @0@'.format(conf_data.get('WLR_HAS_ELOGIND', false)), + ' xwayland: @0@'.format(conf_data.get('WLR_HAS_XWAYLAND', false)), + ' x11_backend: @0@'.format(conf_data.get('WLR_HAS_X11_BACKEND', false)), + ' xcb-icccm: @0@'.format(conf_data.get('WLR_HAS_XCB_ICCCM', false)), + ' xcb-errors: @0@'.format(conf_data.get('WLR_HAS_XCB_ERRORS', false)), '----------------', '' ] diff --git a/meson_options.txt b/meson_options.txt index 4812b6f8..9e8567d0 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -3,3 +3,4 @@ option('enable_systemd', type: 'combo', choices: ['auto', 'true', 'false'], valu option('enable_elogind', type: 'combo', choices: ['auto', 'true', 'false'], value: 'auto', description: 'Enable support for logind') option('enable_xcb_errors', type: 'combo', choices: ['auto', 'true', 'false'], value: 'auto', description: 'Use xcb-errors util library') option('enable_xwayland', type: 'boolean', value: true, description: 'Enable support X11 applications') +option('enable_x11_backend', type: 'boolean', value: true, description: 'Enable X11 backend') diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index 9403c0ed..61665a07 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -144,7 +144,7 @@ static bool gles2_render_texture_with_matrix( } -static void gles2_render_quad(struct wlr_renderer *wlr_renderer, +static void gles2_render_quad_with_matrix(struct wlr_renderer *wlr_renderer, const float color[static 4], const float matrix[static 9]) { struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer); @@ -161,7 +161,7 @@ static void gles2_render_quad(struct wlr_renderer *wlr_renderer, GLES2_DEBUG_POP; } -static void gles2_render_ellipse(struct wlr_renderer *wlr_renderer, +static void gles2_render_ellipse_with_matrix(struct wlr_renderer *wlr_renderer, const float color[static 4], const float matrix[static 9]) { struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer); @@ -256,8 +256,8 @@ static const struct wlr_renderer_impl renderer_impl = { .scissor = gles2_scissor, .texture_create = gles2_renderer_texture_create, .render_texture_with_matrix = gles2_render_texture_with_matrix, - .render_quad = gles2_render_quad, - .render_ellipse = gles2_render_ellipse, + .render_quad_with_matrix = gles2_render_quad_with_matrix, + .render_ellipse_with_matrix = gles2_render_ellipse_with_matrix, .formats = gles2_renderer_formats, .buffer_is_drm = gles2_buffer_is_drm, .read_pixels = gles2_read_pixels, diff --git a/render/wlr_renderer.c b/render/wlr_renderer.c index 622aa1dd..5598a0e7 100644 --- a/render/wlr_renderer.c +++ b/render/wlr_renderer.c @@ -39,13 +39,16 @@ struct wlr_texture *wlr_render_texture_create(struct wlr_renderer *r) { bool wlr_render_texture(struct wlr_renderer *r, struct wlr_texture *texture, const float projection[static 9], int x, int y, float alpha) { - float mat[9]; - wlr_matrix_identity(mat); - wlr_matrix_translate(mat, x, y); - wlr_matrix_scale(mat, texture->width, texture->height); - wlr_matrix_multiply(mat, projection, mat); + const struct wlr_box box = { + .x = x, .y = y, + .width = texture->width, .height = texture->height, + }; - return wlr_render_texture_with_matrix(r, texture, mat, alpha); + float matrix[9]; + wlr_matrix_project_box(matrix, &box, WL_OUTPUT_TRANSFORM_NORMAL, 0, + projection); + + return wlr_render_texture_with_matrix(r, texture, matrix, alpha); } bool wlr_render_texture_with_matrix(struct wlr_renderer *r, @@ -54,14 +57,32 @@ bool wlr_render_texture_with_matrix(struct wlr_renderer *r, return r->impl->render_texture_with_matrix(r, texture, matrix, alpha); } -void wlr_render_colored_quad(struct wlr_renderer *r, +void wlr_render_rect(struct wlr_renderer *r, const struct wlr_box *box, + const float color[static 4], const float projection[static 9]) { + float matrix[9]; + wlr_matrix_project_box(matrix, box, WL_OUTPUT_TRANSFORM_NORMAL, 0, + projection); + + wlr_render_quad_with_matrix(r, color, matrix); +} + +void wlr_render_quad_with_matrix(struct wlr_renderer *r, const float color[static 4], const float matrix[static 9]) { - r->impl->render_quad(r, color, matrix); + r->impl->render_quad_with_matrix(r, color, matrix); +} + +void wlr_render_ellipse(struct wlr_renderer *r, const struct wlr_box *box, + const float color[static 4], const float projection[static 9]) { + float matrix[9]; + wlr_matrix_project_box(matrix, box, WL_OUTPUT_TRANSFORM_NORMAL, 0, + projection); + + wlr_render_ellipse_with_matrix(r, color, matrix); } -void wlr_render_colored_ellipse(struct wlr_renderer *r, +void wlr_render_ellipse_with_matrix(struct wlr_renderer *r, const float color[static 4], const float matrix[static 9]) { - r->impl->render_ellipse(r, color, matrix); + r->impl->render_ellipse_with_matrix(r, color, matrix); } const enum wl_shm_format *wlr_renderer_get_formats( diff --git a/rootston/config.c b/rootston/config.c index e63efc0b..0883f6d4 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -25,7 +25,9 @@ static void usage(const char *name, int ret) { " (default: rootston.ini).\n" " See `rootston.ini.example` for config\n" " file documentation.\n" - " -E <COMMAND> Command that will be ran at startup.\n" , name); + " -E <COMMAND> Command that will be ran at startup.\n" + " -D Enable damage tracking debugging.\n", + name); exit(ret); } @@ -394,7 +396,7 @@ struct roots_config *roots_config_create_from_args(int argc, char *argv[]) { wl_list_init(&config->bindings); int c; - while ((c = getopt(argc, argv, "C:E:h")) != -1) { + while ((c = getopt(argc, argv, "C:E:hD")) != -1) { switch (c) { case 'C': config->config_path = strdup(optarg); @@ -402,6 +404,9 @@ struct roots_config *roots_config_create_from_args(int argc, char *argv[]) { case 'E': config->startup_cmd = strdup(optarg); break; + case 'D': + config->debug_damage_tracking = true; + break; case 'h': case '?': usage(argv[0], c != 'h'); diff --git a/rootston/input.c b/rootston/input.c index 657b0946..962be9fa 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -5,7 +5,9 @@ #include <wlr/types/wlr_cursor.h> #include <wlr/util/log.h> #include <wlr/xcursor.h> +#ifdef WLR_HAS_XWAYLAND #include <wlr/xwayland.h> +#endif #include "rootston/config.h" #include "rootston/input.h" #include "rootston/keyboard.h" diff --git a/rootston/output.c b/rootston/output.c index 1284c928..8d6444d6 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -363,7 +363,7 @@ static void render_decorations(struct roots_view *view, pixman_region32_rectangles(&damage, &nrects); for (int i = 0; i < nrects; ++i) { scissor_output(output, &rects[i]); - wlr_render_colored_quad(renderer, color, matrix); + wlr_render_quad_with_matrix(renderer, color, matrix); } damage_finish: @@ -486,6 +486,10 @@ static void render_output(struct roots_output *output) { goto renderer_end; } + if (server->config->debug_damage_tracking) { + wlr_renderer_clear(renderer, (float[]){1, 1, 0, 0}); + } + int nrects; pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects); for (int i = 0; i < nrects; ++i) { @@ -667,32 +671,23 @@ static void damage_from_surface(struct wlr_surface *surface, surface_intersect_output(surface, output->desktop->layout, wlr_output, lx, ly, rotation, &box); - if (rotation == 0) { - pixman_region32_t damage; - pixman_region32_init(&damage); - pixman_region32_copy(&damage, &surface->current->surface_damage); - wlr_region_scale(&damage, &damage, wlr_output->scale); - if (ceil(wlr_output->scale) > surface->current->scale) { - // When scaling up a surface, it'll become blurry so we need to - // expand the damage region - wlr_region_expand(&damage, &damage, - ceil(wlr_output->scale) - surface->current->scale); - } - pixman_region32_translate(&damage, box.x, box.y); - wlr_output_damage_add(output->damage, &damage); - pixman_region32_fini(&damage); - } else { - pixman_box32_t *extents = - pixman_region32_extents(&surface->current->surface_damage); - struct wlr_box damage_box = { - .x = box.x + extents->x1 * wlr_output->scale, - .y = box.y + extents->y1 * wlr_output->scale, - .width = (extents->x2 - extents->x1) * wlr_output->scale, - .height = (extents->y2 - extents->y1) * wlr_output->scale, - }; - wlr_box_rotated_bounds(&damage_box, rotation, &damage_box); - wlr_output_damage_add_box(output->damage, &damage_box); - } + int center_x = box.x + box.width/2; + int center_y = box.y + box.height/2; + + pixman_region32_t damage; + pixman_region32_init(&damage); + pixman_region32_copy(&damage, &surface->current->surface_damage); + wlr_region_scale(&damage, &damage, wlr_output->scale); + if (ceil(wlr_output->scale) > surface->current->scale) { + // When scaling up a surface, it'll become blurry so we need to + // expand the damage region + wlr_region_expand(&damage, &damage, + ceil(wlr_output->scale) - surface->current->scale); + } + pixman_region32_translate(&damage, box.x, box.y); + wlr_region_rotated_bounds(&damage, &damage, rotation, center_x, center_y); + wlr_output_damage_add(output->damage, &damage); + pixman_region32_fini(&damage); } void output_damage_from_view(struct roots_output *output, diff --git a/rootston/seat.c b/rootston/seat.c index d2d211ba..017e6221 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -723,6 +723,33 @@ void roots_seat_set_focus(struct roots_seat *seat, struct roots_view *view) { wl_list_insert(&seat->input->server->desktop->views, &view->link); } + + bool unfullscreen = true; + +#ifdef WLR_HAS_XWAYLAND + if (view && view->type == ROOTS_XWAYLAND_VIEW && + view->xwayland_surface->override_redirect) { + unfullscreen = false; + } +#endif + + if (unfullscreen) { + struct roots_desktop *desktop = view->desktop; + struct roots_output *output; + struct wlr_box box; + view_get_box(view, &box); + wl_list_for_each(output, &desktop->outputs, link) { + if (output->fullscreen_view && + output->fullscreen_view != view && + wlr_output_layout_intersects( + desktop->layout, + output->wlr_output, &box)) { + view_set_fullscreen(output->fullscreen_view, + false, NULL); + } + } + } + struct roots_view *prev_focus = roots_seat_get_focus(seat); if (view == prev_focus) { return; diff --git a/types/wlr_xdg_shell.c b/types/wlr_xdg_shell.c index f08f9c77..cf713eb9 100644 --- a/types/wlr_xdg_shell.c +++ b/types/wlr_xdg_shell.c @@ -194,7 +194,9 @@ static void xdg_surface_unmap(struct wlr_xdg_surface *surface) { assert(surface->role != WLR_XDG_SURFACE_ROLE_NONE); // TODO: probably need to ungrab before this event - wlr_signal_emit_safe(&surface->events.unmap, surface); + if (surface->mapped) { + wlr_signal_emit_safe(&surface->events.unmap, surface); + } if (surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) { wl_resource_set_user_data(surface->toplevel->resource, NULL); diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index 0043330c..464e0157 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -194,7 +194,9 @@ static void xdg_surface_unmap(struct wlr_xdg_surface_v6 *surface) { assert(surface->role != WLR_XDG_SURFACE_V6_ROLE_NONE); // TODO: probably need to ungrab before this event - wlr_signal_emit_safe(&surface->events.unmap, surface); + if (surface->mapped) { + wlr_signal_emit_safe(&surface->events.unmap, surface); + } if (surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { wl_resource_set_user_data(surface->toplevel->resource, NULL); diff --git a/util/region.c b/util/region.c index 88e38fd2..38f84c5e 100644 --- a/util/region.c +++ b/util/region.c @@ -128,3 +128,52 @@ void wlr_region_expand(pixman_region32_t *dst, pixman_region32_t *src, pixman_region32_init_rects(dst, dst_rects, nrects); free(dst_rects); } + +void wlr_region_rotated_bounds(pixman_region32_t *dst, pixman_region32_t *src, + float rotation, int ox, int oy) { + if (rotation == 0) { + pixman_region32_copy(dst, src); + return; + } + + int nrects; + pixman_box32_t *src_rects = pixman_region32_rectangles(src, &nrects); + + pixman_box32_t *dst_rects = malloc(nrects * sizeof(pixman_box32_t)); + if (dst_rects == NULL) { + return; + } + + for (int i = 0; i < nrects; ++i) { + double x1 = src_rects[i].x1 - ox; + double y1 = src_rects[i].y1 - oy; + double x2 = src_rects[i].x2 - ox; + double y2 = src_rects[i].y2 - oy; + + double rx1 = x1 * cos(rotation) - y1 * sin(rotation); + double ry1 = x1 * sin(rotation) + y1 * cos(rotation); + + double rx2 = x2 * cos(rotation) - y1 * sin(rotation); + double ry2 = x2 * sin(rotation) + y1 * cos(rotation); + + double rx3 = x2 * cos(rotation) - y2 * sin(rotation); + double ry3 = x2 * sin(rotation) + y2 * cos(rotation); + + double rx4 = x1 * cos(rotation) - y2 * sin(rotation); + double ry4 = x1 * sin(rotation) + y2 * cos(rotation); + + x1 = fmin(fmin(rx1, rx2), fmin(rx3, rx4)); + y1 = fmin(fmin(ry1, ry2), fmin(ry3, ry4)); + x2 = fmax(fmax(rx1, rx2), fmax(rx3, rx4)); + y2 = fmax(fmax(ry1, ry2), fmax(ry3, ry4)); + + dst_rects[i].x1 = floor(ox + x1); + dst_rects[i].x2 = ceil(ox + x2); + dst_rects[i].y1 = floor(oy + y1); + dst_rects[i].y2 = ceil(oy + y2); + } + + pixman_region32_fini(dst); + pixman_region32_init_rects(dst, dst_rects, nrects); + free(dst_rects); +} |