mirror of
https://github.com/labwc/labwc.git
synced 2026-03-03 01:40:37 -05:00
cursor: Restore drag icon after the move to scene-graph
Also move everything DnD related to src/dnd.c
This commit is contained in:
parent
3e1a800c14
commit
deb658b672
6 changed files with 241 additions and 55 deletions
27
include/dnd.h
Normal file
27
include/dnd.h
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
#ifndef __LAB_DND_H
|
||||||
|
#define __LAB_DND_H
|
||||||
|
|
||||||
|
#include <wayland-server-core.h>
|
||||||
|
|
||||||
|
struct seat;
|
||||||
|
struct wlr_drag_icon;
|
||||||
|
struct wlr_scene_tree;
|
||||||
|
|
||||||
|
struct drag_icon {
|
||||||
|
struct wlr_scene_tree *icon_tree;
|
||||||
|
struct wlr_drag_icon *icon;
|
||||||
|
struct {
|
||||||
|
struct wl_listener map;
|
||||||
|
struct wl_listener commit;
|
||||||
|
struct wl_listener unmap;
|
||||||
|
struct wl_listener destroy;
|
||||||
|
} events;
|
||||||
|
};
|
||||||
|
|
||||||
|
void dnd_init(struct seat *seat);
|
||||||
|
void dnd_icons_show(struct seat *seat, bool show);
|
||||||
|
void dnd_icons_move(struct seat *seat, double x, double y);
|
||||||
|
void dnd_finish(struct seat *seat);
|
||||||
|
|
||||||
|
#endif /* __LAB_DND_H */
|
||||||
|
|
@ -104,7 +104,6 @@ struct seat {
|
||||||
struct wlr_cursor *cursor;
|
struct wlr_cursor *cursor;
|
||||||
struct wlr_xcursor_manager *xcursor_manager;
|
struct wlr_xcursor_manager *xcursor_manager;
|
||||||
|
|
||||||
struct wlr_drag_icon *drag_icon;
|
|
||||||
struct wlr_pointer_constraint_v1 *current_constraint;
|
struct wlr_pointer_constraint_v1 *current_constraint;
|
||||||
struct wlr_idle *wlr_idle;
|
struct wlr_idle *wlr_idle;
|
||||||
struct wlr_idle_inhibit_manager_v1 *wlr_idle_inhibit_manager;
|
struct wlr_idle_inhibit_manager_v1 *wlr_idle_inhibit_manager;
|
||||||
|
|
@ -136,6 +135,16 @@ struct seat {
|
||||||
uint32_t resize_edges;
|
uint32_t resize_edges;
|
||||||
} pressed;
|
} pressed;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
bool active;
|
||||||
|
struct {
|
||||||
|
struct wl_listener request;
|
||||||
|
struct wl_listener start;
|
||||||
|
struct wl_listener destroy;
|
||||||
|
} events;
|
||||||
|
struct wlr_scene_tree *icons;
|
||||||
|
} drag;
|
||||||
|
|
||||||
struct wl_client *active_client_while_inhibited;
|
struct wl_client *active_client_while_inhibited;
|
||||||
struct wl_list inputs;
|
struct wl_list inputs;
|
||||||
struct wl_listener new_input;
|
struct wl_listener new_input;
|
||||||
|
|
@ -163,9 +172,6 @@ struct seat {
|
||||||
struct wl_listener touch_motion;
|
struct wl_listener touch_motion;
|
||||||
struct wl_listener touch_frame;
|
struct wl_listener touch_frame;
|
||||||
|
|
||||||
struct wl_listener request_start_drag;
|
|
||||||
struct wl_listener start_drag;
|
|
||||||
struct wl_listener destroy_drag;
|
|
||||||
struct wl_listener constraint_commit;
|
struct wl_listener constraint_commit;
|
||||||
struct wl_listener idle_inhibitor_create;
|
struct wl_listener idle_inhibitor_create;
|
||||||
struct wl_listener pressed_surface_destroy;
|
struct wl_listener pressed_surface_destroy;
|
||||||
|
|
|
||||||
64
src/cursor.c
64
src/cursor.c
|
|
@ -9,6 +9,7 @@
|
||||||
#include "common/mem.h"
|
#include "common/mem.h"
|
||||||
#include "common/scene-helpers.h"
|
#include "common/scene-helpers.h"
|
||||||
#include "config/mousebind.h"
|
#include "config/mousebind.h"
|
||||||
|
#include "dnd.h"
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
#include "menu/menu.h"
|
#include "menu/menu.h"
|
||||||
#include "resistance.h"
|
#include "resistance.h"
|
||||||
|
|
@ -172,21 +173,6 @@ request_set_primary_selection_notify(struct wl_listener *listener, void *data)
|
||||||
event->serial);
|
event->serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
request_start_drag_notify(struct wl_listener *listener, void *data)
|
|
||||||
{
|
|
||||||
struct seat *seat = wl_container_of(
|
|
||||||
listener, seat, request_start_drag);
|
|
||||||
struct wlr_seat_request_start_drag_event *event = data;
|
|
||||||
if (wlr_seat_validate_pointer_grab_serial(seat->seat, event->origin,
|
|
||||||
event->serial)) {
|
|
||||||
wlr_seat_start_pointer_drag(seat->seat, event->drag,
|
|
||||||
event->serial);
|
|
||||||
} else {
|
|
||||||
wlr_data_source_destroy(event->drag->source);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
process_cursor_move(struct server *server, uint32_t time)
|
process_cursor_move(struct server *server, uint32_t time)
|
||||||
{
|
{
|
||||||
|
|
@ -348,7 +334,7 @@ cursor_update_common(struct server *server, struct cursor_context *ctx,
|
||||||
/* TODO: verify drag_icon logic */
|
/* TODO: verify drag_icon logic */
|
||||||
if (seat->pressed.surface && ctx->surface != seat->pressed.surface
|
if (seat->pressed.surface && ctx->surface != seat->pressed.surface
|
||||||
&& !update_pressed_surface(seat, ctx)
|
&& !update_pressed_surface(seat, ctx)
|
||||||
&& !seat->drag_icon) {
|
&& !seat->drag.active) {
|
||||||
if (cursor_has_moved) {
|
if (cursor_has_moved) {
|
||||||
/*
|
/*
|
||||||
* Button has been pressed while over another
|
* Button has been pressed while over another
|
||||||
|
|
@ -403,7 +389,7 @@ cursor_update_common(struct server *server, struct cursor_context *ctx,
|
||||||
* a drag operation.
|
* a drag operation.
|
||||||
*/
|
*/
|
||||||
wlr_seat_pointer_notify_clear_focus(wlr_seat);
|
wlr_seat_pointer_notify_clear_focus(wlr_seat);
|
||||||
if (!seat->drag_icon) {
|
if (!seat->drag.active) {
|
||||||
cursor_set(seat, cursor_get_from_ssd(ctx->type));
|
cursor_set(seat, cursor_get_from_ssd(ctx->type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -446,6 +432,10 @@ process_cursor_motion(struct server *server, uint32_t time)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (seat->drag.active) {
|
||||||
|
dnd_icons_move(seat, seat->cursor->x, seat->cursor->y);
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx.view && rc.focus_follow_mouse) {
|
if (ctx.view && rc.focus_follow_mouse) {
|
||||||
desktop_focus_and_activate_view(seat, ctx.view);
|
desktop_focus_and_activate_view(seat, ctx.view);
|
||||||
if (rc.raise_on_focus) {
|
if (rc.raise_on_focus) {
|
||||||
|
|
@ -490,21 +480,6 @@ cursor_update_focus(struct server *server)
|
||||||
/*cursor_has_moved*/ false);
|
/*cursor_has_moved*/ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
start_drag(struct wl_listener *listener, void *data)
|
|
||||||
{
|
|
||||||
struct seat *seat = wl_container_of(listener, seat, start_drag);
|
|
||||||
struct wlr_drag *wlr_drag = data;
|
|
||||||
seat_reset_pressed(seat);
|
|
||||||
seat->drag_icon = wlr_drag->icon;
|
|
||||||
if (!seat->drag_icon) {
|
|
||||||
wlr_log(WLR_ERROR,
|
|
||||||
"Started drag but application did not set a drag icon");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
wl_signal_add(&seat->drag_icon->events.destroy, &seat->destroy_drag);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
handle_constraint_commit(struct wl_listener *listener, void *data)
|
handle_constraint_commit(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
|
|
@ -611,18 +586,6 @@ cursor_motion(struct wl_listener *listener, void *data)
|
||||||
process_cursor_motion(seat->server, event->time_msec);
|
process_cursor_motion(seat->server, event->time_msec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
destroy_drag(struct wl_listener *listener, void *data)
|
|
||||||
{
|
|
||||||
struct seat *seat = wl_container_of(listener, seat, destroy_drag);
|
|
||||||
|
|
||||||
if (!seat->drag_icon) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
seat->drag_icon = NULL;
|
|
||||||
desktop_focus_topmost_mapped_view(seat->server);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
cursor_motion_absolute(struct wl_listener *listener, void *data)
|
cursor_motion_absolute(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
|
|
@ -1022,6 +985,8 @@ cursor_init(struct seat *seat)
|
||||||
cursor_names = cursors_x11;
|
cursor_names = cursors_x11;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dnd_init(seat);
|
||||||
|
|
||||||
seat->cursor_motion.notify = cursor_motion;
|
seat->cursor_motion.notify = cursor_motion;
|
||||||
wl_signal_add(&seat->cursor->events.motion, &seat->cursor_motion);
|
wl_signal_add(&seat->cursor->events.motion, &seat->cursor_motion);
|
||||||
seat->cursor_motion_absolute.notify = cursor_motion_absolute;
|
seat->cursor_motion_absolute.notify = cursor_motion_absolute;
|
||||||
|
|
@ -1054,13 +1019,6 @@ cursor_init(struct seat *seat)
|
||||||
seat->request_set_selection.notify = request_set_selection_notify;
|
seat->request_set_selection.notify = request_set_selection_notify;
|
||||||
wl_signal_add(&seat->seat->events.request_set_selection,
|
wl_signal_add(&seat->seat->events.request_set_selection,
|
||||||
&seat->request_set_selection);
|
&seat->request_set_selection);
|
||||||
seat->request_start_drag.notify = request_start_drag_notify;
|
|
||||||
wl_signal_add(&seat->seat->events.request_start_drag,
|
|
||||||
&seat->request_start_drag);
|
|
||||||
seat->start_drag.notify = start_drag;
|
|
||||||
wl_signal_add(&seat->seat->events.start_drag,
|
|
||||||
&seat->start_drag);
|
|
||||||
seat->destroy_drag.notify = destroy_drag;
|
|
||||||
|
|
||||||
seat->request_set_primary_selection.notify =
|
seat->request_set_primary_selection.notify =
|
||||||
request_set_primary_selection_notify;
|
request_set_primary_selection_notify;
|
||||||
|
|
@ -1070,6 +1028,8 @@ cursor_init(struct seat *seat)
|
||||||
|
|
||||||
void cursor_finish(struct seat *seat)
|
void cursor_finish(struct seat *seat)
|
||||||
{
|
{
|
||||||
|
/* TODO: either clean up all the listeners or none of them */
|
||||||
|
|
||||||
wl_list_remove(&seat->cursor_motion.link);
|
wl_list_remove(&seat->cursor_motion.link);
|
||||||
wl_list_remove(&seat->cursor_motion_absolute.link);
|
wl_list_remove(&seat->cursor_motion_absolute.link);
|
||||||
wl_list_remove(&seat->cursor_button.link);
|
wl_list_remove(&seat->cursor_button.link);
|
||||||
|
|
@ -1088,4 +1048,6 @@ void cursor_finish(struct seat *seat)
|
||||||
|
|
||||||
wlr_xcursor_manager_destroy(seat->xcursor_manager);
|
wlr_xcursor_manager_destroy(seat->xcursor_manager);
|
||||||
wlr_cursor_destroy(seat->cursor);
|
wlr_cursor_destroy(seat->cursor);
|
||||||
|
|
||||||
|
dnd_finish(seat);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "common/list.h"
|
#include "common/list.h"
|
||||||
#include "common/scene-helpers.h"
|
#include "common/scene-helpers.h"
|
||||||
|
#include "dnd.h"
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
#include "layers.h"
|
#include "layers.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
|
@ -295,10 +296,20 @@ get_cursor_context(struct server *server)
|
||||||
{
|
{
|
||||||
struct cursor_context ret = {.type = LAB_SSD_NONE};
|
struct cursor_context ret = {.type = LAB_SSD_NONE};
|
||||||
struct wlr_cursor *cursor = server->seat.cursor;
|
struct wlr_cursor *cursor = server->seat.cursor;
|
||||||
|
|
||||||
|
/* Prevent drag icons to be on top of the hitbox detection */
|
||||||
|
if (server->seat.drag.active) {
|
||||||
|
dnd_icons_show(&server->seat, false);
|
||||||
|
}
|
||||||
|
|
||||||
struct wlr_scene_node *node =
|
struct wlr_scene_node *node =
|
||||||
wlr_scene_node_at(&server->scene->tree.node,
|
wlr_scene_node_at(&server->scene->tree.node,
|
||||||
cursor->x, cursor->y, &ret.sx, &ret.sy);
|
cursor->x, cursor->y, &ret.sx, &ret.sy);
|
||||||
|
|
||||||
|
if (server->seat.drag.active) {
|
||||||
|
dnd_icons_show(&server->seat, true);
|
||||||
|
}
|
||||||
|
|
||||||
ret.node = node;
|
ret.node = node;
|
||||||
if (!node) {
|
if (!node) {
|
||||||
ret.type = LAB_SSD_ROOT;
|
ret.type = LAB_SSD_ROOT;
|
||||||
|
|
|
||||||
179
src/dnd.c
Normal file
179
src/dnd.c
Normal file
|
|
@ -0,0 +1,179 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
#include <assert.h>
|
||||||
|
#include <wlr/types/wlr_data_device.h>
|
||||||
|
#include <wlr/types/wlr_scene.h>
|
||||||
|
#include <wlr/util/log.h>
|
||||||
|
#include "common/mem.h"
|
||||||
|
#include "dnd.h"
|
||||||
|
#include "labwc.h" /* for struct seat */
|
||||||
|
|
||||||
|
/* Internal DnD icon handlers */
|
||||||
|
static void
|
||||||
|
handle_icon_map(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct drag_icon *self = wl_container_of(listener, self, events.map);
|
||||||
|
struct wlr_drag_icon *icon = data;
|
||||||
|
if (icon->data) {
|
||||||
|
struct wlr_scene_tree *surface_tree = icon->data;
|
||||||
|
wlr_scene_node_set_enabled(&surface_tree->node, true);
|
||||||
|
} else {
|
||||||
|
icon->data = wlr_scene_subsurface_tree_create(
|
||||||
|
self->icon_tree, icon->surface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_surface_commit(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct drag_icon *self = wl_container_of(listener, self, events.commit);
|
||||||
|
struct wlr_surface *surface = data;
|
||||||
|
struct wlr_scene_tree *surface_tree = self->icon->data;
|
||||||
|
if (surface_tree) {
|
||||||
|
wlr_scene_node_set_position(&surface_tree->node,
|
||||||
|
surface->sx, surface->sy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_icon_unmap(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct drag_icon *self = wl_container_of(listener, self, events.unmap);
|
||||||
|
struct wlr_drag_icon *icon = data;
|
||||||
|
struct wlr_scene_tree *surface_tree = icon->data;
|
||||||
|
if (surface_tree) {
|
||||||
|
wlr_scene_node_set_enabled(&surface_tree->node, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_icon_destroy(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct drag_icon *self = wl_container_of(listener, self, events.destroy);
|
||||||
|
|
||||||
|
wl_list_remove(&self->events.map.link);
|
||||||
|
wl_list_remove(&self->events.commit.link);
|
||||||
|
wl_list_remove(&self->events.unmap.link);
|
||||||
|
wl_list_remove(&self->events.destroy.link);
|
||||||
|
|
||||||
|
if (self->icon->data) {
|
||||||
|
struct wlr_scene_tree *tree = self->icon->data;
|
||||||
|
wlr_scene_node_destroy(&tree->node);
|
||||||
|
}
|
||||||
|
|
||||||
|
self->icon = NULL;
|
||||||
|
self->icon_tree = NULL;
|
||||||
|
free(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
drag_icon_create(struct seat *seat, struct wlr_drag_icon *wlr_icon)
|
||||||
|
{
|
||||||
|
assert(seat);
|
||||||
|
assert(wlr_icon);
|
||||||
|
struct drag_icon *self = znew(*self);
|
||||||
|
|
||||||
|
self->icon = wlr_icon;
|
||||||
|
self->icon_tree = seat->drag.icons;
|
||||||
|
|
||||||
|
/* Position will be updated by cursor movement */
|
||||||
|
wlr_scene_node_set_position(&self->icon_tree->node,
|
||||||
|
seat->cursor->x, seat->cursor->y);
|
||||||
|
wlr_scene_node_raise_to_top(&self->icon_tree->node);
|
||||||
|
|
||||||
|
/* Set up events */
|
||||||
|
self->events.map.notify = handle_icon_map;
|
||||||
|
self->events.commit.notify = handle_surface_commit;
|
||||||
|
self->events.unmap.notify = handle_icon_unmap;
|
||||||
|
self->events.destroy.notify = handle_icon_destroy;
|
||||||
|
|
||||||
|
wl_signal_add(&wlr_icon->events.map, &self->events.map);
|
||||||
|
wl_signal_add(&wlr_icon->surface->events.commit, &self->events.commit);
|
||||||
|
wl_signal_add(&wlr_icon->events.unmap, &self->events.unmap);
|
||||||
|
wl_signal_add(&wlr_icon->events.destroy, &self->events.destroy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Internal DnD handlers */
|
||||||
|
static void
|
||||||
|
handle_drag_request(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct seat *seat = wl_container_of(listener, seat, drag.events.request);
|
||||||
|
struct wlr_seat_request_start_drag_event *event = data;
|
||||||
|
|
||||||
|
if (wlr_seat_validate_pointer_grab_serial(
|
||||||
|
seat->seat, event->origin, event->serial)) {
|
||||||
|
wlr_seat_start_pointer_drag(seat->seat, event->drag,
|
||||||
|
event->serial);
|
||||||
|
} else {
|
||||||
|
wlr_data_source_destroy(event->drag->source);
|
||||||
|
wlr_log(WLR_ERROR, "wrong source for drag request");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_drag_start(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct seat *seat = wl_container_of(listener, seat, drag.events.start);
|
||||||
|
assert(!seat->drag.active);
|
||||||
|
struct wlr_drag *drag = data;
|
||||||
|
|
||||||
|
seat->drag.active = true;
|
||||||
|
seat_reset_pressed(seat);
|
||||||
|
if (drag->icon) {
|
||||||
|
/* Cleans up automatically on drag->icon->events.detroy */
|
||||||
|
drag_icon_create(seat, drag->icon);
|
||||||
|
wlr_scene_node_set_enabled(&seat->drag.icons->node, true);
|
||||||
|
}
|
||||||
|
wl_signal_add(&drag->events.destroy, &seat->drag.events.destroy);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_drag_destroy(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct seat *seat = wl_container_of(listener, seat, drag.events.destroy);
|
||||||
|
assert(seat->drag.active);
|
||||||
|
|
||||||
|
seat->drag.active = false;
|
||||||
|
wl_list_remove(&seat->drag.events.destroy.link);
|
||||||
|
wlr_scene_node_set_enabled(&seat->drag.icons->node, false);
|
||||||
|
/* TODO: Not sure we actually need the following */
|
||||||
|
desktop_focus_topmost_mapped_view(seat->server);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Public API */
|
||||||
|
void
|
||||||
|
dnd_init(struct seat *seat)
|
||||||
|
{
|
||||||
|
seat->drag.icons = wlr_scene_tree_create(&seat->server->scene->tree);
|
||||||
|
wlr_scene_node_set_enabled(&seat->drag.icons->node, false);
|
||||||
|
|
||||||
|
seat->drag.events.request.notify = handle_drag_request;
|
||||||
|
seat->drag.events.start.notify = handle_drag_start;
|
||||||
|
seat->drag.events.destroy.notify = handle_drag_destroy;
|
||||||
|
|
||||||
|
wl_signal_add(&seat->seat->events.request_start_drag,
|
||||||
|
&seat->drag.events.request);
|
||||||
|
wl_signal_add(&seat->seat->events.start_drag, &seat->drag.events.start);
|
||||||
|
/*
|
||||||
|
* destroy.notify is listened to in handle_drag_start() and reset in
|
||||||
|
* handle_drag_destroy()
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dnd_icons_show(struct seat *seat, bool show)
|
||||||
|
{
|
||||||
|
wlr_scene_node_set_enabled(&seat->drag.icons->node, show);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dnd_icons_move(struct seat *seat, double x, double y)
|
||||||
|
{
|
||||||
|
wlr_scene_node_set_position(&seat->drag.icons->node, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dnd_finish(struct seat *seat)
|
||||||
|
{
|
||||||
|
wlr_scene_node_destroy(&seat->drag.icons->node);
|
||||||
|
wl_list_remove(&seat->drag.events.request.link);
|
||||||
|
wl_list_remove(&seat->drag.events.start.link);
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@ labwc_sources = files(
|
||||||
'cursor.c',
|
'cursor.c',
|
||||||
'debug.c',
|
'debug.c',
|
||||||
'desktop.c',
|
'desktop.c',
|
||||||
|
'dnd.c',
|
||||||
'foreign.c',
|
'foreign.c',
|
||||||
'interactive.c',
|
'interactive.c',
|
||||||
'keyboard.c',
|
'keyboard.c',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue