[PATCH 1/2] server: Split out varargs version of wl_resource_post_error.
From: Christopher James Halse Rogers This will allow other wrappers around wl_resource_post_error to accept variable argument lists. Signed-off-by: Christopher James Halse Rogers --- src/wayland-server.c | 23 --- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/wayland-server.c b/src/wayland-server.c index eb1e500..00c93f7 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -273,17 +273,14 @@ wl_resource_queue_event(struct wl_resource *resource, uint32_t opcode, ...) wl_resource_queue_event_array(resource, opcode, args); } -WL_EXPORT void -wl_resource_post_error(struct wl_resource *resource, - uint32_t code, const char *msg, ...) +static void +wl_resource_post_error_vargs(struct wl_resource *resource, +uint32_t code, const char *msg, va_list argp) { struct wl_client *client = resource->client; char buffer[128]; - va_list ap; - va_start(ap, msg); - vsnprintf(buffer, sizeof buffer, msg, ap); - va_end(ap); + vsnprintf(buffer, sizeof buffer, msg, argp); /* * When a client aborts, its resources are destroyed in id order, @@ -298,6 +295,18 @@ wl_resource_post_error(struct wl_resource *resource, wl_resource_post_event(client->display_resource, WL_DISPLAY_ERROR, resource, code, buffer); client->error = 1; + +} + +WL_EXPORT void +wl_resource_post_error(struct wl_resource *resource, + uint32_t code, const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + wl_resource_post_error_vargs(resource, code, msg, ap); + va_end(ap); } static void -- 2.15.1 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel
RFC - Add internal server error message
Because C++ exceptions escaping into C FFI invokes undefined behaviour our Wayland implementation wraps all the interface vtable callbacks with try {} catch (...) { log_error }. This has the nice property of not crashing the server, but does result in the client and server having different ideas about the current state. In the interests of debugability it would be nice to tell clients that their request failed due to server error rather than silently continue into unknown territory. These patches introduce a WL_DISPLAY_ERROR_INTERNAL error the compositor can send in such cases. ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH 2/2] proto, server: Add internal server error message.
From: Christopher James Halse Rogers Many languages such as C++ or Rust have an unwinding error-reporting mechanism. Code in these languages can (and must!) wrap request handling callbacks in unwind guards to avoid undefined behaviour. As a consequence such code will detect internal server errors, but have no way to communicate such failures to the client. This adds a WL_DISPLAY_ERROR_INTERNAL error to wl_display so that such code can notify (and disconnect) client which hit internal bugs. Signed-off-by: Christopher James Halse Rogers --- protocol/wayland.xml | 2 ++ src/wayland-client.c | 3 +++ src/wayland-server-core.h | 4 src/wayland-server.c | 23 +++ tests/display-test.c | 40 5 files changed, 72 insertions(+) diff --git a/protocol/wayland.xml b/protocol/wayland.xml index b5662e0..1db31a6 100644 --- a/protocol/wayland.xml +++ b/protocol/wayland.xml @@ -94,6 +94,8 @@ summary="method doesn't exist on the specified interface"/> + diff --git a/src/wayland-client.c b/src/wayland-client.c index c1369b8..7c442b1 100644 --- a/src/wayland-client.c +++ b/src/wayland-client.c @@ -192,6 +192,9 @@ display_protocol_error(struct wl_display *display, uint32_t code, case WL_DISPLAY_ERROR_NO_MEMORY: err = ENOMEM; break; + case WL_DISPLAY_ERROR_INTERNAL: + err = EPROTO; + break; default: err = EFAULT; } diff --git a/src/wayland-server-core.h b/src/wayland-server-core.h index 2e725d9..7137da6 100644 --- a/src/wayland-server-core.h +++ b/src/wayland-server-core.h @@ -324,6 +324,10 @@ wl_client_get_object(struct wl_client *client, uint32_t id); void wl_client_post_no_memory(struct wl_client *client); +void +wl_client_post_internal_error(struct wl_client *client, + const char* msg, ...) WL_PRINTF(2,3); + void wl_client_add_resource_created_listener(struct wl_client *client, struct wl_listener *listener); diff --git a/src/wayland-server.c b/src/wayland-server.c index 00c93f7..6317f8f 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -650,6 +650,29 @@ wl_client_post_no_memory(struct wl_client *client) WL_DISPLAY_ERROR_NO_MEMORY, "no memory"); } +/** Report an internal server error + * + * \param client The client object + * \param msg A printf-style format string + * \param ... Format string arguments + * + * Report an unspecified internal error and disconnect the client. + * + * \memberof wl_client + */ +WL_EXPORT void +wl_client_post_internal_error(struct wl_client *client, + char const *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + wl_resource_post_error_vargs(client->display_resource, +WL_DISPLAY_ERROR_INTERNAL, +msg, ap); + va_end(ap); +} + WL_EXPORT void wl_resource_post_no_memory(struct wl_resource *resource) { diff --git a/tests/display-test.c b/tests/display-test.c index 9b49a0e..63f8b5a 100644 --- a/tests/display-test.c +++ b/tests/display-test.c @@ -419,6 +419,46 @@ TEST(post_nomem_tst) display_destroy(d); } +static void +post_internal_error_main(void) +{ + struct client *c = client_connect(); + struct wl_seat *seat = client_get_seat(c); + uint32_t object_id, protocol_error; + const struct wl_interface *interface; + + assert(stop_display(c, 1) == -1); + int err = wl_display_get_error(c->wl_display); + fprintf(stderr, "Err is %i\n", err); + assert(err == EPROTO); + protocol_error = wl_display_get_protocol_error(c->wl_display, + &interface, + &object_id); + assert(protocol_error == WL_DISPLAY_ERROR_INTERNAL); + assert(interface == &wl_display_interface); + + wl_proxy_destroy((struct wl_proxy *) seat); + client_disconnect_nocheck(c); +} + +TEST(post_internal_error_tst) +{ + struct display *d = display_create(); + struct client_info *cl; + + wl_global_create(d->wl_display, &wl_seat_interface, +1, d, bind_seat); + + cl = client_create_noarg(d, post_internal_error_main); + display_run(d); + + wl_client_post_internal_error(cl->wl_client, "Error %i", 20); + + display_resume(d); + + display_destroy(d); +} + static void register_reading(struct wl_display *display) { -- 2.15.1 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH v2] touchpad: add wobbling detection
On Sun, Feb 18, 2018 at 11:14:55PM +0300, Konstantin Kharlamov wrote: > The details are explained in comment in the code. That aside, I shall > mention the check is so light, that it shouldn't influence CPU > performance even a bit, and can blindly be kept always enabled. I like it! And it does work with a change (see below), so provided it still works for you, it's worth testing on more laptops. > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=104828 > > v2: rename the function, change comment style, and add calculation of > x_diff (the one that was used is an absolute coordinate). > > FWIW, the algorithm don't care that now added "prev_x" is unintialized, prev_x is initialized to 0 because we calloc everything in libinput. > because that happening means the time threshold won't get satisfied > either. It's not like I can't default-init it — it's just that asking > oneself a question "what default value should it have" results in "none". > > Signed-off-by: Konstantin Kharlamov > --- > src/evdev-mt-touchpad.c | 33 + > src/evdev-mt-touchpad.h | 2 ++ > 2 files changed, 35 insertions(+) > > diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c > index ead76456..80f56072 100644 > --- a/src/evdev-mt-touchpad.c > +++ b/src/evdev-mt-touchpad.c > @@ -131,6 +131,36 @@ tp_motion_history_push(struct tp_touch *t) > t->history.index = motion_index; > } > > +static inline void > +tp_detect_wobbling(struct tp_dispatch *tp, int x_diff, uint64_t time) > +{ > + if (tp->hysteresis.enabled) > + return; > + > + /* Idea: if we got a tuple of *very* quick moves like {Left, Right, > Left}, or > + * {Right, Left, Right}, it means touchpad jitters since no human > supposed to > + * be able to move like that within thresholds > + * > + * Algo: we encode left moves as zeroes, and right as ones. We also > drop the > + * array to all zeroes when contraints are not satisfied. Then we > search for > + * the pattern {1,0,1}. It can't match {Left, Right, Left}, but it does > match > + * {Left, Right, Left, Right}, so it's okay. > + */ the interesting bit here will be whether there are touchpads that wobble but with more than one event per direction. I suspect there are but this should be simple enough that it catches the first RLR movement (bound to happen at some point) and enable it then. The main question is whether there is a noticeable period of wobbling until this happens. I honestly don't know, we won't know until ppl start shouting at us... > + if (time - tp->hysteresis.last_motion_time > ms2us(20) || x_diff == 0) { > + tp->hysteresis.x_motion_in_threshold = 0; > + return; > + } empty line here please. > + tp->hysteresis.x_motion_in_threshold <<= 1; > + if (x_diff > 0) { /* right move */ s/x_diff/dx/, we use that everywhere else for deltas. > + tp->hysteresis.x_motion_in_threshold |= 1; > + static const char r_l_r = 5; /* {Right, Left, Right} */ declarations at the top of the block please, separated by an empty line. See CODING_STYLE in the repository. > + if (tp->hysteresis.x_motion_in_threshold & r_l_r) { this one will trigger on the first right movement, you need if ((tp->hysteresis.x_motion_in_threshold & r_l_r) == r_l_r) With that change, it seems to work correctly on my non-wobbling touchpad here. Does it still work for you when you add this? > + tp->hysteresis.enabled = true; > + evdev_log_debug(tp->device, "hysteresis enabled\n"); > + } > + } > +} > + > static inline void > tp_motion_hysteresis(struct tp_dispatch *tp, >struct tp_touch *t) > @@ -1405,6 +1435,8 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time) > tp_thumb_detect(tp, t, time); > tp_palm_detect(tp, t, time); > > + tp_detect_wobbling(tp, tp->hysteresis.prev_x - t->point.x, > time); > + tp->hysteresis.prev_x = t->point.x; the dx calculation should happen within tp_detect_wobbling, just pass the touch in and do the subtraction there. Plus that way you can do a simple: if (tp->prev.x == 0) dx = 0; which makes things more obvious. > tp_motion_hysteresis(tp, t); > tp_motion_history_push(t); > > @@ -2918,6 +2950,7 @@ tp_init_hysteresis(struct tp_dispatch *tp) > tp->hysteresis.margin.x = res_x/2; > tp->hysteresis.margin.y = res_y/2; > tp->hysteresis.enabled = false; > + tp->hysteresis.x_motion_in_threshold = 0; 'threshold' usually refers to a distance in libinput, here it's more a timeout. But calling it x_motion_history would be best here, IMO. > } > > static void > diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h > index 442f34a3..398a18ed 100644 > --- a/src/evdev-mt-touchpad.h > +++ b/src/evdev-mt-touchpad.h > @@ -276,6 +276,8 @
[PATCH libinput] touchpad: only begin fake touches when we have at least one finger down
If a single-touch touchpad drops below the pressure threshold in the same frame where a fake finger is added, we begin a fake touch here. The subsequent loop ends this fake touch because real_fingers_down is 0. This causes the tapping code to have a mismatch of how many fingers are down because it never sees the touch begin event for that finger. https://bugs.freedesktop.org/show_bug.cgi?id=105160 --- src/evdev-mt-touchpad-tap.c | 1 + src/evdev-mt-touchpad.c | 16 +--- test/test-touchpad-tap.c| 43 +++ 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c index eaf3a573..fadc9535 100644 --- a/src/evdev-mt-touchpad-tap.c +++ b/src/evdev-mt-touchpad-tap.c @@ -1027,6 +1027,7 @@ tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time) } else if (t->state == TOUCH_END) { if (t->was_down) { + assert(tp->tap.nfingers_down >= 1); tp->tap.nfingers_down--; tp_tap_handle_event(tp, t, TAP_EVENT_RELEASE, time); } diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index 02ad9dd8..b3ed6d56 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -1102,14 +1102,16 @@ tp_unhover_pressure(struct tp_dispatch *tp, uint64_t time) * _all_ fingers have enough pressure, even if some of the slotted * ones don't. Anything else gets insane quickly. */ - tp_for_each_touch(tp, t) { - if (t->state == TOUCH_HOVERING) { - /* avoid jumps when landing a finger */ - tp_motion_history_reset(t); - tp_begin_touch(tp, t, time); + if (real_fingers_down > 0) { + tp_for_each_touch(tp, t) { + if (t->state == TOUCH_HOVERING) { + /* avoid jumps when landing a finger */ + tp_motion_history_reset(t); + tp_begin_touch(tp, t, time); - if (tp->nfingers_down >= nfake_touches) - break; + if (tp->nfingers_down >= nfake_touches) + break; + } } } diff --git a/test/test-touchpad-tap.c b/test/test-touchpad-tap.c index 06caeb20..0616ae22 100644 --- a/test/test-touchpad-tap.c +++ b/test/test-touchpad-tap.c @@ -1591,6 +1591,48 @@ START_TEST(touchpad_3fg_tap_quickrelease) } END_TEST +START_TEST(touchpad_3fg_tap_hover_btntool) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + + if (libevdev_get_abs_maximum(dev->evdev, +ABS_MT_SLOT) >= 2) + return; + + litest_enable_tap(dev->libinput_device); + litest_enable_edge_scroll(dev); + + litest_drain_events(li); + + litest_touch_down(dev, 0, 50, 50); + litest_touch_down(dev, 1, 70, 50); + libinput_dispatch(li); + + litest_touch_move_to(dev, 0, 50, 50, 50, 70, 10, 0); + litest_touch_move_to(dev, 1, 70, 50, 50, 70, 10, 0); + litest_drain_events(li); + + /* drop below the pressure threshold in the same frame as starting a */ + litest_event(dev, EV_ABS, ABS_MT_PRESSURE, 3); + litest_event(dev, EV_ABS, ABS_PRESSURE, 3); + litest_event(dev, EV_KEY, BTN_TOUCH, 0); + litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0); + litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + libinput_dispatch(li); + + litest_push_event_frame(dev); + litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 1); + litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 0); + litest_pop_event_frame(dev); + litest_assert_empty_queue(li); + + litest_touch_up(dev, 0); + litest_touch_up(dev, 1); +} +END_TEST + START_TEST(touchpad_3fg_tap_btntool) { struct litest_device *dev = litest_current_device(); @@ -3273,6 +3315,7 @@ litest_setup_tests_touchpad_tap(void) litest_add_ranged("tap-3fg:3fg", touchpad_3fg_tap, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &tap_map_range); litest_add("tap-3fg:3fg", touchpad_3fg_tap_tap_again, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add("tap-3fg:3fg", touchpad_3fg_tap_quickrelease, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); + litest_add("tap-3fg:3fg", touchpad_3fg_tap_hover_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add_for_device("tap-3fg:3fg", touchpad_3fg_tap_btntool_pointerjump, LITEST_SYNAPTICS_TOPBUTTONPAD); litest_add("tap-4fg:4fg", touchpad_4fg_tap, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT); litest_add("tap-4fg:4fg", touchpad_4fg_tap_q
Re: [PATCH 0/2 libinput] [RFC] Add touchpad wobbliness detection
FWIW, given peoples complained about hysteresis algo latency, I'm also poking around with alternative hysteresis algos. One possible idea that came to my mind is to use the detection code posted here to figure the maximum wobbliness length (along each axis separately), then simply ignore movements of that length. No idea how's that gonna work, will check on holidays. On 19.02.2018 10:59, Peter Hutterer wrote: On Sun, Feb 18, 2018 at 01:09:22PM +0300, Konstantin Kharlamov wrote: For the purposes it seems to work fine — it's marked RFC because I see a small oddness, and I think it's better to ask someone more acknowledgable in libinput codebase. thanks, much appreciated. I was hoping I get to this today but didn't, I'll try for it tomorrow. meanwhile: For some reason every time I run libinput debug-events --verbose | grep bled I see a message about hysteresis being enabled, which then never appears until I stop the command, and re-run it again. It looks like every time the command ran, touchpad being reinitialized, making the function tp_init_hysteresis() to ran again. it's expected, yes. debug-events instantiates a new libinput context (you can't get to the one in the compositor) and your code, from a quick glance, only runs until enabled. so every time you start the tool, you start from zero. Cheers, Peter If this is an intentional behavior, then I have no other question, and the patchset should be fine. Though it would be nice if someone with a "non-wobbly" touchpad could test that it does not enable hysteresis for them (it all should be good, but testing never hurts :) P.S.: I don't have commit rights. Konstantin Kharlamov (2): touchpad: remove the code for disabling hysteresis touchpad: add wobbling detection src/evdev-mt-touchpad.c | 42 -- src/evdev-mt-touchpad.h | 1 + 2 files changed, 29 insertions(+), 14 deletions(-) -- 2.15.1 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel
[RFC weston 2/2] compositor-x11: Use event loop abstraction API
From: Quentin Glidic Signed-off-by: Quentin Glidic --- libweston/compositor-x11.c | 64 +- 1 file changed, 29 insertions(+), 35 deletions(-) diff --git a/libweston/compositor-x11.c b/libweston/compositor-x11.c index 14faeda03..7675b7275 100644 --- a/libweston/compositor-x11.c +++ b/libweston/compositor-x11.c @@ -81,7 +81,7 @@ struct x11_backend { xcb_screen_t*screen; xcb_cursor_t null_cursor; struct wl_array keys; - struct wl_event_source *xcb_source; + void*xcb_source; struct xkb_keymap *xkb_keymap; unsigned int has_xkb; uint8_t xkb_event_base; @@ -122,7 +122,7 @@ struct x11_output { xcb_window_twindow; struct weston_mode mode; struct weston_mode native; - struct wl_event_source *finish_frame_timer; + void *finish_frame_timer; xcb_gc_tgc; xcb_shm_seg_t segment; @@ -411,7 +411,9 @@ x11_output_repaint_gl(struct weston_output *output_base, pixman_region32_subtract(&ec->primary_plane.damage, &ec->primary_plane.damage, damage); - wl_event_source_timer_update(output->finish_frame_timer, 10); + weston_compositor_event_source_update_timeout(ec, + output->finish_frame_timer, + 10); return 0; } @@ -498,11 +500,13 @@ x11_output_repaint_shm(struct weston_output *output_base, free(err); } - wl_event_source_timer_update(output->finish_frame_timer, 10); + weston_compositor_event_source_update_timeout(ec, + output->finish_frame_timer, + 10); return 0; } -static int +static enum weston_event_source_status finish_frame_handler(void *data) { struct x11_output *output = data; @@ -511,7 +515,7 @@ finish_frame_handler(void *data) weston_compositor_read_presentation_clock(output->base.compositor, &ts); weston_output_finish_frame(&output->base, &ts, 0); - return 1; + return WESTON_EVENT_SOURCE_CONTINUE; } static void @@ -874,7 +878,8 @@ x11_output_disable(struct weston_output *base) if (!output->base.enabled) return 0; - wl_event_source_remove(output->finish_frame_timer); + weston_compositor_event_source_remove(base->compositor, + output->finish_frame_timer); if (backend->use_pixman) { pixman_renderer_output_destroy(&output->base); @@ -1044,7 +1049,11 @@ x11_output_enable(struct weston_output *base) loop = wl_display_get_event_loop(b->compositor->wl_display); output->finish_frame_timer = - wl_event_loop_add_timer(loop, finish_frame_handler, output); + weston_compositor_event_source_add_timeout(base->compositor, + WESTON_EVENT_SOURCE_PRIORITY_TIMEOUT, + 0, + finish_frame_handler, + output); weston_log("x11 output %dx%d, window id %d\n", output->base.current_mode->width, @@ -1394,20 +1403,8 @@ x11_backend_deliver_enter_event(struct x11_backend *b, b->prev_y = y; } -static int -x11_backend_next_event(struct x11_backend *b, - xcb_generic_event_t **event, uint32_t mask) -{ - if (mask & WL_EVENT_READABLE) - *event = xcb_poll_for_event(b->conn); - else - *event = xcb_poll_for_queued_event(b->conn); - - return *event != NULL; -} - -static int -x11_backend_handle_event(int fd, uint32_t mask, void *data) +static enum weston_event_source_status +x11_backend_handle_event(int fd, enum weston_event_source_fd_events mask, void *data) { struct x11_backend *b = data; struct x11_output *output; @@ -1424,12 +1421,10 @@ x11_backend_handle_event(int fd, uint32_t mask, void *data) uint32_t *k; uint32_t i, set; uint8_t response_type; - int count; struct timespec time; prev = NULL; - count = 0; - while (x11_backend_next_event(b, &event, mask)) { + while ((event = xcb_poll_for_event(b->conn)) != NULL) { response_type = event->response_type & ~0x80; switch (prev ? prev->response_type & ~0x80 : 0x80) { @@ -1637,7 +1632,6 @@ x11_backend_handle_event(int fd, uint32_t mask, void *data) } #endif - count++; if (prev != event)
[RFC weston 0/2] Event loop abstraction API
From: Quentin Glidic We discussed on IRC about races between the several event sources that exist in libweston, libwayland and compositor code. Adding a priority system in the event loop is a first step to fix these potential races and help cope with bad clients. A second issue is that compositor writers are usually used to some specific event loop library (GLib, Qt, libev or any other) with differences in APIs and some frameworks are tied to one. To make things easier to compositor writers, here is a draft for an event loop API abstraction that should allow to pick any library to work with libweston. (Still lacking the signal handling part.) Sending as RFC to check if the API is fine by Weston contributors before migrating all the codebase to it. Cheers, Quentin Glidic (2): libweston: Add event loop abstraction API compositor-x11: Use event loop abstraction API compositor/main.c | 182 +++-- libweston/compositor-x11.c | 64 libweston/compositor.c | 86 + libweston/compositor.h | 67 + 4 files changed, 358 insertions(+), 41 deletions(-) -- 2.15.1 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel
[RFC weston 1/2] libweston: Add event loop abstraction API
From: Quentin Glidic This will allow compositors to pick any event loop implementation they want, and integrating the libweston components with it. Specifically, idle and timeout sources can now have proper priorities to avoid being ghosted by client event processing. Signed-off-by: Quentin Glidic --- compositor/main.c | 182 +++-- libweston/compositor.c | 86 +++ libweston/compositor.h | 67 ++ 3 files changed, 329 insertions(+), 6 deletions(-) diff --git a/compositor/main.c b/compositor/main.c index 18810f288..c0a5ba506 100644 --- a/compositor/main.c +++ b/compositor/main.c @@ -76,6 +76,180 @@ struct wet_compositor { bool drm_use_current_mode; }; +static struct wet_compositor * +to_wet_compositor(struct weston_compositor *compositor) +{ + return weston_compositor_get_user_data(compositor); +} + +struct wet_event_source { + struct wl_event_loop *loop; + struct wl_event_source *source; + weston_event_source_callback cb; + weston_event_source_fd_callback fd_cb; + void *user_data; +}; + +static void +wet_event_source_idle_cb(void *data) +{ + struct wet_event_source *wsource = data; + enum weston_event_source_status ret; + + ret = wsource->cb(wsource->user_data); + if (ret == WESTON_EVENT_SOURCE_REMOVE) + return; + + wsource->source = wl_event_loop_add_idle(wsource->loop, wet_event_source_idle_cb, wsource); + if (wsource->source == NULL) + free(wsource); +} + +static void * +wet_event_source_add_idle(struct weston_compositor *compositor, + enum weston_event_source_priority priority, + weston_event_source_callback cb, void *user_data) +{ + struct wet_event_source *wsource = malloc(sizeof(struct wet_event_source)); + if (wsource == NULL) + return NULL; + + wsource->loop = wl_display_get_event_loop(compositor->wl_display); + wsource->cb = cb; + wsource->user_data = user_data; + + wsource->source = wl_event_loop_add_idle(wsource->loop, wet_event_source_idle_cb, wsource); + if (wsource->source == NULL) { + free(wsource); + return NULL; + } + + return wsource; +} + +static int +wet_event_source_timeout_cb(void *data) +{ + struct wet_event_source *wsource = data; + enum weston_event_source_status ret; + + ret = wsource->cb(wsource->user_data); + if (ret == WESTON_EVENT_SOURCE_CONTINUE) + return 0; + + wl_event_source_remove(wsource->source); + free(wsource); + return 0; +} + +static void * +wet_event_source_add_timeout(struct weston_compositor *compositor, +enum weston_event_source_priority priority, +uint32_t milliseconds, +weston_event_source_callback cb, void *user_data) +{ + struct wet_event_source *wsource = malloc(sizeof(struct wet_event_source)); + if (wsource == NULL) + return NULL; + + wsource->loop = wl_display_get_event_loop(compositor->wl_display); + wsource->cb = cb; + wsource->user_data = user_data; + + wsource->source = wl_event_loop_add_timer(wsource->loop, wet_event_source_timeout_cb, wsource); + if (wsource->source == NULL) { + free(wsource); + return NULL; + } + + if (milliseconds > 0) + wl_event_source_timer_update(wsource->source, milliseconds); + + return wsource; +} + +static void +wet_event_source_update_timeout(struct weston_compositor *compositor, + void *source, uint32_t milliseconds) +{ + struct wet_event_source *wsource = source; + + wl_event_source_timer_update(wsource->source, milliseconds); +} + +static int +wet_event_source_fd_cb(int fd, uint32_t mask, void *data) +{ + struct wet_event_source *wsource = data; + enum weston_event_source_status ret; + + ret = wsource->fd_cb(fd, mask, wsource->user_data); + if (ret == WESTON_EVENT_SOURCE_CONTINUE) + return 0; + + wl_event_source_remove(wsource->source); + free(wsource); + return 0; +} + +static void * +wet_event_source_add_fd(struct weston_compositor *compositor, + enum weston_event_source_priority priority, + int fd, enum weston_event_source_fd_events events, + weston_event_source_fd_callback cb, void *user_data) +{ + struct wet_event_source *wsource = malloc(sizeof(struct wet_event_source)); + if (wsource == NULL) + return NULL; + + wsource->loop = wl_display_get_event_loop(compositor->wl_display); + wsource->fd_cb = cb; + wsource->user_data = user_data; + + wsource->source = wl_event_loop_add_fd(wsource->loop, fd, events, we
[PATCH] xwm: Update input region on resize
Commit 332d1892 introduced a bug because the window was shaped only when the frame was created, leaving the input region unchanged regardless if the window was resized. This patch updates the input region shape on resize, fixing the problem. --- xwayland/window-manager.c | 46 +++--- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c index c307e19..5588166 100644 --- a/xwayland/window-manager.c +++ b/xwayland/window-manager.c @@ -659,6 +659,30 @@ weston_wm_window_get_input_rect(struct weston_wm_window *window, } static void +weston_wm_window_shape(struct weston_wm_window *window) +{ + struct weston_wm *wm = window->wm; + xcb_rectangle_t rect; + int x, y, width, height; + + weston_wm_window_get_input_rect(window, &x, &y, &width, &height); + + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + + /* The window frame was created with position and size which include +* an offset for margins and shadow. Set the input region to ignore +* shadow. */ + xcb_shape_rectangles(wm->conn, +XCB_SHAPE_SO_SET, +XCB_SHAPE_SK_INPUT, +0, window->frame_id, +0, 0, 1, &rect); +} + +static void weston_wm_window_send_configure_notify(struct weston_wm_window *window) { xcb_configure_notify_event_t configure_notify; @@ -789,6 +813,8 @@ weston_wm_handle_configure_notify(struct weston_wm *wm, xcb_generic_event_t *eve xwayland_api->set_xwayland(window->shsurf, window->x, window->y); } + + weston_wm_window_shape(window); } static void @@ -983,7 +1009,6 @@ weston_wm_window_create_frame(struct weston_wm_window *window) { struct weston_wm *wm = window->wm; uint32_t values[3]; - xcb_rectangle_t rect; int x, y, width, height; int buttons = FRAME_BUTTON_CLOSE; @@ -1040,24 +1065,7 @@ weston_wm_window_create_frame(struct weston_wm_window *window) &wm->format_rgba, width, height); - weston_wm_window_get_input_rect(window, &x, &y, &width, &height); - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; - - /* The window frame was created with position and size which include -* an offset for margins and shadow. Set the input region to ignore -* shadow. */ - xcb_shape_rectangles(wm->conn, -XCB_SHAPE_SO_SET, -XCB_SHAPE_SK_INPUT, -0, -window->frame_id, -0, -0, -1, -&rect); + weston_wm_window_shape(window); hash_table_insert(wm->window_hash, window->frame_id, window); } -- 2.7.4 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH] compositor-drm: handle null cursor_plane
Was crashing when I tried to take a screenshot. --- On my slightly unconventional setup (FreeBSD amdgpu), after merging recent changes, pressing the screenshot hotkey was crashing weston. Debugging revealed that cursor_plane was 0x0 here. I don't know why exactly, but adding this check fixes it. libweston/compositor-drm.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c index ff090907..278bc02d 100644 --- a/libweston/compositor-drm.c +++ b/libweston/compositor-drm.c @@ -1830,8 +1830,10 @@ drm_output_apply_state_legacy(struct drm_output_state *state) */ if (output->base.disable_planes) { output->cursor_view = NULL; - output->cursor_plane->base.x = INT32_MIN; - output->cursor_plane->base.y = INT32_MIN; + if (output->cursor_plane) { + output->cursor_plane->base.x = INT32_MIN; + output->cursor_plane->base.y = INT32_MIN; + } } if (state->dpms != WESTON_DPMS_ON) { -- 2.16.1 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH 0/2 libinput] [RFC] Add touchpad wobbliness detection
On Sun, Feb 18, 2018 at 01:09:22PM +0300, Konstantin Kharlamov wrote: > For the purposes it seems to work fine — it's marked RFC because I see a > small oddness, and I think it's better to ask someone more > acknowledgable in libinput codebase. thanks, much appreciated. I was hoping I get to this today but didn't, I'll try for it tomorrow. meanwhile: > > For some reason every time I run > > libinput debug-events --verbose | grep bled > > I see a message about hysteresis being enabled, which then never appears > until I stop the command, and re-run it again. It looks like every time > the command ran, touchpad being reinitialized, making the function > tp_init_hysteresis() to ran again. it's expected, yes. debug-events instantiates a new libinput context (you can't get to the one in the compositor) and your code, from a quick glance, only runs until enabled. so every time you start the tool, you start from zero. Cheers, Peter > If this is an intentional behavior, then I have no other question, and > the patchset should be fine. Though it would be nice if someone with a > "non-wobbly" touchpad could test that it does not enable hysteresis for > them (it all should be good, but testing never hurts :) > > > P.S.: I don't have commit rights. > > Konstantin Kharlamov (2): > touchpad: remove the code for disabling hysteresis > touchpad: add wobbling detection > > src/evdev-mt-touchpad.c | 42 -- > src/evdev-mt-touchpad.h | 1 + > 2 files changed, 29 insertions(+), 14 deletions(-) > > -- > 2.15.1 > > ___ > wayland-devel mailing list > wayland-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/wayland-devel > ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel