This commit is contained in:
n3rdopolis 2026-01-15 13:04:54 +00:00 committed by GitHub
commit 786a3fcb00
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 101 additions and 11 deletions

View file

@ -16,6 +16,9 @@ activities outside the scope of the running application are prevented.
# OPTIONS
*-c*
Enable clone mode for all attached screens
*-d*
Don't draw client side decorations when possible.

6
cage.c
View file

@ -241,6 +241,7 @@ usage(FILE *file, const char *cage)
fprintf(file,
"Usage: %s [OPTIONS] [--] [APPLICATION...]\n"
"\n"
" -c\t Enable clone mode for all attached screens\n"
" -d\t Don't draw client side decorations, when possible\n"
" -D\t Enable debug logging\n"
" -h\t Display this help message\n"
@ -257,8 +258,11 @@ static bool
parse_args(struct cg_server *server, int argc, char *argv[])
{
int c;
while ((c = getopt(argc, argv, "dDhm:sv")) != -1) {
while ((c = getopt(argc, argv, "cdDhm:sv")) != -1) {
switch (c) {
case 'c':
server->clone_mode = true;
break;
case 'd':
server->xdg_decoration = true;
break;

View file

@ -66,6 +66,13 @@ update_output_manager_config(struct cg_server *server)
}
wlr_output_manager_v1_set_configuration(server->output_manager_v1, config);
if (server->clone_mode) {
struct wlr_box confine_box;
seat_get_clone_confines(server, &confine_box);
server->seat->clone_confine_box = confine_box;
}
}
static inline void
@ -110,7 +117,11 @@ output_enable(struct cg_output *output)
wlr_output_state_set_enabled(&state, true);
if (wlr_output_commit_state(wlr_output, &state)) {
output_layout_add_auto(output);
if (output->server->clone_mode) {
output_layout_add(output, 0, 0);
} else {
output_layout_add_auto(output);
}
}
update_output_manager_config(output->server);
@ -313,7 +324,11 @@ handle_new_output(struct wl_listener *listener, void *data)
wlr_log(WLR_DEBUG, "Enabling new output %s", wlr_output->name);
if (wlr_output_commit_state(wlr_output, &state)) {
output_layout_add_auto(output);
if (output->server->clone_mode) {
output_layout_add(output, 0, 0);
} else {
output_layout_add_auto(output);
}
}
view_position_all(output->server);

49
seat.c
View file

@ -626,6 +626,7 @@ process_cursor_motion(struct cg_seat *seat, uint32_t time_msec, double dx, doubl
struct wlr_surface *surface = NULL;
struct cg_view *view = desktop_view_at(seat->server, seat->cursor->x, seat->cursor->y, &surface, &sx, &sy);
if (!view) {
wlr_seat_pointer_clear_focus(wlr_seat);
} else {
@ -669,9 +670,23 @@ handle_cursor_motion_relative(struct wl_listener *listener, void *data)
{
struct cg_seat *seat = wl_container_of(listener, seat, cursor_motion_relative);
struct wlr_pointer_motion_event *event = data;
double delta_x = event->delta_x;
double delta_y = event->delta_y;
wlr_cursor_move(seat->cursor, &event->pointer->base, event->delta_x, event->delta_y);
process_cursor_motion(seat, event->time_msec, event->delta_x, event->delta_y, event->unaccel_dx,
if (seat->server->clone_mode) {
struct wlr_box confine_box = seat->clone_confine_box;
if (seat->cursor->x + delta_x >= confine_box.width) {
delta_x = confine_box.width - seat->cursor->x;
}
if (seat->cursor->y + delta_y >= confine_box.height) {
delta_y = confine_box.height - seat->cursor->y;
}
}
wlr_cursor_move(seat->cursor, &event->pointer->base, delta_x, delta_y);
process_cursor_motion(seat, event->time_msec, delta_x, delta_y, event->unaccel_dx,
event->unaccel_dy);
wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat);
}
@ -978,6 +993,34 @@ seat_center_cursor(struct cg_seat *seat)
{
/* Place the cursor in the center of the output layout. */
struct wlr_box layout_box;
wlr_output_layout_get_box(seat->server->output_layout, NULL, &layout_box);
if (seat->server->clone_mode) {
layout_box = seat->clone_confine_box;
} else {
wlr_output_layout_get_box(seat->server->output_layout, NULL, &layout_box);
}
wlr_cursor_warp(seat->cursor, NULL, layout_box.width / 2, layout_box.height / 2);
}
void
seat_get_clone_confines(struct cg_server *server, struct wlr_box *confine_box)
{
int width = 0;
int height = 0;
struct cg_output *output;
/* Get the smallest dimensions out of all the screens */
wl_list_for_each (output, &server->outputs, link) {
if (width == 0 || width > output->wlr_output->width) {
width = output->wlr_output->width;
}
if (height == 0 || height > output->wlr_output->height) {
height = output->wlr_output->height;
}
}
confine_box->x = 0;
confine_box->y = 0;
confine_box->width = width;
confine_box->height = height;
}

3
seat.h
View file

@ -48,6 +48,8 @@ struct cg_seat {
struct wl_listener request_set_cursor;
struct wl_listener request_set_selection;
struct wl_listener request_set_primary_selection;
struct wlr_box clone_confine_box;
};
struct cg_keyboard_group {
@ -92,5 +94,6 @@ void seat_destroy(struct cg_seat *seat);
struct cg_view *seat_get_focus(struct cg_seat *seat);
void seat_set_focus(struct cg_seat *seat, struct cg_view *view);
void seat_center_cursor(struct cg_seat *seat);
void seat_get_clone_confines(struct cg_server *server, struct wlr_box *confine_box);
#endif

View file

@ -70,6 +70,7 @@ struct cg_server {
struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager;
bool clone_mode;
bool xdg_decoration;
bool allow_vt_switch;
bool return_app_code;

24
view.c
View file

@ -60,7 +60,12 @@ view_extends_output_layout(struct cg_view *view, struct wlr_box *layout_box)
int width, height;
view->impl->get_geometry(view, &width, &height);
return (layout_box->height < height || layout_box->width < width);
if (view->server->clone_mode) {
struct wlr_box confine_box = view->server->seat->clone_confine_box;
return (confine_box.height < height || confine_box.width < width);
} else {
return (layout_box->height < height || layout_box->width < width);
}
}
static void
@ -73,7 +78,12 @@ view_maximize(struct cg_view *view, struct wlr_box *layout_box)
wlr_scene_node_set_position(&view->scene_tree->node, view->lx, view->ly);
}
view->impl->maximize(view, layout_box->width, layout_box->height);
if (view->server->clone_mode) {
struct wlr_box confine_box = view->server->seat->clone_confine_box;
view->impl->maximize(view, confine_box.width, confine_box.height);
} else {
view->impl->maximize(view, layout_box->width, layout_box->height);
}
}
static void
@ -82,8 +92,14 @@ view_center(struct cg_view *view, struct wlr_box *layout_box)
int width, height;
view->impl->get_geometry(view, &width, &height);
view->lx = (layout_box->width - width) / 2;
view->ly = (layout_box->height - height) / 2;
if (view->server->clone_mode) {
struct wlr_box confine_box = view->server->seat->clone_confine_box;
view->lx = (confine_box.width - width) / 2;
view->ly = (confine_box.height - height) / 2;
} else {
view->lx = (layout_box->width - width) / 2;
view->ly = (layout_box->height - height) / 2;
}
if (view->scene_tree) {
wlr_scene_node_set_position(&view->scene_tree->node, view->lx, view->ly);

View file

@ -15,6 +15,7 @@
#include <wlr/types/wlr_xdg_shell.h>
#include <wlr/util/log.h>
#include "seat.h"
#include "server.h"
#include "view.h"
#include "xdg_shell.h"
@ -100,7 +101,11 @@ popup_unconstrain(struct wlr_xdg_popup *popup)
struct wlr_output *wlr_output =
wlr_output_layout_output_at(output_layout, view->lx + popup_box->x, view->ly + popup_box->y);
struct wlr_box output_box;
wlr_output_layout_get_box(output_layout, wlr_output, &output_box);
if (server->clone_mode) {
output_box = server->seat->clone_confine_box;
} else {
wlr_output_layout_get_box(output_layout, wlr_output, &output_box);
}
struct wlr_box output_toplevel_box = {
.x = output_box.x - view->lx,