xwayland
This commit is contained in:
+1
-1
@@ -2,7 +2,7 @@ BasedOnStyle: LLVM
|
||||
IndentWidth: 4
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
ColumnLimit: 200
|
||||
ColumnLimit: 120
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
SortIncludes: true
|
||||
BreakBeforeBraces: Custom
|
||||
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
#include "types.h"
|
||||
|
||||
void client_from_coords(absn_server *server, double x, double y, struct wlr_surface **rsurface, absn_toplevel **rtoplevel, absn_layer_surface **rlayer_surface, double *rx, double *ry);
|
||||
void client_from_coords(absn_server *server, double x, double y, struct wlr_surface **rsurface,
|
||||
absn_toplevel **rtoplevel, absn_layer_surface **rlayer_surface, double *rx, double *ry);
|
||||
|
||||
void reset_cursor_mode(absn_server *server);
|
||||
void process_cursor_motion(absn_server *server, uint32_t time);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "types.h"
|
||||
|
||||
bool toplevel_is_unmanaged(absn_toplevel *toplevel);
|
||||
bool toplevel_wants_focus(absn_toplevel *toplevel);
|
||||
|
||||
void toplevel_get_geom(absn_toplevel *toplevel);
|
||||
|
||||
|
||||
+7
-5
@@ -28,10 +28,10 @@
|
||||
#define MAX(A, B) (A) > (B) ? (A) : (B)
|
||||
#define MIN(A, B) (A) < (B) ? (A) : (B)
|
||||
/* macro for adding listener for event */
|
||||
#define LISTEN(L, C, E) \
|
||||
do { \
|
||||
(L).notify = (C); \
|
||||
wl_signal_add(&(E), &(L)); \
|
||||
#define LISTEN(L, C, E) \
|
||||
do { \
|
||||
(L).notify = (C); \
|
||||
wl_signal_add(&(E), &(L)); \
|
||||
} while (0);
|
||||
#define UNUSED(X) (void)(X)
|
||||
#define CLEANMASK(M) (M & ~WLR_MODIFIER_CAPS)
|
||||
@@ -51,7 +51,7 @@ enum {
|
||||
BOTTOM_RIGHT,
|
||||
};
|
||||
|
||||
/* toplevel types */
|
||||
/* client types */
|
||||
enum {
|
||||
TOPLEVEL_XDG,
|
||||
TOPLEVEL_X11,
|
||||
@@ -218,6 +218,8 @@ struct absn_toplevel {
|
||||
struct wlr_scene_rect *border[4];
|
||||
struct wlr_xdg_toplevel_decoration_v1 *deco;
|
||||
|
||||
bool can_be_tiled;
|
||||
|
||||
bool floating;
|
||||
bool fullscreen;
|
||||
bool urgent;
|
||||
|
||||
+4
-2
@@ -50,7 +50,8 @@ static int setup(absn_server *server)
|
||||
server->scene = wlr_scene_create();
|
||||
if (wlr_renderer_get_texture_formats(server->renderer, WLR_BUFFER_CAP_DMABUF)) {
|
||||
wlr_drm_create(server->display, server->renderer);
|
||||
wlr_scene_set_linux_dmabuf_v1(server->scene, wlr_linux_dmabuf_v1_create_with_renderer(server->display, 5, server->renderer));
|
||||
wlr_scene_set_linux_dmabuf_v1(server->scene,
|
||||
wlr_linux_dmabuf_v1_create_with_renderer(server->display, 5, server->renderer));
|
||||
}
|
||||
server->bg = wlr_scene_rect_create(&server->scene->tree, 0, 0, bgcolor);
|
||||
|
||||
@@ -74,7 +75,8 @@ static int setup(absn_server *server)
|
||||
wlr_export_dmabuf_manager_v1_create(server->display);
|
||||
wlr_ext_foreign_toplevel_list_v1_create(server->display, 1);
|
||||
|
||||
wlr_server_decoration_manager_set_default_mode(wlr_server_decoration_manager_create(server->display), WLR_SERVER_DECORATION_MANAGER_MODE_SERVER);
|
||||
wlr_server_decoration_manager_set_default_mode(wlr_server_decoration_manager_create(server->display),
|
||||
WLR_SERVER_DECORATION_MANAGER_MODE_SERVER);
|
||||
server->xdg_deco_mgr = wlr_xdg_decoration_manager_v1_create(server->display);
|
||||
LISTEN(server->new_xdg_deco, new_xdg_decoration, server->xdg_deco_mgr->events.new_toplevel_decoration);
|
||||
|
||||
|
||||
+2
-1
@@ -9,7 +9,8 @@
|
||||
* returns surface at given cursor coordinates
|
||||
* and coordinates inside of it to process input event
|
||||
*/
|
||||
void client_from_coords(absn_server *server, double x, double y, struct wlr_surface **rsurface, absn_toplevel **rtoplevel, absn_layer_surface **rlayer_surface, double *rx, double *ry)
|
||||
void client_from_coords(absn_server *server, double x, double y, struct wlr_surface **rsurface,
|
||||
absn_toplevel **rtoplevel, absn_layer_surface **rlayer_surface, double *rx, double *ry)
|
||||
{
|
||||
struct wlr_scene_node *pnode = NULL, *node = NULL;
|
||||
struct wlr_scene_buffer *buffer = NULL;
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#include <stdnoreturn.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdnoreturn.h>
|
||||
#include <unistd.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
||||
+2
-1
@@ -21,7 +21,8 @@ static bool handle_keybind(absn_server *server, uint32_t mods, xkb_keysym_t keys
|
||||
{
|
||||
int nkeyb = sizeof(keybinds) / sizeof(keybinds[0]);
|
||||
for (int i = 0; i < nkeyb; ++i) {
|
||||
if (CLEANMASK(keybinds[i].mods) == CLEANMASK(mods) && xkb_keysym_to_lower(keybinds[i].keysym) == xkb_keysym_to_lower(keysym)) {
|
||||
if (CLEANMASK(keybinds[i].mods) == CLEANMASK(mods) &&
|
||||
xkb_keysym_to_lower(keybinds[i].keysym) == xkb_keysym_to_lower(keysym)) {
|
||||
keybinds[i].cb(server, &keybinds[i].arg);
|
||||
return true;
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
#include <wlr/types/wlr_layer_shell_v1.h>
|
||||
#include <stdlib.h>
|
||||
#include <wlr/types/wlr_layer_shell_v1.h>
|
||||
|
||||
#include "focus.h"
|
||||
#include "layers.h"
|
||||
@@ -54,6 +54,7 @@ void layer_surface_commit(struct wl_listener *listener, void *data)
|
||||
}
|
||||
|
||||
layers_arrange(layer_surface->output);
|
||||
wlr_surface_send_enter(surface->surface, surface->output);
|
||||
}
|
||||
|
||||
void layer_surface_new_popup(struct wl_listener *listener, void *data)
|
||||
|
||||
+4
-2
@@ -19,7 +19,8 @@ static void layer_arrange(absn_output *output, struct wl_list *list, struct wlr_
|
||||
}
|
||||
|
||||
wlr_scene_layer_surface_v1_configure(layer_surface->scene_layer, &output->geom, usable_area);
|
||||
wlr_scene_node_set_position(&layer_surface->popups->node, layer_surface->scene_tree->node.x, layer_surface->scene_tree->node.y);
|
||||
wlr_scene_node_set_position(&layer_surface->popups->node, layer_surface->scene_tree->node.x,
|
||||
layer_surface->scene_tree->node.y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +65,8 @@ void layers_arrange(absn_output *output)
|
||||
output->server->exclusive_focus = layer_surface;
|
||||
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(output->server->seat);
|
||||
if (keyboard) {
|
||||
wlr_seat_keyboard_notify_enter(output->server->seat, layer_surface->wlr->surface, keyboard->keycodes, keyboard->num_keycodes, &keyboard->modifiers);
|
||||
wlr_seat_keyboard_notify_enter(output->server->seat, layer_surface->wlr->surface, keyboard->keycodes,
|
||||
keyboard->num_keycodes, &keyboard->modifiers);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
+8
-4
@@ -44,7 +44,8 @@ static void tile(struct absn_output *output)
|
||||
break;
|
||||
}
|
||||
}
|
||||
new_geom.x = output->usable_area.x + og, new_geom.y = output->usable_area.y + og, new_geom.width = output->usable_area.width - 2 * og, new_geom.height = output->usable_area.height - 2 * og,
|
||||
new_geom.x = output->usable_area.x + og, new_geom.y = output->usable_area.y + og,
|
||||
new_geom.width = output->usable_area.width - 2 * og, new_geom.height = output->usable_area.height - 2 * og,
|
||||
|
||||
toplevel_set_geom(toplevel, &new_geom);
|
||||
return;
|
||||
@@ -56,7 +57,8 @@ static void tile(struct absn_output *output)
|
||||
int mcount = output->workspace->count;
|
||||
float msize = output->workspace->size;
|
||||
|
||||
int32_t main_stack_width = (toplevels_count <= mcount) ? output->usable_area.width - 2 * og : msize * (output->usable_area.width - 2 * og);
|
||||
int32_t main_stack_width =
|
||||
(toplevels_count <= mcount) ? output->usable_area.width - 2 * og : msize * (output->usable_area.width - 2 * og);
|
||||
int32_t w = output->usable_area.width - main_stack_width - 2 * og - lg;
|
||||
|
||||
int32_t pure_h;
|
||||
@@ -163,7 +165,8 @@ static void tile_left(struct absn_output *output)
|
||||
break;
|
||||
}
|
||||
}
|
||||
new_geom.x = output->usable_area.x + og, new_geom.y = output->usable_area.y + og, new_geom.width = output->usable_area.width - 2 * og, new_geom.height = output->usable_area.height - 2 * og,
|
||||
new_geom.x = output->usable_area.x + og, new_geom.y = output->usable_area.y + og,
|
||||
new_geom.width = output->usable_area.width - 2 * og, new_geom.height = output->usable_area.height - 2 * og,
|
||||
|
||||
toplevel_set_geom(toplevel, &new_geom);
|
||||
return;
|
||||
@@ -175,7 +178,8 @@ static void tile_left(struct absn_output *output)
|
||||
int mcount = output->workspace->count;
|
||||
float msize = output->workspace->size;
|
||||
|
||||
int32_t main_stack_width = (toplevels_count <= mcount) ? output->usable_area.width - 2 * og : msize * (output->usable_area.width - 2 * og);
|
||||
int32_t main_stack_width =
|
||||
(toplevels_count <= mcount) ? output->usable_area.width - 2 * og : msize * (output->usable_area.width - 2 * og);
|
||||
int32_t w = output->usable_area.width - main_stack_width - 2 * og - lg;
|
||||
|
||||
int32_t pure_h;
|
||||
|
||||
+2
-1
@@ -17,12 +17,13 @@ void output_frame(struct wl_listener *listener, void *data)
|
||||
absn_toplevel *toplevel;
|
||||
wl_list_for_each(toplevel, &output->server->toplevels, link)
|
||||
{
|
||||
if (toplevel->resizing && toplevel->output == output) {
|
||||
if (toplevel->resizing && !toplevel->floating && toplevel->output == output) {
|
||||
goto skip;
|
||||
}
|
||||
}
|
||||
|
||||
wlr_scene_output_commit(scene_output, NULL);
|
||||
|
||||
skip:
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
wlr_scene_output_send_frame_done(scene_output, &now);
|
||||
|
||||
+4
-2
@@ -156,7 +156,8 @@ void new_layer_surface(struct wl_listener *listener, void *data)
|
||||
struct wlr_scene_tree *scene_layer = server->layers[layermap[surface->pending.layer]];
|
||||
layer_surface->scene_layer = wlr_scene_layer_surface_v1_create(scene_layer, surface);
|
||||
layer_surface->scene_tree = layer_surface->scene_layer->tree;
|
||||
layer_surface->popups = wlr_scene_tree_create(surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP ? server->layers[LAYER_TOP] : scene_layer);
|
||||
layer_surface->popups = wlr_scene_tree_create(
|
||||
surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP ? server->layers[LAYER_TOP] : scene_layer);
|
||||
|
||||
wl_list_insert(&layer_surface->output->layers[surface->pending.layer], &layer_surface->link);
|
||||
wlr_surface_send_enter(surface->surface, surface->output);
|
||||
@@ -300,7 +301,8 @@ void cursor_axis(struct wl_listener *listener, void *data)
|
||||
{
|
||||
absn_server *server = wl_container_of(listener, server, cursor_axis);
|
||||
struct wlr_pointer_axis_event *event = data;
|
||||
wlr_seat_pointer_notify_axis(server->seat, event->time_msec, event->orientation, event->delta, event->delta_discrete, event->source, event->relative_direction);
|
||||
wlr_seat_pointer_notify_axis(server->seat, event->time_msec, event->orientation, event->delta,
|
||||
event->delta_discrete, event->source, event->relative_direction);
|
||||
}
|
||||
|
||||
void cursor_frame(struct wl_listener *listener, void *data)
|
||||
|
||||
+42
-15
@@ -17,10 +17,20 @@ void toplevel_map(struct wl_listener *listener, void *data)
|
||||
toplevel->scene_tree->node.data = toplevel;
|
||||
wlr_scene_node_set_enabled(&toplevel->scene_tree->node, toplevel_is_unmanaged(toplevel));
|
||||
|
||||
if (toplevel->type != TOPLEVEL_X11 && wl_resource_get_version(toplevel->xdg->resource) >= XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION) {
|
||||
update_focused_output(toplevel->server);
|
||||
toplevel->output = toplevel->server->focused_output;
|
||||
toplevel->workspace = toplevel->output->workspace;
|
||||
toplevel->fullscreen = false;
|
||||
|
||||
#ifdef XWAYLAND
|
||||
if (toplevel->type == TOPLEVEL_X11) {
|
||||
toplevel->xw->surface->data = toplevel;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (toplevel->type != TOPLEVEL_X11 &&
|
||||
wl_resource_get_version(toplevel->xdg->resource) >= XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION) {
|
||||
wlr_xdg_toplevel_set_tiled(toplevel->xdg, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT);
|
||||
} else {
|
||||
wlr_xdg_toplevel_set_maximized(toplevel->xdg, true);
|
||||
}
|
||||
|
||||
#ifdef XWAYLAND
|
||||
@@ -36,27 +46,42 @@ void toplevel_map(struct wl_listener *listener, void *data)
|
||||
toplevel_get_geom(toplevel);
|
||||
toplevel->bw = toplevel_is_unmanaged(toplevel) ? 0 : TOPLEVEL_BW;
|
||||
|
||||
#ifdef XWAYLAND
|
||||
if (toplevel->type == TOPLEVEL_X11) {
|
||||
toplevel->xw->surface->data = toplevel;
|
||||
if (toplevel_is_unmanaged(toplevel)) {
|
||||
toplevel_set_floating(toplevel, true);
|
||||
toplevel_set_size(toplevel, toplevel->geom.width, toplevel->geom.height);
|
||||
if (toplevel_wants_focus(toplevel)) {
|
||||
focus_toplevel(toplevel);
|
||||
server->exclusive_focus = toplevel;
|
||||
}
|
||||
goto unset_fullscreen;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
toplevel->border[i] = wlr_scene_rect_create(toplevel->scene_tree, 0, 0, unfocused_bc);
|
||||
toplevel->border[i]->node.data = toplevel;
|
||||
}
|
||||
|
||||
update_focused_output(toplevel->server);
|
||||
toplevel->output = toplevel->server->focused_output;
|
||||
toplevel->workspace = toplevel->output->workspace;
|
||||
toplevel->fullscreen = false;
|
||||
|
||||
wl_list_insert(&toplevel->server->toplevels, &toplevel->link);
|
||||
wl_list_insert(&toplevel->server->focus_stack, &toplevel->flink);
|
||||
|
||||
layout_arrange(toplevel->output);
|
||||
focus_toplevel(focus_get_topmost(toplevel->server));
|
||||
|
||||
if (toplevel->type == TOPLEVEL_XDG && toplevel->xdg->parent) {
|
||||
toplevel->floating = 1;
|
||||
} else if (toplevel->type == TOPLEVEL_X11 && toplevel->xw->parent) {
|
||||
toplevel->floating = 1;
|
||||
}
|
||||
|
||||
unset_fullscreen:
|
||||
absn_toplevel *t;
|
||||
wl_list_for_each(t, &server->toplevels, link)
|
||||
{
|
||||
if (t->workspace == toplevel->workspace && t->fullscreen) {
|
||||
toplevel_set_fullscreen(t, false);
|
||||
}
|
||||
}
|
||||
|
||||
layout_arrange(toplevel->output);
|
||||
}
|
||||
|
||||
void toplevel_unmap(struct wl_listener *listener, void *data)
|
||||
@@ -73,8 +98,10 @@ void toplevel_unmap(struct wl_listener *listener, void *data)
|
||||
toplevel->server->exclusive_focus = NULL;
|
||||
}
|
||||
|
||||
wl_list_remove(&toplevel->link);
|
||||
wl_list_remove(&toplevel->flink);
|
||||
if (!toplevel_is_unmanaged(toplevel)) {
|
||||
wl_list_remove(&toplevel->link);
|
||||
wl_list_remove(&toplevel->flink);
|
||||
}
|
||||
|
||||
layout_arrange(toplevel->output);
|
||||
focus_toplevel(focus_get_topmost(toplevel->server));
|
||||
|
||||
+18
-4
@@ -22,6 +22,14 @@ bool toplevel_is_unmanaged(absn_toplevel *toplevel)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool toplevel_wants_focus(absn_toplevel *toplevel)
|
||||
{
|
||||
#ifdef XWAYLAND
|
||||
return toplevel_is_unmanaged(toplevel) && wlr_xwayland_surface_override_redirect_wants_focus(toplevel->xw) &&
|
||||
wlr_xwayland_surface_icccm_input_model(toplevel->xw) != WLR_ICCCM_INPUT_MODEL_NONE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* used only to get initial window size */
|
||||
void toplevel_get_geom(absn_toplevel *toplevel)
|
||||
{
|
||||
@@ -69,7 +77,8 @@ void toplevel_set_pos(absn_toplevel *toplevel, int32_t x, int32_t y)
|
||||
|
||||
void toplevel_set_size(absn_toplevel *toplevel, int32_t width, int32_t height)
|
||||
{
|
||||
if (width <= 2 * toplevel->bw || height <= 2 * toplevel->bw || (width == toplevel->geom.width && height == toplevel->geom.height)) {
|
||||
if (width <= 2 * toplevel->bw || height <= 2 * toplevel->bw ||
|
||||
(width == toplevel->geom.width && height == toplevel->geom.height)) {
|
||||
return;
|
||||
}
|
||||
toplevel->geom.width = width;
|
||||
@@ -94,13 +103,14 @@ void toplevel_set_size(absn_toplevel *toplevel, int32_t width, int32_t height)
|
||||
}
|
||||
#ifdef XWAYLAND
|
||||
else if (toplevel->type == TOPLEVEL_X11) {
|
||||
wlr_xwayland_surface_configure(toplevel->xw, toplevel->geom.x, toplevel->geom.y, width - 2 * bw, height - 2 * toplevel->bw);
|
||||
wlr_xwayland_surface_configure(toplevel->xw, toplevel->geom.x, toplevel->geom.y, width - 2 * bw,
|
||||
height - 2 * toplevel->bw);
|
||||
/* manually update position */
|
||||
toplevel_set_pos(toplevel, toplevel->geom.x, toplevel->geom.y);
|
||||
} else
|
||||
}
|
||||
#endif
|
||||
|
||||
wlr_scene_subsurface_tree_set_clip(&toplevel->scene_surface->node, &clip);
|
||||
wlr_scene_subsurface_tree_set_clip(&toplevel->scene_surface->node, &clip);
|
||||
}
|
||||
|
||||
void toplevel_set_geom(absn_toplevel *toplevel, struct wlr_box *geom)
|
||||
@@ -115,6 +125,10 @@ void toplevel_set_floating(absn_toplevel *toplevel, bool floating)
|
||||
return;
|
||||
}
|
||||
|
||||
if (floating && !toplevel->can_be_tiled) {
|
||||
return;
|
||||
}
|
||||
|
||||
toplevel->floating = floating;
|
||||
|
||||
if (floating) {
|
||||
|
||||
+11
-1
@@ -1,5 +1,6 @@
|
||||
#ifdef XWAYLAND
|
||||
|
||||
#include "config.h"
|
||||
#include "xwayland.h"
|
||||
#include "toplevel-handlers.h"
|
||||
#include "toplevel.h"
|
||||
@@ -53,7 +54,16 @@ void xwayland_configure(struct wl_listener *listener, void *data)
|
||||
|
||||
void xwayland_set_hints(struct wl_listener *listener, void *data)
|
||||
{
|
||||
UNUSED(listener);
|
||||
UNUSED(data);
|
||||
absn_toplevel *toplevel = wl_container_of(listener, toplevel, xw_set_hints);
|
||||
if (toplevel == toplevel->server->focused_toplevel || !toplevel->xw->hints) {
|
||||
return;
|
||||
}
|
||||
|
||||
toplevel->urgent = xcb_icccm_wm_hints_get_urgency(toplevel->xw->hints);
|
||||
struct wlr_surface *surface = toplevel->xw->surface;
|
||||
if (toplevel->urgent && surface && surface->mapped) {
|
||||
toplevel_set_border_color(toplevel, urgent_bc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user