Comments (1)
So this is actually not that easy with my limited knowledge. The following patch is probably a start (edit: not really, see below).
Patch
diff --git a/include/config/rcxml.h b/include/config/rcxml.h
index d03e4a7..3b09f6d 100644
--- a/include/config/rcxml.h
+++ b/include/config/rcxml.h
@@ -89,6 +89,7 @@ struct rcxml {
/* graphics tablet */
struct tablet_config {
+ char *output_name;
struct wlr_fbox box;
enum rotation rotation;
uint16_t button_map_count;
diff --git a/include/input/tablet.h b/include/input/tablet.h
index df8537d..d02832f 100644
--- a/include/input/tablet.h
+++ b/include/input/tablet.h
@@ -3,12 +3,15 @@
#define LABWC_TABLET_H
#include <wayland-server-core.h>
+#include <labwc.h>
+
struct seat;
struct wlr_device;
struct wlr_input_device;
struct drawing_tablet {
struct seat *seat;
+ struct wlr_input_device *device;
struct wlr_tablet *tablet;
double x, y;
struct {
@@ -17,6 +20,7 @@ struct drawing_tablet {
struct wl_listener button;
struct wl_listener destroy;
// no interest in proximity events
+ struct wl_listener new_output;
} handlers;
};
diff --git a/src/config/rcxml.c b/src/config/rcxml.c
index 1ff3766..be2197a 100644
--- a/src/config/rcxml.c
+++ b/src/config/rcxml.c
@@ -862,6 +862,8 @@ entry(xmlNode *node, char *nodename, char *content)
rc.tablet.box.width = tablet_get_dbl_if_positive(content, "width");
} else if (!strcasecmp(nodename, "height.area.tablet")) {
rc.tablet.box.height = tablet_get_dbl_if_positive(content, "height");
+ } else if (!strcasecmp(nodename, "mapToOutput.tablet")) {
+ rc.tablet.output_name = xstrdup(content);
} else if (!strcasecmp(nodename, "rotate.tablet")) {
rc.tablet.rotation = tablet_parse_rotation(atoi(content));
} else if (!strcasecmp(nodename, "button.map.tablet")) {
diff --git a/src/input/tablet.c b/src/input/tablet.c
index 0a24d61..5ce8640 100644
--- a/src/input/tablet.c
+++ b/src/input/tablet.c
@@ -138,23 +138,48 @@ handle_destroy(struct wl_listener *listener, void *data)
{
struct drawing_tablet *tablet =
wl_container_of(listener, tablet, handlers.destroy);
+ wl_list_remove(&tablet->handlers.new_output.link);
free(tablet);
}
+static void
+map_to_output(struct drawing_tablet *tablet)
+{
+ struct output *output = NULL;
+ wlr_log(WLR_INFO, "map tablet to output %s\n", rc.tablet.output_name);
+ if (rc.tablet.output_name) {
+ output = output_from_name(tablet->seat->server, rc.tablet.output_name);
+ }
+ wlr_cursor_map_input_to_output(tablet->seat->cursor, tablet->device,
+ output ? output->wlr_output : NULL);
+ wlr_cursor_map_input_to_region(tablet->seat->cursor, tablet->device, NULL);
+}
+
+static void
+handle_new_output(struct wl_listener *listener, void *data)
+{
+ struct drawing_tablet *tablet =
+ wl_container_of(listener, tablet, handlers.new_output);
+ map_to_output(tablet);
+}
+
void
tablet_init(struct seat *seat, struct wlr_input_device *wlr_device)
{
wlr_log(WLR_DEBUG, "setting up tablet");
struct drawing_tablet *tablet = znew(*tablet);
tablet->seat = seat;
+ tablet->device = wlr_device;
tablet->tablet = wlr_tablet_from_input_device(wlr_device);
tablet->tablet->data = tablet;
tablet->x = 0.0;
tablet->y = 0.0;
wlr_log(WLR_INFO, "tablet dimensions: %.2fmm x %.2fmm",
tablet->tablet->width_mm, tablet->tablet->height_mm);
+ map_to_output(tablet);
CONNECT_SIGNAL(tablet->tablet, &tablet->handlers, axis);
CONNECT_SIGNAL(tablet->tablet, &tablet->handlers, tip);
CONNECT_SIGNAL(tablet->tablet, &tablet->handlers, button);
CONNECT_SIGNAL(wlr_device, &tablet->handlers, destroy);
+ CONNECT_SIGNAL(seat->server->backend, &tablet->handlers, new_output);
}
diff --git a/src/seat.c b/src/seat.c
index b8fb636..e6214b7 100644
--- a/src/seat.c
+++ b/src/seat.c
@@ -284,6 +284,7 @@ new_tablet(struct seat *seat, struct wlr_input_device *dev)
{
struct input *input = znew(*input);
input->wlr_input_device = dev;
+ wlr_cursor_attach_input_device(seat->cursor, dev);
tablet_init(seat, dev);
return input;
It handles startup, hot-plugging the tablet at runtime and also connecting the mapped output at runtime, but explodes horribly when disconnecting the mapped output. I don't know how to correctly handle destroying of outputs. Any idea how to listen to that? Also no idea if it is really a good idea to connect to new_ouput
like I did in the patch.
On the good side, the mapping itself works fine, also together with coordinate transformation.
Edit: I guess above approach is pretty bad ;). Input to output mapping should still belong in seat
. Something like this should be more promising (also no more fiddling with signals), but cannot test right now because second monitor had been claimed :)
Patch v2
diff --git a/include/config/rcxml.h b/include/config/rcxml.h
index d03e4a7..3b09f6d 100644
--- a/include/config/rcxml.h
+++ b/include/config/rcxml.h
@@ -89,6 +89,7 @@ struct rcxml {
/* graphics tablet */
struct tablet_config {
+ char *output_name;
struct wlr_fbox box;
enum rotation rotation;
uint16_t button_map_count;
diff --git a/include/labwc.h b/include/labwc.h
index 7c409f6..825b300 100644
--- a/include/labwc.h
+++ b/include/labwc.h
@@ -456,6 +456,7 @@ void seat_set_pressed(struct seat *seat, struct view *view,
struct wlr_scene_node *node, struct wlr_surface *surface,
struct wlr_surface *toplevel, uint32_t resize_edges);
void seat_reset_pressed(struct seat *seat);
+void seat_outputs_changed(struct seat *seat);
void interactive_begin(struct view *view, enum input_mode mode, uint32_t edges);
void interactive_finish(struct view *view);
diff --git a/src/config/rcxml.c b/src/config/rcxml.c
index 1ff3766..be2197a 100644
--- a/src/config/rcxml.c
+++ b/src/config/rcxml.c
@@ -862,6 +862,8 @@ entry(xmlNode *node, char *nodename, char *content)
rc.tablet.box.width = tablet_get_dbl_if_positive(content, "width");
} else if (!strcasecmp(nodename, "height.area.tablet")) {
rc.tablet.box.height = tablet_get_dbl_if_positive(content, "height");
+ } else if (!strcasecmp(nodename, "mapToOutput.tablet")) {
+ rc.tablet.output_name = xstrdup(content);
} else if (!strcasecmp(nodename, "rotate.tablet")) {
rc.tablet.rotation = tablet_parse_rotation(atoi(content));
} else if (!strcasecmp(nodename, "button.map.tablet")) {
diff --git a/src/output.c b/src/output.c
index 833cb09..6051e43 100644
--- a/src/output.c
+++ b/src/output.c
@@ -85,6 +85,7 @@ output_destroy_notify(struct wl_listener *listener, void *data)
wl_list_remove(&output->frame.link);
wl_list_remove(&output->destroy.link);
wl_list_remove(&output->request_state.link);
+ seat_outputs_changed(&output->server->seat);
for (size_t i = 0; i < ARRAY_SIZE(output->layer_tree); i++) {
wlr_scene_node_destroy(&output->layer_tree[i]->node);
@@ -329,6 +330,7 @@ new_output_notify(struct wl_listener *listener, void *data)
server->pending_output_layout_change--;
do_output_layout_change(server);
+ seat_outputs_changed(&output->server->seat);
}
void
diff --git a/src/seat.c b/src/seat.c
index b8fb636..d3c069d 100644
--- a/src/seat.c
+++ b/src/seat.c
@@ -204,6 +204,17 @@ output_by_name(struct server *server, const char *name)
return NULL;
}
+static void
+map_input_to_output(struct seat *seat, struct wlr_input_device *dev, char *output_name)
+{
+ struct wlr_output *output = NULL;
+ if (output_name) {
+ output = output_by_name(seat->server, output_name);
+ }
+ wlr_cursor_map_input_to_output(seat->cursor, dev, output);
+ wlr_cursor_map_input_to_region(seat->cursor, dev, NULL);
+}
+
static struct input *
new_pointer(struct seat *seat, struct wlr_input_device *dev)
{
@@ -214,14 +225,9 @@ new_pointer(struct seat *seat, struct wlr_input_device *dev)
/* In support of running with WLR_WL_OUTPUTS set to >=2 */
if (dev->type == WLR_INPUT_DEVICE_POINTER) {
- struct wlr_output *output = NULL;
struct wlr_pointer *pointer = wlr_pointer_from_input_device(dev);
wlr_log(WLR_INFO, "map pointer to output %s\n", pointer->output_name);
- if (pointer->output_name) {
- output = output_by_name(seat->server, pointer->output_name);
- }
- wlr_cursor_map_input_to_output(seat->cursor, dev, output);
- wlr_cursor_map_input_to_region(seat->cursor, dev, NULL);
+ map_input_to_output(seat, dev, pointer->output_name);
}
return input;
}
@@ -267,14 +273,9 @@ new_touch(struct seat *seat, struct wlr_input_device *dev)
/* In support of running with WLR_WL_OUTPUTS set to >=2 */
if (dev->type == WLR_INPUT_DEVICE_TOUCH) {
- struct wlr_output *output = NULL;
struct wlr_touch *touch = wlr_touch_from_input_device(dev);
wlr_log(WLR_INFO, "map touch to output %s\n", touch->output_name);
- if (touch->output_name) {
- output = output_by_name(seat->server, touch->output_name);
- }
- wlr_cursor_map_input_to_output(seat->cursor, dev, output);
- wlr_cursor_map_input_to_region(seat->cursor, dev, NULL);
+ map_input_to_output(seat, dev, touch->output_name);
}
return input;
}
@@ -285,6 +286,9 @@ new_tablet(struct seat *seat, struct wlr_input_device *dev)
struct input *input = znew(*input);
input->wlr_input_device = dev;
tablet_init(seat, dev);
+ wlr_cursor_attach_input_device(seat->cursor, dev);
+ wlr_log(WLR_INFO, "map touch to output %s\n", rc.tablet.output_name);
+ map_input_to_output(seat, dev, rc.tablet.output_name);
return input;
}
@@ -636,3 +640,14 @@ seat_reset_pressed(struct seat *seat)
seat->pressed.toplevel = NULL;
seat->pressed.resize_edges = 0;
}
+
+void
+seat_outputs_changed(struct seat *seat)
+{
+ struct input *input = NULL;
+ wl_list_for_each(input, &seat->inputs, link) {
+ if (input->wlr_input_device->type == WLR_INPUT_DEVICE_TABLET_TOOL) {
+ map_input_to_output(seat, input->wlr_input_device, rc.tablet.output_name);
+ }
+ }
+}
Edit2: Yes, v2 works perfectly. With another small addition, I can also change the mapping on reconfigure
. So if this direction is fine, I'll happily create a PR for this one.
from labwc.
Related Issues (20)
- desk*.xbm (omnipresent) buttons cannot be styled/colorized HOT 5
- RFC: nomenclature for "Omnipresent" button and its theming HOT 3
- document new ssd buttons HOT 5
- Perhaps in the CI `scdoc` should be added.
- [Feature request] Allow pressing ESC to leave magnifier HOT 2
- [Question] Keeping my monitors off after inactivity HOT 18
- [Request] Add support for ~/Desktop icons HOT 4
- Enriching the <query> API to match that of openbox' HOT 2
- Viewporter protocol and layer-shell surfaces HOT 3
- Firefox Wayland goes crazy if display scale is changed and a window is placed over its top left corner HOT 5
- [Bug] Mouse not instantly captured by a game on movement HOT 1
- Unity Editor and various X11 programs fail to create a window HOT 4
- Colors saturation VGA vs HDMI HOT 3
- xdg_toplevel_set_fullscreen only sends config after a buffer is bound HOT 5
- drm leasing of the display labwc is using - does wp_drm_lease_v1_destroy restore the desktop? HOT 4
- Plan for release `0.8.1`
- [Question] How to use the magnifier
- When the width of the window is less than the length of the title, there will be a noticeable shrinkage process HOT 3
- [magnifier]: Leaving a flickering afterimage HOT 2
- menu contrast HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from labwc.