diff options
Diffstat (limited to 'sway/tree')
-rw-r--r-- | sway/tree/container.c | 148 | ||||
-rw-r--r-- | sway/tree/layout.c | 14 | ||||
-rw-r--r-- | sway/tree/output.c | 2 | ||||
-rw-r--r-- | sway/tree/view.c | 31 |
4 files changed, 145 insertions, 50 deletions
diff --git a/sway/tree/container.c b/sway/tree/container.c index 4e85021d..b980c5e9 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -62,8 +62,10 @@ void container_create_notify(struct sway_container *container) { | |||
62 | // TODO send ipc event type based on the container type | 62 | // TODO send ipc event type based on the container type |
63 | wl_signal_emit(&root_container.sway_root->events.new_container, container); | 63 | wl_signal_emit(&root_container.sway_root->events.new_container, container); |
64 | 64 | ||
65 | if (container->type == C_VIEW || container->type == C_CONTAINER) { | 65 | if (container->type == C_VIEW) { |
66 | ipc_event_window(container, "new"); | 66 | ipc_event_window(container, "new"); |
67 | } else if (container->type == C_WORKSPACE) { | ||
68 | ipc_event_workspace(NULL, container, "init"); | ||
67 | } | 69 | } |
68 | } | 70 | } |
69 | 71 | ||
@@ -281,7 +283,7 @@ static struct sway_container *container_output_destroy( | |||
281 | container_remove_child(workspace); | 283 | container_remove_child(workspace); |
282 | if (!workspace_is_empty(workspace)) { | 284 | if (!workspace_is_empty(workspace)) { |
283 | container_add_child(new_output, workspace); | 285 | container_add_child(new_output, workspace); |
284 | ipc_event_workspace(workspace, NULL, "move"); | 286 | ipc_event_workspace(NULL, workspace, "move"); |
285 | } else { | 287 | } else { |
286 | container_destroy(workspace); | 288 | container_destroy(workspace); |
287 | } | 289 | } |
@@ -319,7 +321,13 @@ static struct sway_container *container_destroy_noreaping( | |||
319 | } | 321 | } |
320 | 322 | ||
321 | wl_signal_emit(&con->events.destroy, con); | 323 | wl_signal_emit(&con->events.destroy, con); |
322 | ipc_event_window(con, "close"); | 324 | |
325 | // emit IPC event | ||
326 | if (con->type == C_VIEW) { | ||
327 | ipc_event_window(con, "close"); | ||
328 | } else if (con->type == C_WORKSPACE) { | ||
329 | ipc_event_workspace(NULL, con, "empty"); | ||
330 | } | ||
323 | 331 | ||
324 | // The below functions move their children to somewhere else. | 332 | // The below functions move their children to somewhere else. |
325 | if (con->type == C_OUTPUT) { | 333 | if (con->type == C_OUTPUT) { |
@@ -561,10 +569,15 @@ static struct sway_container *container_at_view(struct sway_container *swayc, | |||
561 | *sx = _sx; | 569 | *sx = _sx; |
562 | *sy = _sy; | 570 | *sy = _sy; |
563 | *surface = _surface; | 571 | *surface = _surface; |
572 | return swayc; | ||
564 | } | 573 | } |
565 | return swayc; | 574 | return NULL; |
566 | } | 575 | } |
567 | 576 | ||
577 | static struct sway_container *tiling_container_at( | ||
578 | struct sway_container *con, double lx, double ly, | ||
579 | struct wlr_surface **surface, double *sx, double *sy); | ||
580 | |||
568 | /** | 581 | /** |
569 | * container_at for a container with layout L_TABBED. | 582 | * container_at for a container with layout L_TABBED. |
570 | */ | 583 | */ |
@@ -591,7 +604,7 @@ static struct sway_container *container_at_tabbed(struct sway_container *parent, | |||
591 | // Surfaces | 604 | // Surfaces |
592 | struct sway_container *current = seat_get_active_child(seat, parent); | 605 | struct sway_container *current = seat_get_active_child(seat, parent); |
593 | 606 | ||
594 | return container_at(current, lx, ly, surface, sx, sy); | 607 | return tiling_container_at(current, lx, ly, surface, sx, sy); |
595 | } | 608 | } |
596 | 609 | ||
597 | /** | 610 | /** |
@@ -616,7 +629,7 @@ static struct sway_container *container_at_stacked( | |||
616 | // Surfaces | 629 | // Surfaces |
617 | struct sway_container *current = seat_get_active_child(seat, parent); | 630 | struct sway_container *current = seat_get_active_child(seat, parent); |
618 | 631 | ||
619 | return container_at(current, lx, ly, surface, sx, sy); | 632 | return tiling_container_at(current, lx, ly, surface, sx, sy); |
620 | } | 633 | } |
621 | 634 | ||
622 | /** | 635 | /** |
@@ -634,45 +647,13 @@ static struct sway_container *container_at_linear(struct sway_container *parent, | |||
634 | .height = child->height, | 647 | .height = child->height, |
635 | }; | 648 | }; |
636 | if (wlr_box_contains_point(&box, lx, ly)) { | 649 | if (wlr_box_contains_point(&box, lx, ly)) { |
637 | return container_at(child, lx, ly, surface, sx, sy); | 650 | return tiling_container_at(child, lx, ly, surface, sx, sy); |
638 | } | 651 | } |
639 | } | 652 | } |
640 | return NULL; | 653 | return NULL; |
641 | } | 654 | } |
642 | 655 | ||
643 | struct sway_container *container_at(struct sway_container *parent, | 656 | static struct sway_container *floating_container_at(double lx, double ly, |
644 | double lx, double ly, | ||
645 | struct wlr_surface **surface, double *sx, double *sy) { | ||
646 | if (!sway_assert(parent->type >= C_WORKSPACE, | ||
647 | "Expected workspace or deeper")) { | ||
648 | return NULL; | ||
649 | } | ||
650 | if (parent->type == C_VIEW) { | ||
651 | return container_at_view(parent, lx, ly, surface, sx, sy); | ||
652 | } | ||
653 | if (!parent->children->length) { | ||
654 | return NULL; | ||
655 | } | ||
656 | |||
657 | switch (parent->layout) { | ||
658 | case L_HORIZ: | ||
659 | case L_VERT: | ||
660 | return container_at_linear(parent, lx, ly, surface, sx, sy); | ||
661 | case L_TABBED: | ||
662 | return container_at_tabbed(parent, lx, ly, surface, sx, sy); | ||
663 | case L_STACKED: | ||
664 | return container_at_stacked(parent, lx, ly, surface, sx, sy); | ||
665 | case L_FLOATING: | ||
666 | sway_assert(false, "Didn't expect to see floating here"); | ||
667 | return NULL; | ||
668 | case L_NONE: | ||
669 | return NULL; | ||
670 | } | ||
671 | |||
672 | return NULL; | ||
673 | } | ||
674 | |||
675 | struct sway_container *floating_container_at(double lx, double ly, | ||
676 | struct wlr_surface **surface, double *sx, double *sy) { | 657 | struct wlr_surface **surface, double *sx, double *sy) { |
677 | for (int i = 0; i < root_container.children->length; ++i) { | 658 | for (int i = 0; i < root_container.children->length; ++i) { |
678 | struct sway_container *output = root_container.children->items[i]; | 659 | struct sway_container *output = root_container.children->items[i]; |
@@ -694,7 +675,8 @@ struct sway_container *floating_container_at(double lx, double ly, | |||
694 | .height = floater->height, | 675 | .height = floater->height, |
695 | }; | 676 | }; |
696 | if (wlr_box_contains_point(&box, lx, ly)) { | 677 | if (wlr_box_contains_point(&box, lx, ly)) { |
697 | return container_at(floater, lx, ly, surface, sx, sy); | 678 | return tiling_container_at(floater, lx, ly, |
679 | surface, sx, sy); | ||
698 | } | 680 | } |
699 | } | 681 | } |
700 | } | 682 | } |
@@ -702,6 +684,90 @@ struct sway_container *floating_container_at(double lx, double ly, | |||
702 | return NULL; | 684 | return NULL; |
703 | } | 685 | } |
704 | 686 | ||
687 | static struct sway_container *tiling_container_at( | ||
688 | struct sway_container *con, double lx, double ly, | ||
689 | struct wlr_surface **surface, double *sx, double *sy) { | ||
690 | if (con->type == C_VIEW) { | ||
691 | return container_at_view(con, lx, ly, surface, sx, sy); | ||
692 | } | ||
693 | if (!con->children->length) { | ||
694 | return NULL; | ||
695 | } | ||
696 | |||
697 | switch (con->layout) { | ||
698 | case L_HORIZ: | ||
699 | case L_VERT: | ||
700 | return container_at_linear(con, lx, ly, surface, sx, sy); | ||
701 | case L_TABBED: | ||
702 | return container_at_tabbed(con, lx, ly, surface, sx, sy); | ||
703 | case L_STACKED: | ||
704 | return container_at_stacked(con, lx, ly, surface, sx, sy); | ||
705 | case L_FLOATING: | ||
706 | sway_assert(false, "Didn't expect to see floating here"); | ||
707 | return NULL; | ||
708 | case L_NONE: | ||
709 | return NULL; | ||
710 | } | ||
711 | return NULL; | ||
712 | } | ||
713 | |||
714 | static bool surface_is_popup(struct wlr_surface *surface) { | ||
715 | if (wlr_surface_is_xdg_surface(surface)) { | ||
716 | struct wlr_xdg_surface *xdg_surface = | ||
717 | wlr_xdg_surface_from_wlr_surface(surface); | ||
718 | while (xdg_surface) { | ||
719 | if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { | ||
720 | return true; | ||
721 | } | ||
722 | xdg_surface = xdg_surface->toplevel->parent; | ||
723 | } | ||
724 | return false; | ||
725 | } | ||
726 | |||
727 | if (wlr_surface_is_xdg_surface_v6(surface)) { | ||
728 | struct wlr_xdg_surface_v6 *xdg_surface_v6 = | ||
729 | wlr_xdg_surface_v6_from_wlr_surface(surface); | ||
730 | while (xdg_surface_v6) { | ||
731 | if (xdg_surface_v6->role == WLR_XDG_SURFACE_V6_ROLE_POPUP) { | ||
732 | return true; | ||
733 | } | ||
734 | xdg_surface_v6 = xdg_surface_v6->toplevel->parent; | ||
735 | } | ||
736 | return false; | ||
737 | } | ||
738 | |||
739 | return false; | ||
740 | } | ||
741 | |||
742 | struct sway_container *container_at(struct sway_container *workspace, | ||
743 | double lx, double ly, | ||
744 | struct wlr_surface **surface, double *sx, double *sy) { | ||
745 | if (!sway_assert(workspace->type == C_WORKSPACE, "Expected a workspace")) { | ||
746 | return NULL; | ||
747 | } | ||
748 | struct sway_container *c; | ||
749 | // Focused view's popups | ||
750 | struct sway_seat *seat = input_manager_current_seat(input_manager); | ||
751 | struct sway_container *focus = | ||
752 | seat_get_focus_inactive(seat, &root_container); | ||
753 | if (focus && focus->type == C_VIEW) { | ||
754 | container_at_view(focus, lx, ly, surface, sx, sy); | ||
755 | if (*surface && surface_is_popup(*surface)) { | ||
756 | return focus; | ||
757 | } | ||
758 | *surface = NULL; | ||
759 | } | ||
760 | // Floating | ||
761 | if ((c = floating_container_at(lx, ly, surface, sx, sy))) { | ||
762 | return c; | ||
763 | } | ||
764 | // Tiling | ||
765 | if ((c = tiling_container_at(workspace, lx, ly, surface, sx, sy))) { | ||
766 | return c; | ||
767 | } | ||
768 | return NULL; | ||
769 | } | ||
770 | |||
705 | void container_for_each_descendant_dfs(struct sway_container *container, | 771 | void container_for_each_descendant_dfs(struct sway_container *container, |
706 | void (*f)(struct sway_container *container, void *data), | 772 | void (*f)(struct sway_container *container, void *data), |
707 | void *data) { | 773 | void *data) { |
diff --git a/sway/tree/layout.c b/sway/tree/layout.c index a0764a54..1f82e534 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c | |||
@@ -217,7 +217,9 @@ void container_move_to(struct sway_container *container, | |||
217 | container_sort_workspaces(new_parent); | 217 | container_sort_workspaces(new_parent); |
218 | seat_set_focus(seat, new_parent); | 218 | seat_set_focus(seat, new_parent); |
219 | workspace_output_raise_priority(container, old_parent, new_parent); | 219 | workspace_output_raise_priority(container, old_parent, new_parent); |
220 | ipc_event_workspace(container, NULL, "move"); | 220 | ipc_event_workspace(NULL, container, "move"); |
221 | } else if (container->type == C_VIEW) { | ||
222 | ipc_event_window(container, "move"); | ||
221 | } | 223 | } |
222 | container_notify_subtree_changed(old_parent); | 224 | container_notify_subtree_changed(old_parent); |
223 | container_notify_subtree_changed(new_parent); | 225 | container_notify_subtree_changed(new_parent); |
@@ -578,6 +580,10 @@ void container_move(struct sway_container *container, | |||
578 | container_notify_subtree_changed(old_parent); | 580 | container_notify_subtree_changed(old_parent); |
579 | container_notify_subtree_changed(container->parent); | 581 | container_notify_subtree_changed(container->parent); |
580 | 582 | ||
583 | if (container->type == C_VIEW) { | ||
584 | ipc_event_window(container, "move"); | ||
585 | } | ||
586 | |||
581 | if (old_parent) { | 587 | if (old_parent) { |
582 | seat_set_focus(config->handler_context.seat, old_parent); | 588 | seat_set_focus(config->handler_context.seat, old_parent); |
583 | seat_set_focus(config->handler_context.seat, container); | 589 | seat_set_focus(config->handler_context.seat, container); |
@@ -592,7 +598,7 @@ void container_move(struct sway_container *container, | |||
592 | next_ws = container_parent(next_ws, C_WORKSPACE); | 598 | next_ws = container_parent(next_ws, C_WORKSPACE); |
593 | } | 599 | } |
594 | if (last_ws && next_ws && last_ws != next_ws) { | 600 | if (last_ws && next_ws && last_ws != next_ws) { |
595 | ipc_event_workspace(last_ws, container, "focus"); | 601 | ipc_event_workspace(last_ws, next_ws, "focus"); |
596 | workspace_detect_urgent(last_ws); | 602 | workspace_detect_urgent(last_ws); |
597 | workspace_detect_urgent(next_ws); | 603 | workspace_detect_urgent(next_ws); |
598 | } | 604 | } |
@@ -995,13 +1001,13 @@ static void swap_focus(struct sway_container *con1, | |||
995 | if (focus == con1 && (con2->parent->layout == L_TABBED | 1001 | if (focus == con1 && (con2->parent->layout == L_TABBED |
996 | || con2->parent->layout == L_STACKED)) { | 1002 | || con2->parent->layout == L_STACKED)) { |
997 | if (workspace_is_visible(ws2)) { | 1003 | if (workspace_is_visible(ws2)) { |
998 | seat_set_focus_warp(seat, con2, false); | 1004 | seat_set_focus_warp(seat, con2, false, true); |
999 | } | 1005 | } |
1000 | seat_set_focus(seat, ws1 != ws2 ? con2 : con1); | 1006 | seat_set_focus(seat, ws1 != ws2 ? con2 : con1); |
1001 | } else if (focus == con2 && (con1->parent->layout == L_TABBED | 1007 | } else if (focus == con2 && (con1->parent->layout == L_TABBED |
1002 | || con1->parent->layout == L_STACKED)) { | 1008 | || con1->parent->layout == L_STACKED)) { |
1003 | if (workspace_is_visible(ws1)) { | 1009 | if (workspace_is_visible(ws1)) { |
1004 | seat_set_focus_warp(seat, con1, false); | 1010 | seat_set_focus_warp(seat, con1, false, true); |
1005 | } | 1011 | } |
1006 | seat_set_focus(seat, ws1 != ws2 ? con1 : con2); | 1012 | seat_set_focus(seat, ws1 != ws2 ? con1 : con2); |
1007 | } else if (ws1 != ws2) { | 1013 | } else if (ws1 != ws2) { |
diff --git a/sway/tree/output.c b/sway/tree/output.c index da535c18..31e3bf9b 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c | |||
@@ -22,7 +22,7 @@ static void restore_workspaces(struct sway_container *output) { | |||
22 | if (highest == output) { | 22 | if (highest == output) { |
23 | container_remove_child(ws); | 23 | container_remove_child(ws); |
24 | container_add_child(output, ws); | 24 | container_add_child(output, ws); |
25 | ipc_event_workspace(ws, NULL, "move"); | 25 | ipc_event_workspace(NULL, ws, "move"); |
26 | j--; | 26 | j--; |
27 | } | 27 | } |
28 | } | 28 | } |
diff --git a/sway/tree/view.c b/sway/tree/view.c index 0dbd3812..051b93ce 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -303,6 +303,12 @@ void view_close(struct sway_view *view) { | |||
303 | } | 303 | } |
304 | } | 304 | } |
305 | 305 | ||
306 | void view_close_popups(struct sway_view *view) { | ||
307 | if (view->impl->close_popups) { | ||
308 | view->impl->close_popups(view); | ||
309 | } | ||
310 | } | ||
311 | |||
306 | void view_damage_from(struct sway_view *view) { | 312 | void view_damage_from(struct sway_view *view) { |
307 | for (int i = 0; i < root_container.children->length; ++i) { | 313 | for (int i = 0; i < root_container.children->length; ++i) { |
308 | struct sway_container *cont = root_container.children->items[i]; | 314 | struct sway_container *cont = root_container.children->items[i]; |
@@ -333,6 +339,16 @@ void view_for_each_surface(struct sway_view *view, | |||
333 | } | 339 | } |
334 | } | 340 | } |
335 | 341 | ||
342 | void view_for_each_popup(struct sway_view *view, | ||
343 | wlr_surface_iterator_func_t iterator, void *user_data) { | ||
344 | if (!view->surface) { | ||
345 | return; | ||
346 | } | ||
347 | if (view->impl->for_each_popup) { | ||
348 | view->impl->for_each_popup(view, iterator, user_data); | ||
349 | } | ||
350 | } | ||
351 | |||
336 | static void view_subsurface_create(struct sway_view *view, | 352 | static void view_subsurface_create(struct sway_view *view, |
337 | struct wlr_subsurface *subsurface); | 353 | struct wlr_subsurface *subsurface); |
338 | 354 | ||
@@ -865,6 +881,8 @@ void view_update_title(struct sway_view *view, bool force) { | |||
865 | 881 | ||
866 | // Update title after the global font height is updated | 882 | // Update title after the global font height is updated |
867 | container_update_title_textures(view->swayc); | 883 | container_update_title_textures(view->swayc); |
884 | |||
885 | ipc_event_window(view->swayc, "title"); | ||
868 | } | 886 | } |
869 | 887 | ||
870 | static bool find_by_mark_iterator(struct sway_container *con, | 888 | static bool find_by_mark_iterator(struct sway_container *con, |
@@ -887,6 +905,7 @@ bool view_find_and_unmark(char *mark) { | |||
887 | free(view_mark); | 905 | free(view_mark); |
888 | list_del(view->marks, i); | 906 | list_del(view->marks, i); |
889 | view_update_marks_textures(view); | 907 | view_update_marks_textures(view); |
908 | ipc_event_window(container, "mark"); | ||
890 | return true; | 909 | return true; |
891 | } | 910 | } |
892 | } | 911 | } |
@@ -894,11 +913,10 @@ bool view_find_and_unmark(char *mark) { | |||
894 | } | 913 | } |
895 | 914 | ||
896 | void view_clear_marks(struct sway_view *view) { | 915 | void view_clear_marks(struct sway_view *view) { |
897 | for (int i = 0; i < view->marks->length; ++i) { | 916 | while (view->marks->length) { |
898 | free(view->marks->items[i]); | 917 | list_del(view->marks, 0); |
918 | ipc_event_window(view->swayc, "mark"); | ||
899 | } | 919 | } |
900 | list_free(view->marks); | ||
901 | view->marks = create_list(); | ||
902 | } | 920 | } |
903 | 921 | ||
904 | bool view_has_mark(struct sway_view *view, char *mark) { | 922 | bool view_has_mark(struct sway_view *view, char *mark) { |
@@ -911,6 +929,11 @@ bool view_has_mark(struct sway_view *view, char *mark) { | |||
911 | return false; | 929 | return false; |
912 | } | 930 | } |
913 | 931 | ||
932 | void view_add_mark(struct sway_view *view, char *mark) { | ||
933 | list_add(view->marks, strdup(mark)); | ||
934 | ipc_event_window(view->swayc, "mark"); | ||
935 | } | ||
936 | |||
914 | static void update_marks_texture(struct sway_view *view, | 937 | static void update_marks_texture(struct sway_view *view, |
915 | struct wlr_texture **texture, struct border_colors *class) { | 938 | struct wlr_texture **texture, struct border_colors *class) { |
916 | struct sway_container *output = container_parent(view->swayc, C_OUTPUT); | 939 | struct sway_container *output = container_parent(view->swayc, C_OUTPUT); |