aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree/view.c
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-08-19 11:01:51 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-08-20 09:23:24 +1000
commit0f6d212629964c6a131b5675fa6c9f4d48da43aa (patch)
tree2dec4ff1e44ede939eb01927425c5da61e41ab5e /sway/tree/view.c
parentMerge pull request #2493 from RyanDwyer/fix-popup-position (diff)
downloadsway-0f6d212629964c6a131b5675fa6c9f4d48da43aa.tar.gz
sway-0f6d212629964c6a131b5675fa6c9f4d48da43aa.tar.zst
sway-0f6d212629964c6a131b5675fa6c9f4d48da43aa.zip
Send output enter/leave events correctly
Previously we used a reparent event to detect when a view changes parent, then sent an output enter/leave to the surfaces if needed. This worked for tiling views but not floating views, as floating views can intersect another output without changing parent. The solution implemented for floating views also applies cleanly to tiling views, so the previous method has been completely replaced and the reparent event has been removed. This introduces a new function container_discover_outputs. This function compares the container's `current` position to the outputs, sends enter and leave events as needed, and keeps track of which outputs it's intersecting in a new `container->outputs` list. If it has entered a new output with a different scale then the title and marks textures will also be recreated at the new scale. The function is called when a transaction applies. This is convenient as it means we don't have to call it from various places. There is imperfect rendering when a floating view overlaps two outputs with different scales. It renders correctly for the most recently entered output, but there is only one title texture so it renders incorrectly on the old output. Fixes #2482
Diffstat (limited to 'sway/tree/view.c')
-rw-r--r--sway/tree/view.c58
1 files changed, 4 insertions, 54 deletions
diff --git a/sway/tree/view.c b/sway/tree/view.c
index b77a9bb2..4abf1abb 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -364,48 +364,6 @@ static void view_handle_surface_new_subsurface(struct wl_listener *listener,
364 view_subsurface_create(view, subsurface); 364 view_subsurface_create(view, subsurface);
365} 365}
366 366
367static void surface_send_enter_iterator(struct wlr_surface *surface,
368 int x, int y, void *data) {
369 struct wlr_output *wlr_output = data;
370 wlr_surface_send_enter(surface, wlr_output);
371}
372
373static void surface_send_leave_iterator(struct wlr_surface *surface,
374 int x, int y, void *data) {
375 struct wlr_output *wlr_output = data;
376 wlr_surface_send_leave(surface, wlr_output);
377}
378
379static void view_handle_container_reparent(struct wl_listener *listener,
380 void *data) {
381 struct sway_view *view =
382 wl_container_of(listener, view, container_reparent);
383 struct sway_container *old_parent = data;
384
385 struct sway_container *old_output = old_parent;
386 if (old_output != NULL && old_output->type != C_OUTPUT) {
387 old_output = container_parent(old_output, C_OUTPUT);
388 }
389
390 struct sway_container *new_output = view->swayc->parent;
391 if (new_output != NULL && new_output->type != C_OUTPUT) {
392 new_output = container_parent(new_output, C_OUTPUT);
393 }
394
395 if (old_output == new_output) {
396 return;
397 }
398
399 if (old_output != NULL) {
400 view_for_each_surface(view, surface_send_leave_iterator,
401 old_output->sway_output->wlr_output);
402 }
403 if (new_output != NULL) {
404 view_for_each_surface(view, surface_send_enter_iterator,
405 new_output->sway_output->wlr_output);
406 }
407}
408
409static bool view_has_executed_criteria(struct sway_view *view, 367static bool view_has_executed_criteria(struct sway_view *view,
410 struct criteria *criteria) { 368 struct criteria *criteria) {
411 for (int i = 0; i < view->executed_criteria->length; ++i) { 369 for (int i = 0; i < view->executed_criteria->length; ++i) {
@@ -567,9 +525,6 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
567 &view->surface_new_subsurface); 525 &view->surface_new_subsurface);
568 view->surface_new_subsurface.notify = view_handle_surface_new_subsurface; 526 view->surface_new_subsurface.notify = view_handle_surface_new_subsurface;
569 527
570 wl_signal_add(&view->swayc->events.reparent, &view->container_reparent);
571 view->container_reparent.notify = view_handle_container_reparent;
572
573 if (view->impl->wants_floating && view->impl->wants_floating(view)) { 528 if (view->impl->wants_floating && view->impl->wants_floating(view)) {
574 view->border = config->floating_border; 529 view->border = config->floating_border;
575 view->border_thickness = config->floating_border_thickness; 530 view->border_thickness = config->floating_border_thickness;
@@ -587,15 +542,12 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
587 view_update_title(view, false); 542 view_update_title(view, false);
588 container_notify_subtree_changed(view->swayc->parent); 543 container_notify_subtree_changed(view->swayc->parent);
589 view_execute_criteria(view); 544 view_execute_criteria(view);
590
591 view_handle_container_reparent(&view->container_reparent, NULL);
592} 545}
593 546
594void view_unmap(struct sway_view *view) { 547void view_unmap(struct sway_view *view) {
595 wl_signal_emit(&view->events.unmap, view); 548 wl_signal_emit(&view->events.unmap, view);
596 549
597 wl_list_remove(&view->surface_new_subsurface.link); 550 wl_list_remove(&view->surface_new_subsurface.link);
598 wl_list_remove(&view->container_reparent.link);
599 551
600 if (view->urgent_timer) { 552 if (view->urgent_timer) {
601 wl_event_source_remove(view->urgent_timer); 553 wl_event_source_remove(view->urgent_timer);
@@ -937,10 +889,8 @@ void view_add_mark(struct sway_view *view, char *mark) {
937 889
938static void update_marks_texture(struct sway_view *view, 890static void update_marks_texture(struct sway_view *view,
939 struct wlr_texture **texture, struct border_colors *class) { 891 struct wlr_texture **texture, struct border_colors *class) {
940 struct sway_container *output = container_parent(view->swayc, C_OUTPUT); 892 struct sway_output *output =
941 if (!output) { 893 view->swayc->outputs->items[view->swayc->outputs->length - 1];
942 return;
943 }
944 if (*texture) { 894 if (*texture) {
945 wlr_texture_destroy(*texture); 895 wlr_texture_destroy(*texture);
946 *texture = NULL; 896 *texture = NULL;
@@ -973,7 +923,7 @@ static void update_marks_texture(struct sway_view *view,
973 } 923 }
974 free(part); 924 free(part);
975 925
976 double scale = output->sway_output->wlr_output->scale; 926 double scale = output->wlr_output->scale;
977 int width = 0; 927 int width = 0;
978 int height = view->swayc->title_height * scale; 928 int height = view->swayc->title_height * scale;
979 929
@@ -999,7 +949,7 @@ static void update_marks_texture(struct sway_view *view,
999 unsigned char *data = cairo_image_surface_get_data(surface); 949 unsigned char *data = cairo_image_surface_get_data(surface);
1000 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); 950 int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
1001 struct wlr_renderer *renderer = wlr_backend_get_renderer( 951 struct wlr_renderer *renderer = wlr_backend_get_renderer(
1002 output->sway_output->wlr_output->backend); 952 output->wlr_output->backend);
1003 *texture = wlr_texture_from_pixels( 953 *texture = wlr_texture_from_pixels(
1004 renderer, WL_SHM_FORMAT_ARGB8888, stride, width, height, data); 954 renderer, WL_SHM_FORMAT_ARGB8888, stride, width, height, data);
1005 cairo_surface_destroy(surface); 955 cairo_surface_destroy(surface);