Move popup unconstraining logic
This commit is contained in:
parent
24cc0719a4
commit
6abedbee48
2 changed files with 48 additions and 59 deletions
|
@ -8,12 +8,15 @@
|
||||||
#include "desktop/popup.h"
|
#include "desktop/popup.h"
|
||||||
|
|
||||||
#include <wlr/types/wlr_layer_shell_v1.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_scene.h>
|
||||||
#include <wlr/types/wlr_xdg_shell.h>
|
#include <wlr/types/wlr_xdg_shell.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
|
|
||||||
|
#include "desktop/desktop.h"
|
||||||
#include "desktop/desktop_surface.h"
|
#include "desktop/desktop_surface.h"
|
||||||
#include "desktop/layer_shell.h"
|
#include "desktop/layer_shell.h"
|
||||||
|
#include "desktop/output.h"
|
||||||
#include "desktop/view.h"
|
#include "desktop/view.h"
|
||||||
|
|
||||||
struct kiwmi_desktop_surface *
|
struct kiwmi_desktop_surface *
|
||||||
|
@ -46,6 +49,49 @@ popup_get_desktop_surface(struct wlr_xdg_popup *popup)
|
||||||
return NULL;
|
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
|
void
|
||||||
popup_attach(
|
popup_attach(
|
||||||
struct wlr_xdg_popup *popup,
|
struct wlr_xdg_popup *popup,
|
||||||
|
@ -61,6 +107,8 @@ popup_attach(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
popup_unconstrain(popup, desktop_surface);
|
||||||
|
|
||||||
struct wlr_scene_node *node =
|
struct wlr_scene_node *node =
|
||||||
wlr_scene_xdg_surface_create(&parent_tree->node, popup->base);
|
wlr_scene_xdg_surface_create(&parent_tree->node, popup->base);
|
||||||
if (!node) {
|
if (!node) {
|
||||||
|
|
|
@ -48,54 +48,6 @@ popup_extension_destroy_notify(struct wl_listener *listener, void *UNUSED(data))
|
||||||
view_child_destroy(popup);
|
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
|
static void
|
||||||
popup_reconfigure(struct kiwmi_view_child *popup)
|
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");
|
wlr_log(WLR_ERROR, "Expected an xdg_popup view_child");
|
||||||
return;
|
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 = {
|
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;
|
child->extension_destroy.notify = popup_extension_destroy_notify;
|
||||||
wl_signal_add(&wlr_popup->base->events.destroy, &child->extension_destroy);
|
wl_signal_add(&wlr_popup->base->events.destroy, &child->extension_destroy);
|
||||||
|
|
||||||
popup_unconstrain(child);
|
|
||||||
|
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue