From d664e78c943ca4eaac3bd73fba3dc9dac454da4e Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Fri, 1 Apr 2011 16:29:03 +0200 Subject: [PATCH] [broadway] Make pointer grabs not roundtrip Since we're really only initializing grabs (except for implicit grabs at least) from the client side we might as well do all the grab time checks on the client side to avoid unnecassary roundtrips. --- gdk/broadway/broadway.c | 18 +++------- gdk/broadway/broadway.h | 8 ++--- gdk/broadway/broadway.js | 17 +-------- gdk/broadway/gdkdevice-broadway.c | 58 +++++++++++++++++++----------- gdk/broadway/gdkdisplay-broadway.c | 6 ++++ gdk/broadway/gdkdisplay-broadway.h | 5 +++ 6 files changed, 58 insertions(+), 54 deletions(-) diff --git a/gdk/broadway/broadway.c b/gdk/broadway/broadway.c index 714905f9cf..604d18b23e 100644 --- a/gdk/broadway/broadway.c +++ b/gdk/broadway/broadway.c @@ -668,40 +668,32 @@ broadway_output_query_pointer (BroadwayOutput *output, int id) return serial; } -guint32 +void broadway_output_grab_pointer (BroadwayOutput *output, int id, - gboolean owner_event, - guint32 time_) + gboolean owner_event) { - char buf[HEADER_LEN + 3 + 1 + 6]; - guint32 serial; + char buf[HEADER_LEN + 3 + 1]; int p; - serial = output->serial; p = write_header (output, buf, 'g'); append_uint16 (id, buf, &p); buf[p++] = owner_event ? '1': '0'; - append_uint32 (time_, buf, &p); assert (p == sizeof (buf)); broadway_output_write (output, buf, sizeof (buf)); - - return serial; } guint32 -broadway_output_ungrab_pointer (BroadwayOutput *output, - guint32 time_) +broadway_output_ungrab_pointer (BroadwayOutput *output) { - char buf[HEADER_LEN + 6]; + char buf[HEADER_LEN]; guint32 serial; int p; serial = output->serial; p = write_header (output, buf, 'u'); - append_uint32 (time_, buf, &p); assert (p == sizeof (buf)); diff --git a/gdk/broadway/broadway.h b/gdk/broadway/broadway.h index 635fc918c1..0b9e9da584 100644 --- a/gdk/broadway/broadway.h +++ b/gdk/broadway/broadway.h @@ -59,9 +59,7 @@ void broadway_output_copy_rectangles (BroadwayOutput *output, int dy); guint32 broadway_output_query_pointer (BroadwayOutput *output, int id); -guint32 broadway_output_grab_pointer (BroadwayOutput *output, +void broadway_output_grab_pointer (BroadwayOutput *output, int id, - gboolean owner_event, - guint32 time_); -guint32 broadway_output_ungrab_pointer (BroadwayOutput *output, - guint32 time_); + gboolean owner_event); +guint32 broadway_output_ungrab_pointer (BroadwayOutput *output); diff --git a/gdk/broadway/broadway.js b/gdk/broadway/broadway.js index 686464be8e..b1c03a5b16 100644 --- a/gdk/broadway/broadway.js +++ b/gdk/broadway/broadway.js @@ -107,10 +107,6 @@ function initContext(canvas, x, y, id) return context; } -var GDK_GRAB_SUCCESS = 0; -var GDK_GRAB_ALREADY_GRABBED = 1; -var GDK_GRAB_INVALID_TIME = 2; - var GDK_CROSSING_NORMAL = 0; var GDK_CROSSING_GRAB = 1; var GDK_CROSSING_UNGRAB = 2; @@ -365,21 +361,10 @@ function handleCommands(cmdObj) var id = base64_16(cmd, i); i = i + 3; var ownerEvents = cmd[i++] == '1'; - var time = base64_32(cmd, i); - i = i + 6; - - if (grab.window != null) { - /* Previous grab, compare times */ - if (time != 0 && grab.time != 0 && - time > grab.time) { - sendInput ("g", [GDK_GRAB_INVALID_TIME]); - break; - } - } doGrab(id, ownerEvents, time, false); - sendInput ("g", [GDK_GRAB_SUCCESS]); + sendInput ("g", []); break; case 'u': // Ungrab diff --git a/gdk/broadway/gdkdevice-broadway.c b/gdk/broadway/gdkdevice-broadway.c index b99241f7b7..da01406b15 100644 --- a/gdk/broadway/gdkdevice-broadway.c +++ b/gdk/broadway/gdkdevice-broadway.c @@ -248,9 +248,6 @@ gdk_broadway_device_grab (GdkDevice *device, { GdkDisplay *display; GdkBroadwayDisplay *broadway_display; - GdkWindowImplBroadway *impl; - guint32 serial; - BroadwayInputMsg *reply; display = gdk_device_get_display (device); broadway_display = GDK_BROADWAY_DISPLAY (display); @@ -264,18 +261,28 @@ gdk_broadway_device_grab (GdkDevice *device, { /* Device is a pointer */ + if (broadway_display->pointer_grab_window != NULL && + time_ != 0 && broadway_display->pointer_grab_time > time_) + return GDK_GRAB_ALREADY_GRABBED; + + if (time_ == 0) + time_ = broadway_display->last_event_time; + + broadway_display->pointer_grab_window = window; + broadway_display->pointer_grab_owner_events = owner_events; + broadway_display->pointer_grab_time = time_; + if (broadway_display->output) { - impl = GDK_WINDOW_IMPL_BROADWAY (window->impl); - - serial = broadway_output_grab_pointer (broadway_display->output, - impl->id, owner_events, time_); - reply = _gdk_broadway_display_block_for_input (display, 'g', serial, FALSE); - if (reply != NULL) - return reply->grab_reply.res; + broadway_output_grab_pointer (broadway_display->output, + GDK_WINDOW_IMPL_BROADWAY (window->impl)->id, + owner_events); + gdk_display_flush (display); } - return GDK_GRAB_NOT_VIEWABLE; + /* TODO: What about toplevel grab events if we're not connected? */ + + return GDK_GRAB_SUCCESS; } } @@ -304,19 +311,30 @@ gdk_broadway_device_ungrab (GdkDevice *device, { /* Device is a pointer */ + if (broadway_display->pointer_grab_window != NULL && + time_ != 0 && broadway_display->pointer_grab_time > time_) + return; + + /* TODO: What about toplevel grab events if we're not connected? */ + if (broadway_display->output) { - serial = broadway_output_ungrab_pointer (broadway_display->output, time_); - + serial = broadway_output_ungrab_pointer (broadway_display->output); gdk_display_flush (display); - - grab = _gdk_display_get_last_device_grab (display, device); - if (grab && - (time_ == GDK_CURRENT_TIME || - grab->time == GDK_CURRENT_TIME || - !TIME_IS_LATER (grab->time, time_))) - grab->serial_end = serial; } + else + { + serial = broadway_display->saved_serial; + } + + grab = _gdk_display_get_last_device_grab (display, device); + if (grab && + (time_ == GDK_CURRENT_TIME || + grab->time == GDK_CURRENT_TIME || + !TIME_IS_LATER (grab->time, time_))) + grab->serial_end = serial; + + broadway_display->pointer_grab_window = NULL; } } diff --git a/gdk/broadway/gdkdisplay-broadway.c b/gdk/broadway/gdkdisplay-broadway.c index 839f665758..cb9235b449 100644 --- a/gdk/broadway/gdkdisplay-broadway.c +++ b/gdk/broadway/gdkdisplay-broadway.c @@ -634,6 +634,12 @@ start_output (HttpRequest *request) broadway_display->output = broadway_output_new (dup(fd), broadway_display->saved_serial); _gdk_broadway_resync_windows (); + + if (broadway_display->pointer_grab_window) + broadway_output_grab_pointer (broadway_display->output, + GDK_WINDOW_IMPL_BROADWAY (broadway_display->pointer_grab_window->impl)->id, + broadway_display->pointer_grab_owner_events); + http_request_free (request); } diff --git a/gdk/broadway/gdkdisplay-broadway.h b/gdk/broadway/gdkdisplay-broadway.h index 98a2b9f37a..170345ebdd 100644 --- a/gdk/broadway/gdkdisplay-broadway.h +++ b/gdk/broadway/gdkdisplay-broadway.h @@ -147,6 +147,11 @@ struct _GdkBroadwayDisplay GList *input_messages; guint64 last_event_time; + + /* Explicit pointer grabs: */ + GdkWindow *pointer_grab_window; + guint32 pointer_grab_time; + gboolean pointer_grab_owner_events; }; struct _GdkBroadwayDisplayClass