[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.
This commit is contained in:
Alexander Larsson 2011-04-01 16:29:03 +02:00
parent 56d05e093d
commit d664e78c94
6 changed files with 58 additions and 54 deletions

View File

@ -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));

View File

@ -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);

View File

@ -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

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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