Move popup unconstraining logic

This commit is contained in:
tiosgz 2022-05-08 09:48:44 +00:00
parent 24cc0719a4
commit 6abedbee48
2 changed files with 48 additions and 59 deletions

View file

@ -8,12 +8,15 @@
#include "desktop/popup.h"
#include <wlr/types/wlr_layer_shell_v1.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_scene.h>
#include <wlr/types/wlr_xdg_shell.h>
#include <wlr/util/log.h>
#include "desktop/desktop.h"
#include "desktop/desktop_surface.h"
#include "desktop/layer_shell.h"
#include "desktop/output.h"
#include "desktop/view.h"
struct kiwmi_desktop_surface *
@ -46,6 +49,49 @@ popup_get_desktop_surface(struct wlr_xdg_popup *popup)
return NULL;
}
static void
popup_unconstrain(
struct wlr_xdg_popup *popup,
struct kiwmi_desktop_surface *desktop_surface)
{
struct kiwmi_output *output = desktop_surface_get_output(desktop_surface);
if (!output) {
return;
}
struct wlr_output *wlr_output = output->wlr_output;
int lx, ly;
desktop_surface_get_pos(desktop_surface, &lx, &ly);
if (desktop_surface->type == KIWMI_DESKTOP_SURFACE_VIEW) {
// wlroots expects surface-local, not view-local coords
struct kiwmi_view *view =
wl_container_of(desktop_surface, view, desktop_surface);
lx -= view->geom.x;
ly -= view->geom.y;
}
double ox = lx;
double oy = ly;
wlr_output_layout_output_coords(
output->desktop->output_layout, wlr_output, &ox, &oy);
int output_width;
int output_height;
wlr_output_effective_resolution(wlr_output, &output_width, &output_height);
// Relative to the desktop_surface
struct wlr_box output_box = {
.x = -ox,
.y = -oy,
.width = output_width,
.height = output_height,
};
wlr_xdg_popup_unconstrain_from_box(popup, &output_box);
}
void
popup_attach(
struct wlr_xdg_popup *popup,
@ -61,6 +107,8 @@ popup_attach(
}
}
popup_unconstrain(popup, desktop_surface);
struct wlr_scene_node *node =
wlr_scene_xdg_surface_create(&parent_tree->node, popup->base);
if (!node) {

View file

@ -48,54 +48,6 @@ popup_extension_destroy_notify(struct wl_listener *listener, void *UNUSED(data))
view_child_destroy(popup);
}
static void
popup_unconstrain(struct kiwmi_view_child *popup)
{
if (popup->type != KIWMI_VIEW_CHILD_XDG_POPUP) {
wlr_log(WLR_ERROR, "Expected an xdg_popup kiwmi_view_child");
return;
}
struct kiwmi_view *view = popup->view;
// Prefer output at view center
struct wlr_output *output = wlr_output_layout_output_at(
view->desktop->output_layout,
view->x + view->geom.width / 2,
view->y + view->geom.height / 2);
if (!output) {
// Retry with view top-left corner (if its center is off-screen)
output = wlr_output_layout_output_at(
view->desktop->output_layout, view->x, view->y);
}
if (!output) {
wlr_log(
WLR_ERROR, "View's output not found, popups may end up invisible");
return;
}
double view_ox = view->x;
double view_oy = view->y;
wlr_output_layout_output_coords(
view->desktop->output_layout, output, &view_ox, &view_oy);
int output_width;
int output_height;
wlr_output_effective_resolution(output, &output_width, &output_height);
// relative to the view
struct wlr_box output_box = {
.x = -view_ox,
.y = -view_oy,
.width = output_width,
.height = output_height,
};
wlr_xdg_popup_unconstrain_from_box(popup->wlr_xdg_popup, &output_box);
}
static void
popup_reconfigure(struct kiwmi_view_child *popup)
{
@ -103,15 +55,6 @@ popup_reconfigure(struct kiwmi_view_child *popup)
wlr_log(WLR_ERROR, "Expected an xdg_popup view_child");
return;
}
popup_unconstrain(popup);
struct kiwmi_view_child *subchild;
wl_list_for_each (subchild, &popup->children, link) {
if (subchild->impl && subchild->impl->reconfigure) {
subchild->impl->reconfigure(subchild);
}
}
}
static const struct kiwmi_view_child_impl xdg_popup_view_child_impl = {
@ -146,8 +89,6 @@ view_child_popup_create(
child->extension_destroy.notify = popup_extension_destroy_notify;
wl_signal_add(&wlr_popup->base->events.destroy, &child->extension_destroy);
popup_unconstrain(child);
return child;
}