mirror of
https://github.com/labwc/labwc.git
synced 2025-11-03 09:01:51 -05:00
view: add 'struct border margin'
Simplify various view interfaces as a result
This commit is contained in:
parent
5a77c84fc8
commit
090e78b85a
9 changed files with 91 additions and 101 deletions
|
|
@ -112,6 +112,13 @@ struct view_impl {
|
||||||
void (*unmap)(struct view *view);
|
void (*unmap)(struct view *view);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct border {
|
||||||
|
int top;
|
||||||
|
int right;
|
||||||
|
int bottom;
|
||||||
|
int left;
|
||||||
|
};
|
||||||
|
|
||||||
struct view {
|
struct view {
|
||||||
struct server *server;
|
struct server *server;
|
||||||
enum view_type type;
|
enum view_type type;
|
||||||
|
|
@ -127,7 +134,19 @@ struct view {
|
||||||
bool mapped;
|
bool mapped;
|
||||||
bool been_mapped;
|
bool been_mapped;
|
||||||
bool minimized;
|
bool minimized;
|
||||||
|
|
||||||
|
/* geometry of the wlr_surface contained within the view */
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* margin refers to the space between the extremities of the view and
|
||||||
|
* wlr_surface - typically made up of decoration.
|
||||||
|
* For xdg-shell views, the margin is typically negative.
|
||||||
|
*/
|
||||||
|
struct border margin;
|
||||||
|
|
||||||
|
int xdg_grab_offset;
|
||||||
|
|
||||||
bool show_server_side_deco;
|
bool show_server_side_deco;
|
||||||
|
|
||||||
struct wl_listener map;
|
struct wl_listener map;
|
||||||
|
|
@ -168,8 +187,6 @@ void xwayland_surface_new(struct wl_listener *listener, void *data);
|
||||||
void xwayland_unmanaged_create(struct server *server,
|
void xwayland_unmanaged_create(struct server *server,
|
||||||
struct wlr_xwayland_surface *xsurface);
|
struct wlr_xwayland_surface *xsurface);
|
||||||
|
|
||||||
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
|
||||||
|
|
@ -181,7 +198,6 @@ struct wlr_box view_geometry(struct view *view);
|
||||||
void view_resize(struct view *view, struct wlr_box geo);
|
void view_resize(struct view *view, struct wlr_box geo);
|
||||||
void view_minimize(struct view *view);
|
void view_minimize(struct view *view);
|
||||||
void view_unminimize(struct view *view);
|
void view_unminimize(struct view *view);
|
||||||
bool view_hasfocus(struct view *view);
|
|
||||||
|
|
||||||
void desktop_focus_view(struct view *view);
|
void desktop_focus_view(struct view *view);
|
||||||
|
|
||||||
|
|
@ -218,7 +234,7 @@ void keyboard_new(struct server *server, struct wlr_input_device *device);
|
||||||
void output_frame(struct wl_listener *listener, void *data);
|
void output_frame(struct wl_listener *listener, void *data);
|
||||||
void output_new(struct wl_listener *listener, void *data);
|
void output_new(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
struct wlr_box deco_max_extents(struct view *view);
|
struct border deco_max_extents(struct view *view);
|
||||||
struct wlr_box deco_box(struct view *view, enum deco_part deco_part);
|
struct wlr_box deco_box(struct view *view, enum deco_part deco_part);
|
||||||
enum deco_part deco_at(struct view *view, double lx, double ly);
|
enum deco_part deco_at(struct view *view, double lx, double ly);
|
||||||
|
|
||||||
|
|
|
||||||
16
src/cursor.c
16
src/cursor.c
|
|
@ -30,7 +30,9 @@ static void process_cursor_resize(struct server *server, uint32_t time)
|
||||||
double dy = server->cursor->y - server->grab_y;
|
double dy = server->cursor->y - server->grab_y;
|
||||||
|
|
||||||
struct view *view = server->grabbed_view;
|
struct view *view = server->grabbed_view;
|
||||||
struct wlr_box new_view_geo = view_geometry(view);
|
struct wlr_box new_view_geo = {
|
||||||
|
.x = view->x, .y = view->y, .width = view->w, .height = view->h
|
||||||
|
};
|
||||||
|
|
||||||
if (server->resize_edges & WLR_EDGE_TOP) {
|
if (server->resize_edges & WLR_EDGE_TOP) {
|
||||||
new_view_geo.y = server->grab_box.y + dy;
|
new_view_geo.y = server->grab_box.y + dy;
|
||||||
|
|
@ -53,6 +55,8 @@ static void process_cursor_resize(struct server *server, uint32_t time)
|
||||||
view->y = new_view_geo.y;
|
view->y = new_view_geo.y;
|
||||||
|
|
||||||
/* Resize */
|
/* Resize */
|
||||||
|
new_view_geo.width -= 2 * view->xdg_grab_offset;
|
||||||
|
new_view_geo.height -= 2 * view->xdg_grab_offset;
|
||||||
view_resize(view, new_view_geo);
|
view_resize(view, new_view_geo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,8 +78,8 @@ static void process_cursor_motion(struct server *server, uint32_t time)
|
||||||
struct wlr_surface *surface = NULL;
|
struct wlr_surface *surface = NULL;
|
||||||
int view_area;
|
int view_area;
|
||||||
struct view *view = desktop_view_at(server, server->cursor->x,
|
struct view *view = desktop_view_at(server, server->cursor->x,
|
||||||
server->cursor->y, &surface, &sx, &sy,
|
server->cursor->y, &surface, &sx,
|
||||||
&view_area);
|
&sy, &view_area);
|
||||||
if (!view) {
|
if (!view) {
|
||||||
/* If there's no view under the cursor, set the cursor image to
|
/* If there's no view under the cursor, set the cursor image to
|
||||||
* a default. This is what makes the cursor image appear when
|
* a default. This is what makes the cursor image appear when
|
||||||
|
|
@ -83,6 +87,8 @@ static void process_cursor_motion(struct server *server, uint32_t time)
|
||||||
wlr_xcursor_manager_set_cursor_image(
|
wlr_xcursor_manager_set_cursor_image(
|
||||||
server->cursor_mgr, XCURSOR_DEFAULT, server->cursor);
|
server->cursor_mgr, XCURSOR_DEFAULT, server->cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: Could we use wlr_xcursor_get_resize_name() here?? */
|
||||||
switch (view_area) {
|
switch (view_area) {
|
||||||
case LAB_DECO_PART_TITLE:
|
case LAB_DECO_PART_TITLE:
|
||||||
wlr_xcursor_manager_set_cursor_image(
|
wlr_xcursor_manager_set_cursor_image(
|
||||||
|
|
@ -189,8 +195,8 @@ void cursor_button(struct wl_listener *listener, void *data)
|
||||||
struct wlr_surface *surface;
|
struct wlr_surface *surface;
|
||||||
int view_area;
|
int view_area;
|
||||||
struct view *view = desktop_view_at(server, server->cursor->x,
|
struct view *view = desktop_view_at(server, server->cursor->x,
|
||||||
server->cursor->y, &surface, &sx, &sy,
|
server->cursor->y, &surface, &sx,
|
||||||
&view_area);
|
&sy, &view_area);
|
||||||
if (event->state == WLR_BUTTON_RELEASED) {
|
if (event->state == WLR_BUTTON_RELEASED) {
|
||||||
/* Exit interactive move/resize mode. */
|
/* Exit interactive move/resize mode. */
|
||||||
server->cursor_mode = LAB_CURSOR_PASSTHROUGH;
|
server->cursor_mode = LAB_CURSOR_PASSTHROUGH;
|
||||||
|
|
|
||||||
16
src/deco.c
16
src/deco.c
|
|
@ -10,17 +10,17 @@
|
||||||
#include "common/bug-on.h"
|
#include "common/bug-on.h"
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
|
|
||||||
#define BORDER_WIDTH (1)
|
#define BORDER_WIDTH (2)
|
||||||
|
|
||||||
struct wlr_box deco_max_extents(struct view *view)
|
struct border deco_max_extents(struct view *view)
|
||||||
{
|
{
|
||||||
struct wlr_box box = {
|
struct border border = {
|
||||||
.x = view->x - BORDER_WIDTH,
|
.top = rc.title_height + BORDER_WIDTH,
|
||||||
.y = view->y - rc.title_height - BORDER_WIDTH,
|
.bottom = BORDER_WIDTH,
|
||||||
.width = view->w + 2 * BORDER_WIDTH,
|
.left = BORDER_WIDTH,
|
||||||
.height = view->h + rc.title_height + 2 * BORDER_WIDTH,
|
.right = BORDER_WIDTH,
|
||||||
};
|
};
|
||||||
return box;
|
return border;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_box deco_box(struct view *view, enum deco_part deco_part)
|
struct wlr_box deco_box(struct view *view, enum deco_part deco_part)
|
||||||
|
|
|
||||||
|
|
@ -153,11 +153,8 @@ static bool _view_at(struct view *view, double lx, double ly,
|
||||||
view->xdg_surface, view_sx, view_sy, &_sx, &_sy);
|
view->xdg_surface, view_sx, view_sy, &_sx, &_sy);
|
||||||
break;
|
break;
|
||||||
case LAB_XWAYLAND_VIEW:
|
case LAB_XWAYLAND_VIEW:
|
||||||
if (!view->xwayland_surface->surface)
|
_surface = wlr_surface_surface_at(view->surface, view_sx,
|
||||||
return false;
|
view_sy, &_sx, &_sy);
|
||||||
_surface =
|
|
||||||
wlr_surface_surface_at(view->xwayland_surface->surface,
|
|
||||||
view_sx, view_sy, &_sx, &_sy);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,9 @@ void interactive_begin(struct view *view, enum cursor_mode mode, uint32_t edges)
|
||||||
/* Remember view and cursor positions at start of move/resize */
|
/* Remember view and cursor positions at start of move/resize */
|
||||||
server->grab_x = server->cursor->x;
|
server->grab_x = server->cursor->x;
|
||||||
server->grab_y = server->cursor->y;
|
server->grab_y = server->cursor->y;
|
||||||
server->grab_box = view_geometry(view);
|
struct wlr_box box = {
|
||||||
|
.x = view->x, .y = view->y, .width = view->w, .height = view->h
|
||||||
|
};
|
||||||
|
memcpy(&server->grab_box, &box, sizeof(struct wlr_box));
|
||||||
server->resize_edges = edges;
|
server->resize_edges = edges;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
12
src/output.c
12
src/output.c
|
|
@ -53,14 +53,10 @@ static void render_cycle_box(struct output *output)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
render_it:
|
render_it:
|
||||||
if ((view->type == LAB_XWAYLAND_VIEW) || !rc.client_side_decorations) {
|
box.x = view->x - view->margin.left;
|
||||||
box = deco_max_extents(view);
|
box.y = view->y - view->margin.top;
|
||||||
} else {
|
box.width = view->w + view->margin.left + view->margin.right;
|
||||||
box.x = view->x;
|
box.height = view->h + view->margin.top + view->margin.bottom;
|
||||||
box.y = view->y;
|
|
||||||
box.width = view->w;
|
|
||||||
box.height = view->h;
|
|
||||||
}
|
|
||||||
struct draw_data dd = {
|
struct draw_data dd = {
|
||||||
.renderer = view->server->renderer,
|
.renderer = view->server->renderer,
|
||||||
.transform_matrix = output->wlr_output->transform_matrix,
|
.transform_matrix = output->wlr_output->transform_matrix,
|
||||||
|
|
|
||||||
61
src/view.c
61
src/view.c
|
|
@ -1,70 +1,13 @@
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
#include "common/bug-on.h"
|
#include "common/bug-on.h"
|
||||||
|
|
||||||
void view_init_position(struct view *view)
|
|
||||||
{
|
|
||||||
/* If surface already has a 'desired' position, don't touch it */
|
|
||||||
if (view->x || view->y)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Do not touch xwayland surfaces like menus and apps like dmenu */
|
|
||||||
if (view->type == LAB_XWAYLAND_VIEW && !view->show_server_side_deco)
|
|
||||||
return;
|
|
||||||
|
|
||||||
struct wlr_box box;
|
|
||||||
if (view->type == LAB_XDG_SHELL_VIEW && !view->show_server_side_deco)
|
|
||||||
/*
|
|
||||||
* We're here either because rc.xml says yes to CSD or
|
|
||||||
* because the XDG shell won't allow CSD to be turned off
|
|
||||||
*/
|
|
||||||
wlr_xdg_surface_get_geometry(view->xdg_surface, &box);
|
|
||||||
else
|
|
||||||
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 box = { 0 };
|
|
||||||
switch (view->type) {
|
|
||||||
case LAB_XDG_SHELL_VIEW:
|
|
||||||
wlr_xdg_surface_get_geometry(view->xdg_surface, &box);
|
|
||||||
break;
|
|
||||||
case LAB_XWAYLAND_VIEW:
|
|
||||||
box.width = view->w;
|
|
||||||
box.height = view->h;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return box;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get geometry relative to screen */
|
|
||||||
struct wlr_box view_geometry(struct view *view)
|
|
||||||
{
|
|
||||||
struct wlr_box b = view_get_surface_geometry(view);
|
|
||||||
/* Add XDG view invisible border if it exists */
|
|
||||||
b.width += 2 * b.x;
|
|
||||||
b.height += 2 * b.y;
|
|
||||||
/* Make co-ordinates relative to screen */
|
|
||||||
b.x = view->x;
|
|
||||||
b.y = view->y;
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
void view_resize(struct view *view, struct wlr_box geo)
|
void view_resize(struct view *view, struct wlr_box geo)
|
||||||
{
|
{
|
||||||
struct wlr_box border = view_get_surface_geometry(view);
|
|
||||||
struct wlr_box box = {
|
struct wlr_box box = {
|
||||||
.x = view->x,
|
.x = view->x,
|
||||||
.y = view->y,
|
.y = view->y,
|
||||||
.width = geo.width - 2 * border.x,
|
.width = geo.width,
|
||||||
.height = geo.height - 2 * border.y,
|
.height = geo.height,
|
||||||
};
|
};
|
||||||
view->impl->configure(view, box);
|
view->impl->configure(view, box);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
25
src/xdg.c
25
src/xdg.c
|
|
@ -129,18 +129,41 @@ static void xdg_toplevel_view_close(struct view *view)
|
||||||
wlr_xdg_toplevel_send_close(view->xdg_surface);
|
wlr_xdg_toplevel_send_close(view->xdg_surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct border xdg_shell_border(struct view *view)
|
||||||
|
{
|
||||||
|
struct wlr_box box;
|
||||||
|
wlr_xdg_surface_get_geometry(view->xdg_surface, &box);
|
||||||
|
struct border border = {
|
||||||
|
.top = -box.y,
|
||||||
|
.bottom = -box.y,
|
||||||
|
.left = -box.x,
|
||||||
|
.right = -box.x,
|
||||||
|
};
|
||||||
|
return border;
|
||||||
|
}
|
||||||
|
|
||||||
static void xdg_toplevel_view_map(struct view *view)
|
static void xdg_toplevel_view_map(struct view *view)
|
||||||
{
|
{
|
||||||
view->mapped = true;
|
view->mapped = true;
|
||||||
view->surface = view->xdg_surface->surface;
|
view->surface = view->xdg_surface->surface;
|
||||||
if (!view->been_mapped) {
|
if (!view->been_mapped) {
|
||||||
view->show_server_side_deco = has_ssd(view);
|
view->show_server_side_deco = has_ssd(view);
|
||||||
view_init_position(view);
|
if (view->show_server_side_deco) {
|
||||||
|
view->margin = deco_max_extents(view);
|
||||||
|
} else {
|
||||||
|
view->margin = xdg_shell_border(view);
|
||||||
|
view->xdg_grab_offset = -view->margin.left;
|
||||||
|
}
|
||||||
|
/* align to edge of screen */
|
||||||
|
view->x += view->margin.left;
|
||||||
|
view->y += view->margin.top;
|
||||||
}
|
}
|
||||||
view->been_mapped = true;
|
view->been_mapped = true;
|
||||||
|
|
||||||
wl_signal_add(&view->xdg_surface->surface->events.commit,
|
wl_signal_add(&view->xdg_surface->surface->events.commit,
|
||||||
&view->commit);
|
&view->commit);
|
||||||
view->commit.notify = handle_commit;
|
view->commit.notify = handle_commit;
|
||||||
|
|
||||||
desktop_focus_view(view);
|
desktop_focus_view(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,12 +55,10 @@ static void _close(struct view *view)
|
||||||
wlr_xwayland_surface_close(view->xwayland_surface);
|
wlr_xwayland_surface_close(view->xwayland_surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool want_ssd(struct view *view)
|
static bool want_deco(struct view *view)
|
||||||
{
|
{
|
||||||
if (view->xwayland_surface->decorations !=
|
return view->xwayland_surface->decorations ==
|
||||||
WLR_XWAYLAND_SURFACE_DECORATIONS_ALL)
|
WLR_XWAYLAND_SURFACE_DECORATIONS_ALL;
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void map(struct view *view)
|
static void map(struct view *view)
|
||||||
|
|
@ -68,12 +66,20 @@ static void map(struct view *view)
|
||||||
view->mapped = true;
|
view->mapped = true;
|
||||||
view->x = view->xwayland_surface->x;
|
view->x = view->xwayland_surface->x;
|
||||||
view->y = view->xwayland_surface->y;
|
view->y = view->xwayland_surface->y;
|
||||||
|
view->w = view->xwayland_surface->width;
|
||||||
|
view->h = view->xwayland_surface->height;
|
||||||
view->surface = view->xwayland_surface->surface;
|
view->surface = view->xwayland_surface->surface;
|
||||||
if (!view->been_mapped) {
|
view->show_server_side_deco = want_deco(view);
|
||||||
view->show_server_side_deco = want_ssd(view);
|
|
||||||
view_init_position(view);
|
view->margin = deco_max_extents(view);
|
||||||
}
|
|
||||||
view->been_mapped = true;
|
/* ensure we're inside screen */
|
||||||
|
view->x += view->margin.left;
|
||||||
|
view->y += view->margin.top;
|
||||||
|
struct wlr_box box = {
|
||||||
|
.x = view->x, .y = view->y, .width = view->w, .height = view->h
|
||||||
|
};
|
||||||
|
view->impl->configure(view, box);
|
||||||
|
|
||||||
/* Add commit here, as xwayland map/unmap can change the wlr_surface */
|
/* Add commit here, as xwayland map/unmap can change the wlr_surface */
|
||||||
wl_signal_add(&view->xwayland_surface->surface->events.commit,
|
wl_signal_add(&view->xwayland_surface->surface->events.commit,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue