diff options
author | Ryan Dwyer <RyanDwyer@users.noreply.github.com> | 2018-07-13 08:17:45 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-13 08:17:45 +1000 |
commit | 53133fdefb1cdd97d21b3d5424868b70642d46dc (patch) | |
tree | 21c8d74ed97be81ed731f92443a4cd726ee8ac4b | |
parent | 9b16227ec3cfc648f177f186d29b9f0002b7bbde (diff) | |
parent | da8149c066c8bd3fe662337159081600a93950f7 (diff) |
Merge branch 'master' into xwayland-floating-borders
-rw-r--r-- | sway/config.c | 12 | ||||
-rw-r--r-- | sway/desktop/xdg_shell.c | 50 | ||||
-rw-r--r-- | sway/desktop/xdg_shell_v6.c | 50 |
3 files changed, 106 insertions, 6 deletions
diff --git a/sway/config.c b/sway/config.c index c59f4f0d..d2386f46 100644 --- a/sway/config.c +++ b/sway/config.c @@ -560,7 +560,7 @@ static char *expand_line(const char *block, const char *line, bool add_brace) { bool read_config(FILE *file, struct sway_config *config) { bool reading_main_config = false; - char *current_config, *config_pos; + char *this_config = NULL, *config_pos; long config_size = 0; if (config->current_config == NULL) { reading_main_config = true; @@ -569,8 +569,8 @@ bool read_config(FILE *file, struct sway_config *config) { config_size = ftell(file); rewind(file); - config_pos = current_config = malloc(config_size + 1); - if (current_config == NULL) { + config_pos = this_config = malloc(config_size + 1); + if (this_config == NULL) { wlr_log(WLR_ERROR, "Unable to allocate buffer for config contents"); return false; } @@ -616,7 +616,7 @@ bool read_config(FILE *file, struct sway_config *config) { list_foreach(stack, free); list_free(stack); free(line); - free(current_config); + free(this_config); return false; } wlr_log(WLR_DEBUG, "Expanded line: %s", expanded); @@ -678,8 +678,8 @@ bool read_config(FILE *file, struct sway_config *config) { list_free(stack); if (reading_main_config) { - current_config[config_size - 1] = '\0'; - config->current_config = current_config; + this_config[config_size - 1] = '\0'; + config->current_config = this_config; } return success; } diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index be14adbe..17b7b750 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -45,6 +45,53 @@ static void popup_handle_destroy(struct wl_listener *listener, void *data) { view_child_destroy(&popup->child); } +static void popup_unconstrain(struct sway_xdg_popup *popup) { + // get the output of the popup's positioner anchor point and convert it to + // the toplevel parent's coordinate system and then pass it to + // wlr_xdg_popup_unconstrain_from_box + + struct sway_view *view = popup->child.view; + struct wlr_output_layout *output_layout = + root_container.sway_root->output_layout; + struct wlr_xdg_popup *wlr_popup = popup->wlr_xdg_surface->popup; + + int anchor_lx, anchor_ly; + wlr_xdg_popup_get_anchor_point(wlr_popup, &anchor_lx, &anchor_ly); + + int popup_lx, popup_ly; + wlr_xdg_popup_get_toplevel_coords(wlr_popup, wlr_popup->geometry.x, + wlr_popup->geometry.y, &popup_lx, &popup_ly); + popup_lx += view->x; + popup_ly += view->y; + + anchor_lx += popup_lx; + anchor_ly += popup_ly; + + double dest_x = 0, dest_y = 0; + wlr_output_layout_closest_point(output_layout, NULL, anchor_lx, anchor_ly, + &dest_x, &dest_y); + + struct wlr_output *output = + wlr_output_layout_output_at(output_layout, dest_x, dest_y); + if (output == NULL) { + return; + } + + int width = 0, height = 0; + wlr_output_effective_resolution(output, &width, &height); + + // the output box expressed in the coordinate system of the toplevel parent + // of the popup + struct wlr_box output_toplevel_sx_box = { + .x = output->lx - view->x, + .y = output->ly - view->y, + .width = width, + .height = height + }; + + wlr_xdg_popup_unconstrain_from_box(wlr_popup, &output_toplevel_sx_box); +} + static struct sway_xdg_popup *popup_create( struct wlr_xdg_popup *wlr_popup, struct sway_view *view) { struct wlr_xdg_surface *xdg_surface = wlr_popup->base; @@ -55,12 +102,15 @@ static struct sway_xdg_popup *popup_create( return NULL; } view_child_init(&popup->child, &popup_impl, view, xdg_surface->surface); + popup->wlr_xdg_surface = xdg_surface; wl_signal_add(&xdg_surface->events.new_popup, &popup->new_popup); popup->new_popup.notify = popup_handle_new_popup; wl_signal_add(&xdg_surface->events.destroy, &popup->destroy); popup->destroy.notify = popup_handle_destroy; + popup_unconstrain(popup); + return popup; } diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index f5cf085a..43e58918 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -44,6 +44,53 @@ static void popup_handle_destroy(struct wl_listener *listener, void *data) { view_child_destroy(&popup->child); } +static void popup_unconstrain(struct sway_xdg_popup_v6 *popup) { + // get the output of the popup's positioner anchor point and convert it to + // the toplevel parent's coordinate system and then pass it to + // wlr_xdg_popup_unconstrain_from_box + + struct sway_view *view = popup->child.view; + struct wlr_output_layout *output_layout = + root_container.sway_root->output_layout; + struct wlr_xdg_popup_v6 *wlr_popup = popup->wlr_xdg_surface_v6->popup; + + int anchor_lx, anchor_ly; + wlr_xdg_popup_v6_get_anchor_point(wlr_popup, &anchor_lx, &anchor_ly); + + int popup_lx, popup_ly; + wlr_xdg_popup_v6_get_toplevel_coords(wlr_popup, wlr_popup->geometry.x, + wlr_popup->geometry.y, &popup_lx, &popup_ly); + popup_lx += view->x; + popup_ly += view->y; + + anchor_lx += popup_lx; + anchor_ly += popup_ly; + + double dest_x = 0, dest_y = 0; + wlr_output_layout_closest_point(output_layout, NULL, anchor_lx, anchor_ly, + &dest_x, &dest_y); + + struct wlr_output *output = + wlr_output_layout_output_at(output_layout, dest_x, dest_y); + if (output == NULL) { + return; + } + + int width = 0, height = 0; + wlr_output_effective_resolution(output, &width, &height); + + // the output box expressed in the coordinate system of the toplevel parent + // of the popup + struct wlr_box output_toplevel_sx_box = { + .x = output->lx - view->x, + .y = output->ly - view->y, + .width = width, + .height = height + }; + + wlr_xdg_popup_v6_unconstrain_from_box(wlr_popup, &output_toplevel_sx_box); +} + static struct sway_xdg_popup_v6 *popup_create( struct wlr_xdg_popup_v6 *wlr_popup, struct sway_view *view) { struct wlr_xdg_surface_v6 *xdg_surface = wlr_popup->base; @@ -54,12 +101,15 @@ static struct sway_xdg_popup_v6 *popup_create( return NULL; } view_child_init(&popup->child, &popup_impl, view, xdg_surface->surface); + popup->wlr_xdg_surface_v6 = xdg_surface; wl_signal_add(&xdg_surface->events.new_popup, &popup->new_popup); popup->new_popup.notify = popup_handle_new_popup; wl_signal_add(&xdg_surface->events.destroy, &popup->destroy); popup->destroy.notify = popup_handle_destroy; + popup_unconstrain(popup); + return popup; } |