Adjust xdg-shell view position on first map

This commit is contained in:
Johan Malm 2020-06-01 19:42:15 +01:00
parent 0eb64a29aa
commit 6e0d11bff5
5 changed files with 50 additions and 35 deletions

View file

@ -34,7 +34,7 @@
#define XCURSOR_MOVE "grabbing" #define XCURSOR_MOVE "grabbing"
#define XWL_TITLEBAR_HEIGHT (10) #define XWL_TITLEBAR_HEIGHT (10)
#define XWL_WINDOW_BORDER (3) #define XWL_WINDOW_BORDER (3)
#define LAB_DISABLE_CSD (1) #define LAB_DISABLE_CSD (0)
enum cursor_mode { enum cursor_mode {
LAB_CURSOR_PASSTHROUGH, LAB_CURSOR_PASSTHROUGH,
@ -137,6 +137,7 @@ void xdg_surface_new(struct wl_listener *listener, void *data);
int xwl_nr_parents(struct view *view); int xwl_nr_parents(struct view *view);
void xwl_surface_new(struct wl_listener *listener, void *data); void xwl_surface_new(struct wl_listener *listener, void *data);
void view_init_position(struct view *view);
/** /**
* view_get_surface_geometry - geometry relative to view * view_get_surface_geometry - geometry relative to view
* @view: toplevel containing the surface to process * @view: toplevel containing the surface to process

View file

@ -29,26 +29,28 @@ struct wlr_box deco_box(struct view *view, enum deco_part deco_part)
box.y = view->y - XWL_TITLEBAR_HEIGHT - XWL_WINDOW_BORDER; box.y = view->y - XWL_TITLEBAR_HEIGHT - XWL_WINDOW_BORDER;
box.width = box.width =
view->surface->current.width + 2 * XWL_WINDOW_BORDER; view->surface->current.width + 2 * XWL_WINDOW_BORDER;
box.height = + XWL_WINDOW_BORDER; box.height = XWL_WINDOW_BORDER;
break; break;
case LAB_DECO_PART_RIGHT: case LAB_DECO_PART_RIGHT:
box.x = view->x + view->surface->current.width; box.x = view->x + view->surface->current.width;
box.y = view->y - XWL_TITLEBAR_HEIGHT; box.y = view->y - XWL_TITLEBAR_HEIGHT;
box.width = XWL_WINDOW_BORDER; box.width = XWL_WINDOW_BORDER;
box.height = view->surface->current.height + XWL_TITLEBAR_HEIGHT; box.height =
view->surface->current.height + XWL_TITLEBAR_HEIGHT;
break; break;
case LAB_DECO_PART_BOTTOM: case LAB_DECO_PART_BOTTOM:
box.x = view->x - XWL_WINDOW_BORDER; box.x = view->x - XWL_WINDOW_BORDER;
box.y = view->y + view->surface->current.height; box.y = view->y + view->surface->current.height;
box.width = box.width =
view->surface->current.width + 2 * XWL_WINDOW_BORDER; view->surface->current.width + 2 * XWL_WINDOW_BORDER;
box.height = + XWL_WINDOW_BORDER; box.height = +XWL_WINDOW_BORDER;
break; break;
case LAB_DECO_PART_LEFT: case LAB_DECO_PART_LEFT:
box.x = view->x - XWL_WINDOW_BORDER; box.x = view->x - XWL_WINDOW_BORDER;
box.y = view->y - XWL_TITLEBAR_HEIGHT; box.y = view->y - XWL_TITLEBAR_HEIGHT;
box.width = XWL_WINDOW_BORDER; box.width = XWL_WINDOW_BORDER;
box.height = view->surface->current.height + XWL_TITLEBAR_HEIGHT; box.height =
view->surface->current.height + XWL_TITLEBAR_HEIGHT;
break; break;
default: default:
break; break;

View file

@ -1,5 +1,42 @@
#include "labwc.h" #include "labwc.h"
static bool is_toplevel(struct view *view)
{
switch (view->type) {
case LAB_XDG_SHELL_VIEW:
return view->xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL;
case LAB_XWAYLAND_VIEW:
return xwl_nr_parents(view) > 0 ? false : true;
}
return false;
}
void view_init_position(struct view *view)
{
/* If surface already has a 'desired' position, don't touch it */
if (view->x || view->y)
return;
if (!is_toplevel(view))
return;
struct wlr_box box;
if (view->type == LAB_XDG_SHELL_VIEW && !LAB_DISABLE_CSD) {
/* CSD */
wlr_xdg_surface_get_geometry(view->xdg_surface, &box);
} else if (!view_want_deco(view)) {
return;
} else {
/* SSD */
box = deco_max_extents(view);
}
view->x -= box.x;
view->y -= box.y;
if (view->type != LAB_XWAYLAND_VIEW)
return;
wlr_xwayland_surface_configure(view->xwayland_surface, view->x, view->y,
view->xwayland_surface->width,
view->xwayland_surface->height);
}
struct wlr_box view_get_surface_geometry(struct view *view) struct wlr_box view_get_surface_geometry(struct view *view)
{ {
struct wlr_box box = { 0 }; struct wlr_box box = { 0 };
@ -46,17 +83,7 @@ void view_resize(struct view *view, struct wlr_box geo)
} }
} }
static bool is_toplevel(struct view *view) /* Do we want _server_ side decoration? */
{
switch (view->type) {
case LAB_XDG_SHELL_VIEW:
return view->xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL;
case LAB_XWAYLAND_VIEW:
return xwl_nr_parents(view) > 0 ? false : true;
}
return false;
}
bool view_want_deco(struct view *view) bool view_want_deco(struct view *view)
{ {
if (!is_toplevel(view)) if (!is_toplevel(view))

View file

@ -49,11 +49,12 @@ void xdg_toplevel_decoration(struct wl_listener *listener, void *data)
void xdg_surface_map(struct wl_listener *listener, void *data) void xdg_surface_map(struct wl_listener *listener, void *data)
{ {
/* Called when the surface is mapped, or ready to display on-screen. */
struct view *view = wl_container_of(listener, view, map); struct view *view = wl_container_of(listener, view, map);
view->mapped = true; view->mapped = true;
view->been_mapped = true;
view->surface = view->xdg_surface->surface; view->surface = view->xdg_surface->surface;
if (!view->been_mapped)
view_init_position(view);
view->been_mapped = true;
view_focus(view); view_focus(view);
} }

View file

@ -16,22 +16,6 @@ int xwl_nr_parents(struct view *view)
return i; return i;
} }
static void position(struct view *view)
{
struct wlr_box box;
if (!view_want_deco(view))
return;
if (view->x || view->y)
return;
box = deco_box(view, LAB_DECO_PART_TITLE);
view->y = box.height;
box = deco_box(view, LAB_DECO_PART_LEFT);
view->x = box.width;
wlr_xwayland_surface_configure(view->xwayland_surface, view->x, view->y,
view->xwayland_surface->width,
view->xwayland_surface->height);
}
void xwl_surface_map(struct wl_listener *listener, void *data) void xwl_surface_map(struct wl_listener *listener, void *data)
{ {
struct view *view = wl_container_of(listener, view, map); struct view *view = wl_container_of(listener, view, map);
@ -40,7 +24,7 @@ void xwl_surface_map(struct wl_listener *listener, void *data)
view->y = view->xwayland_surface->y; view->y = view->xwayland_surface->y;
view->surface = view->xwayland_surface->surface; view->surface = view->xwayland_surface->surface;
if (!view->been_mapped) if (!view->been_mapped)
position(view); view_init_position(view);
view->been_mapped = true; view->been_mapped = true;
view_focus(view); view_focus(view);
} }