mirror of
https://github.com/labwc/labwc.git
synced 2025-10-29 05:40:24 -04:00
Support xwayland view resize (LAB_DECO_PART_LEFT)
This commit is contained in:
parent
9a0c2b8417
commit
e716a92c00
7 changed files with 118 additions and 49 deletions
|
|
@ -145,6 +145,7 @@ Cpp11BracedListStyle: false
|
||||||
ForEachMacros:
|
ForEachMacros:
|
||||||
- 'wl_list_for_each'
|
- 'wl_list_for_each'
|
||||||
- 'wl_list_for_each_reverse'
|
- 'wl_list_for_each_reverse'
|
||||||
|
- 'wl_list_for_each_safe'
|
||||||
|
|
||||||
# The maximum number of consecutive empty lines to keep.
|
# The maximum number of consecutive empty lines to keep.
|
||||||
MaxEmptyLinesToKeep: 1
|
MaxEmptyLinesToKeep: 1
|
||||||
|
|
|
||||||
10
deco.c
10
deco.c
|
|
@ -39,9 +39,11 @@ 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)
|
||||||
{
|
{
|
||||||
struct wlr_box box;
|
enum deco_part deco_part;
|
||||||
box = deco_box(view, LAB_DECO_PART_TOP);
|
for (deco_part = 0; deco_part < LAB_DECO_NONE; ++deco_part) {
|
||||||
if (wlr_box_contains_point(&box, lx, ly))
|
struct wlr_box box = deco_box(view, deco_part);
|
||||||
return LAB_DECO_PART_TOP;
|
if (wlr_box_contains_point(&box, lx, ly))
|
||||||
|
return deco_part;
|
||||||
|
}
|
||||||
return LAB_DECO_NONE;
|
return LAB_DECO_NONE;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
8
labwc.h
8
labwc.h
|
|
@ -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 {
|
||||||
TINYWL_CURSOR_PASSTHROUGH,
|
TINYWL_CURSOR_PASSTHROUGH,
|
||||||
|
|
@ -79,6 +79,9 @@ struct server {
|
||||||
struct wlr_output_layout *output_layout;
|
struct wlr_output_layout *output_layout;
|
||||||
struct wl_list outputs;
|
struct wl_list outputs;
|
||||||
struct wl_listener new_output;
|
struct wl_listener new_output;
|
||||||
|
|
||||||
|
/* For use in cycle (alt-tab) mode */
|
||||||
|
struct view *cycle_view;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct output {
|
struct output {
|
||||||
|
|
@ -90,7 +93,8 @@ struct output {
|
||||||
|
|
||||||
enum view_type { LAB_XDG_SHELL_VIEW, LAB_XWAYLAND_VIEW };
|
enum view_type { LAB_XDG_SHELL_VIEW, LAB_XWAYLAND_VIEW };
|
||||||
|
|
||||||
enum deco_part { LAB_DECO_NONE, LAB_DECO_PART_TOP, LAB_DECO_PART_LEFT };
|
/* Keep LAB_DECO_NONE last for the purpose of iterating */
|
||||||
|
enum deco_part { LAB_DECO_PART_TOP = 0, LAB_DECO_PART_LEFT, LAB_DECO_NONE };
|
||||||
|
|
||||||
struct view {
|
struct view {
|
||||||
enum view_type type;
|
enum view_type type;
|
||||||
|
|
|
||||||
12
main.c
12
main.c
|
|
@ -134,8 +134,8 @@ int main(int argc, char *argv[])
|
||||||
wlr_cursor_attach_output_layout(server.cursor, server.output_layout);
|
wlr_cursor_attach_output_layout(server.cursor, server.output_layout);
|
||||||
|
|
||||||
// This is done below
|
// This is done below
|
||||||
//server.cursor_mgr = wlr_xcursor_manager_create(NULL, XCURSOR_SIZE);
|
// server.cursor_mgr = wlr_xcursor_manager_create(NULL, XCURSOR_SIZE);
|
||||||
//if (!server.cursor_mgr) {
|
// if (!server.cursor_mgr) {
|
||||||
// wlr_log(WLR_ERROR, "cannot create xcursor manager");
|
// wlr_log(WLR_ERROR, "cannot create xcursor manager");
|
||||||
// return 1;
|
// return 1;
|
||||||
//}
|
//}
|
||||||
|
|
@ -279,10 +279,10 @@ int main(int argc, char *argv[])
|
||||||
wl_list_remove(&_output->link);
|
wl_list_remove(&_output->link);
|
||||||
free(_output);
|
free(_output);
|
||||||
}
|
}
|
||||||
struct output *_keyboard, *_keyboard_tmp;
|
struct output *k, *k_tmp;
|
||||||
wl_list_for_each_safe (_keyboard, _keyboard_tmp, &server.keyboards, link) {
|
wl_list_for_each_safe (k, k_tmp, &server.keyboards, link) {
|
||||||
wl_list_remove(&_keyboard->link);
|
wl_list_remove(&k->link);
|
||||||
free(_keyboard);
|
free(k);
|
||||||
}
|
}
|
||||||
wlr_cursor_destroy(server.cursor);
|
wlr_cursor_destroy(server.cursor);
|
||||||
wlr_output_layout_destroy(server.output_layout);
|
wlr_output_layout_destroy(server.output_layout);
|
||||||
|
|
|
||||||
45
output.c
45
output.c
|
|
@ -7,6 +7,47 @@ struct render_data {
|
||||||
struct timespec *when;
|
struct timespec *when;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void render_grab(struct output *output)
|
||||||
|
{
|
||||||
|
if (output->server->cursor_mode == TINYWL_CURSOR_PASSTHROUGH)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (output->server->cursor_mode == TINYWL_CURSOR_RESIZE) {
|
||||||
|
float grab_box_color[] = { 0.0, 1.0, 0.0, 0.3 };
|
||||||
|
wlr_render_rect(output->server->renderer,
|
||||||
|
&output->server->grab_box, grab_box_color,
|
||||||
|
output->wlr_output->transform_matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
float grab_point_color[] = { 1.0, 0.0, 1.0, 1.0 };
|
||||||
|
struct wlr_box point = { .x = output->server->grab_x +
|
||||||
|
output->server->grabbed_view->x - 1,
|
||||||
|
.y = output->server->grab_y +
|
||||||
|
output->server->grabbed_view->y - 1,
|
||||||
|
.width = 3,
|
||||||
|
.height = 3 };
|
||||||
|
fprintf(stderr, "XX grab_x=%f; grab_y=%f\n", output->server->grab_x,
|
||||||
|
output->server->grab_y);
|
||||||
|
wlr_render_rect(output->server->renderer, &point, grab_point_color,
|
||||||
|
output->wlr_output->transform_matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void render_cycle_box(struct output *output)
|
||||||
|
{
|
||||||
|
if (!output->server->cycle_view)
|
||||||
|
return;
|
||||||
|
struct view *view;
|
||||||
|
wl_list_for_each_reverse (view, &output->server->views, link) {
|
||||||
|
if (view != output->server->cycle_view)
|
||||||
|
continue;
|
||||||
|
struct wlr_box box = deco_max_extents(view);
|
||||||
|
float cycle_color[] = { 0.0, 0.0, 0.0, 0.2 };
|
||||||
|
wlr_render_rect(output->server->renderer, &box, cycle_color,
|
||||||
|
output->wlr_output->transform_matrix);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void render_decorations(struct wlr_output *output, struct view *view)
|
static void render_decorations(struct wlr_output *output, struct view *view)
|
||||||
{
|
{
|
||||||
if (!view_want_deco(view))
|
if (!view_want_deco(view))
|
||||||
|
|
@ -144,6 +185,10 @@ void output_frame(struct wl_listener *listener, void *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If in cycle (alt-tab) mode, highlight selected view */
|
||||||
|
render_cycle_box(output);
|
||||||
|
render_grab(output);
|
||||||
|
|
||||||
/* Hardware cursors are rendered by the GPU on a separate plane, and can
|
/* Hardware cursors are rendered by the GPU on a separate plane, and can
|
||||||
* be moved around without re-rendering what's beneath them - which is
|
* be moved around without re-rendering what's beneath them - which is
|
||||||
* more efficient. However, not all hardware supports hardware cursors.
|
* more efficient. However, not all hardware supports hardware cursors.
|
||||||
|
|
|
||||||
87
server.c
87
server.c
|
|
@ -1,10 +1,21 @@
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
|
|
||||||
static bool in_alt_tab_mode;
|
static struct wlr_box view_geometry(struct view *view)
|
||||||
static struct view *alt_tab_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->xwayland_surface->width;
|
||||||
|
box.height = view->xwayland_surface->height;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return box;
|
||||||
|
}
|
||||||
|
|
||||||
void begin_interactive(struct view *view, enum cursor_mode mode,
|
void begin_interactive(struct view *view, enum cursor_mode mode, uint32_t edges)
|
||||||
uint32_t edges)
|
|
||||||
{
|
{
|
||||||
/* This function sets up an interactive move or resize operation, where
|
/* This function sets up an interactive move or resize operation, where
|
||||||
* the compositor stops propegating pointer events to clients and
|
* the compositor stops propegating pointer events to clients and
|
||||||
|
|
@ -13,24 +24,13 @@ void begin_interactive(struct view *view, enum cursor_mode mode,
|
||||||
server->grabbed_view = view;
|
server->grabbed_view = view;
|
||||||
server->cursor_mode = mode;
|
server->cursor_mode = mode;
|
||||||
|
|
||||||
if (mode == TINYWL_CURSOR_MOVE) {
|
switch (mode) {
|
||||||
|
case TINYWL_CURSOR_MOVE:
|
||||||
server->grab_x = server->cursor->x - view->x;
|
server->grab_x = server->cursor->x - view->x;
|
||||||
server->grab_y = server->cursor->y - view->y;
|
server->grab_y = server->cursor->y - view->y;
|
||||||
} else {
|
break;
|
||||||
struct wlr_box geo_box;
|
case TINYWL_CURSOR_RESIZE: {
|
||||||
switch (view->type) {
|
struct wlr_box geo_box = view_geometry(view);
|
||||||
case LAB_XDG_SHELL_VIEW:
|
|
||||||
wlr_xdg_surface_get_geometry(view->xdg_surface,
|
|
||||||
&geo_box);
|
|
||||||
break;
|
|
||||||
case LAB_XWAYLAND_VIEW:
|
|
||||||
geo_box.x = view->xwayland_surface->x;
|
|
||||||
geo_box.y = view->xwayland_surface->y;
|
|
||||||
geo_box.width = view->xwayland_surface->width;
|
|
||||||
geo_box.height = view->xwayland_surface->height;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
double border_x =
|
double border_x =
|
||||||
(view->x + geo_box.x) +
|
(view->x + geo_box.x) +
|
||||||
((edges & WLR_EDGE_RIGHT) ? geo_box.width : 0);
|
((edges & WLR_EDGE_RIGHT) ? geo_box.width : 0);
|
||||||
|
|
@ -43,6 +43,9 @@ void begin_interactive(struct view *view, enum cursor_mode mode,
|
||||||
server->grab_box.x += view->x;
|
server->grab_box.x += view->x;
|
||||||
server->grab_box.y += view->y;
|
server->grab_box.y += view->y;
|
||||||
server->resize_edges = edges;
|
server->resize_edges = edges;
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,9 +82,8 @@ static bool handle_keybinding(struct server *server, xkb_keysym_t sym)
|
||||||
break;
|
break;
|
||||||
case XKB_KEY_F1:
|
case XKB_KEY_F1:
|
||||||
case XKB_KEY_F2:
|
case XKB_KEY_F2:
|
||||||
in_alt_tab_mode = true;
|
server->cycle_view = next_toplevel(view_front_toplevel(server));
|
||||||
alt_tab_view = next_toplevel(view_front_toplevel(server));
|
fprintf(stderr, "cycle_view=%p\n", (void *)server->cycle_view);
|
||||||
fprintf(stderr, "alt_tab_view=%p\n", (void *)alt_tab_view);
|
|
||||||
break;
|
break;
|
||||||
case XKB_KEY_F3:
|
case XKB_KEY_F3:
|
||||||
if (fork() == 0) {
|
if (fork() == 0) {
|
||||||
|
|
@ -120,17 +122,17 @@ static void keyboard_handle_key(struct wl_listener *listener, void *data)
|
||||||
uint32_t modifiers =
|
uint32_t modifiers =
|
||||||
wlr_keyboard_get_modifiers(keyboard->device->keyboard);
|
wlr_keyboard_get_modifiers(keyboard->device->keyboard);
|
||||||
|
|
||||||
if (in_alt_tab_mode) {
|
if (server->cycle_view) {
|
||||||
if ((syms[0] == XKB_KEY_Alt_L) &&
|
if ((syms[0] == XKB_KEY_Alt_L) &&
|
||||||
event->state == WLR_KEY_RELEASED) {
|
event->state == WLR_KEY_RELEASED) {
|
||||||
/* end cycle */
|
/* end cycle */
|
||||||
in_alt_tab_mode = false;
|
view_focus(server->cycle_view);
|
||||||
view_focus(alt_tab_view);
|
server->cycle_view = NULL;
|
||||||
} else if (event->state == WLR_KEY_PRESSED) {
|
} else if (event->state == WLR_KEY_PRESSED) {
|
||||||
/* cycle to next */
|
/* cycle to next */
|
||||||
alt_tab_view = next_toplevel(alt_tab_view);
|
server->cycle_view = next_toplevel(server->cycle_view);
|
||||||
fprintf(stderr, "alt_tab_view=%p\n",
|
fprintf(stderr, "cycle_view=%p\n",
|
||||||
(void *)alt_tab_view);
|
(void *)server->cycle_view);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -268,11 +270,6 @@ static void process_cursor_move(struct server *server, uint32_t time)
|
||||||
static void process_cursor_resize(struct server *server, uint32_t time)
|
static void process_cursor_resize(struct server *server, uint32_t time)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Resizing the grabbed view can be a little bit complicated, because we
|
|
||||||
* could be resizing from any corner or edge. This not only resizes the
|
|
||||||
* view on one or two axes, but can also move the view if you resize
|
|
||||||
* from the top or left edges (or top-left corner).
|
|
||||||
*
|
|
||||||
* TODO: Wait for the client to prepare a buffer at the new size, then
|
* TODO: Wait for the client to prepare a buffer at the new size, then
|
||||||
* commit any movement that was prepared.
|
* commit any movement that was prepared.
|
||||||
*/
|
*/
|
||||||
|
|
@ -303,14 +300,22 @@ static void process_cursor_resize(struct server *server, uint32_t time)
|
||||||
new_right = new_left + 1;
|
new_right = new_left + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_box geo_box;
|
struct wlr_box geo_box = view_geometry(view);
|
||||||
wlr_xdg_surface_get_geometry(view->xdg_surface, &geo_box);
|
|
||||||
view->x = new_left - geo_box.x;
|
view->x = new_left - geo_box.x;
|
||||||
view->y = new_top - geo_box.y;
|
view->y = new_top - geo_box.y;
|
||||||
|
|
||||||
int new_width = new_right - new_left;
|
int new_width = new_right - new_left;
|
||||||
int new_height = new_bottom - new_top;
|
int new_height = new_bottom - new_top;
|
||||||
wlr_xdg_toplevel_set_size(view->xdg_surface, new_width, new_height);
|
switch (view->type) {
|
||||||
|
case LAB_XDG_SHELL_VIEW:
|
||||||
|
wlr_xdg_toplevel_set_size(view->xdg_surface, new_width,
|
||||||
|
new_height);
|
||||||
|
break;
|
||||||
|
case LAB_XWAYLAND_VIEW:
|
||||||
|
wlr_xwayland_surface_configure(view->xwayland_surface, view->x,
|
||||||
|
view->y, new_width, new_height);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_cursor_motion(struct server *server, uint32_t time)
|
static void process_cursor_motion(struct server *server, uint32_t time)
|
||||||
|
|
@ -345,6 +350,10 @@ 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, "left_ptr", server->cursor);
|
server->cursor_mgr, "left_ptr", server->cursor);
|
||||||
break;
|
break;
|
||||||
|
case LAB_DECO_PART_LEFT:
|
||||||
|
wlr_xcursor_manager_set_cursor_image(
|
||||||
|
server->cursor_mgr, "left_side", server->cursor);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (surface) {
|
if (surface) {
|
||||||
bool focus_changed = seat->pointer_state.focused_surface !=
|
bool focus_changed = seat->pointer_state.focused_surface !=
|
||||||
|
|
@ -431,6 +440,10 @@ void server_cursor_button(struct wl_listener *listener, void *data)
|
||||||
case LAB_DECO_PART_TOP:
|
case LAB_DECO_PART_TOP:
|
||||||
begin_interactive(view, TINYWL_CURSOR_MOVE, 0);
|
begin_interactive(view, TINYWL_CURSOR_MOVE, 0);
|
||||||
break;
|
break;
|
||||||
|
case LAB_DECO_PART_LEFT:
|
||||||
|
begin_interactive(view, TINYWL_CURSOR_RESIZE,
|
||||||
|
WLR_EDGE_LEFT);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
4
view.c
4
view.c
|
|
@ -165,6 +165,10 @@ struct view *view_at(struct server *server, double lx, double ly,
|
||||||
*view_area = LAB_DECO_PART_TOP;
|
*view_area = LAB_DECO_PART_TOP;
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
if (deco_at(view, lx, ly) == LAB_DECO_PART_LEFT) {
|
||||||
|
*view_area = LAB_DECO_PART_LEFT;
|
||||||
|
return view;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue