Fix relative mouse handling
This commit is contained in:
parent
8c79ebe502
commit
7c6847a6bd
142
gtk-vnc-0.3.8-relative-mouse.patch
Normal file
142
gtk-vnc-0.3.8-relative-mouse.patch
Normal file
@ -0,0 +1,142 @@
|
||||
commit 85279b75576fcce7465754a8cc7b21cb6db5c355
|
||||
Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
Date: Thu Feb 26 13:29:16 2009 +0000
|
||||
|
||||
Change pointer grab to allow movement across entire desktop and
|
||||
fix warping of pointer at desktop edges, to make relative mouse
|
||||
mode work correctly. Document what's going on with more comments.
|
||||
|
||||
diff --git a/src/vncdisplay.c b/src/vncdisplay.c
|
||||
index 5a25b91..f1082da 100644
|
||||
--- a/src/vncdisplay.c
|
||||
+++ b/src/vncdisplay.c
|
||||
@@ -439,14 +439,22 @@ static void do_pointer_grab(VncDisplay *obj, gboolean quiet)
|
||||
if (!priv->grab_keyboard)
|
||||
do_keyboard_grab(obj, quiet);
|
||||
|
||||
+ /*
|
||||
+ * For relative mouse to work correctly when grabbed we need to
|
||||
+ * allow the pointer to move anywhere on the local desktop, so
|
||||
+ * use NULL for the 'confine_to' argument. Furthermore we need
|
||||
+ * the coords to be reported to our VNC window, regardless of
|
||||
+ * what window the pointer is actally over, so use 'FALSE' for
|
||||
+ * 'owner_events' parameter
|
||||
+ */
|
||||
gdk_pointer_grab(GTK_WIDGET(obj)->window,
|
||||
- TRUE,
|
||||
+ FALSE, /* All events to come to our window directly */
|
||||
GDK_POINTER_MOTION_MASK |
|
||||
GDK_BUTTON_PRESS_MASK |
|
||||
GDK_BUTTON_RELEASE_MASK |
|
||||
GDK_BUTTON_MOTION_MASK |
|
||||
GDK_SCROLL_MASK,
|
||||
- GTK_WIDGET(obj)->window,
|
||||
+ NULL, /* Allow cursor to move over entire desktop */
|
||||
priv->remote_cursor ? priv->remote_cursor : priv->null_cursor,
|
||||
GDK_CURRENT_TIME);
|
||||
priv->in_pointer_grab = TRUE;
|
||||
@@ -551,15 +559,33 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *scroll)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+
|
||||
+/*
|
||||
+ * There are several scenarios to considier when handling client
|
||||
+ * mouse motion events:
|
||||
+ *
|
||||
+ * - Mouse in relative mode + centered rendering of desktop
|
||||
+ * - Mouse in relative mode + scaled rendering of desktop
|
||||
+ * - Mouse in absolute mode + centered rendering of desktop
|
||||
+ * - Mouse in absolute mode + scaled rendering of desktop
|
||||
+ *
|
||||
+ * Once scaled / offset, absolute mode is easy.
|
||||
+ *
|
||||
+ * Relative mode has a couple of special complications
|
||||
+ *
|
||||
+ * - Need to turn client absolute events into a delta
|
||||
+ * - Need to warp local pointer to avoid hitting a wall
|
||||
+ */
|
||||
static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
|
||||
{
|
||||
VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
|
||||
- int dx, dy;
|
||||
int ww, wh;
|
||||
|
||||
if (priv->gvnc == NULL || !gvnc_is_initialized(priv->gvnc))
|
||||
return FALSE;
|
||||
|
||||
+ /* In relative mode, only move the server mouse pointer
|
||||
+ * if the client grab is active */
|
||||
if (!priv->absolute && !priv->in_pointer_grab)
|
||||
return FALSE;
|
||||
|
||||
@@ -568,11 +594,14 @@ static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
|
||||
|
||||
gdk_drawable_get_size(widget->window, &ww, &wh);
|
||||
|
||||
+ /* First apply adjustments to the coords in the motion event */
|
||||
if (priv->allow_scaling) {
|
||||
double sx, sy;
|
||||
sx = (double)priv->fb.width / (double)ww;
|
||||
sy = (double)priv->fb.height / (double)wh;
|
||||
|
||||
+ /* Scaling the desktop, so scale the mouse coords
|
||||
+ * by same ratio */
|
||||
motion->x *= sx;
|
||||
motion->y *= sy;
|
||||
} else {
|
||||
@@ -583,21 +612,28 @@ static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
|
||||
if (wh > priv->fb.height)
|
||||
mh = (wh - priv->fb.height) / 2;
|
||||
|
||||
+ /* Not scaling, drawing the desktop centered
|
||||
+ * in the larger window, so offset the mouse
|
||||
+ * coords to match centering */
|
||||
motion->x -= mw;
|
||||
motion->y -= mh;
|
||||
-
|
||||
- if (motion->x < 0 || motion->x >= priv->fb.width ||
|
||||
- motion->y < 0 || motion->y >= priv->fb.height)
|
||||
- return FALSE;
|
||||
}
|
||||
|
||||
- if (!priv->absolute && priv->in_pointer_grab) {
|
||||
+ /* Next adjust the real client pointer */
|
||||
+ if (!priv->absolute) {
|
||||
GdkDrawable *drawable = GDK_DRAWABLE(widget->window);
|
||||
GdkDisplay *display = gdk_drawable_get_display(drawable);
|
||||
GdkScreen *screen = gdk_drawable_get_screen(drawable);
|
||||
int x = (int)motion->x_root;
|
||||
int y = (int)motion->y_root;
|
||||
|
||||
+ /* In relative mode check to see if client pointer hit
|
||||
+ * one of the screen edges, and if so move it back by
|
||||
+ * 200 pixels. This is important because the pointer
|
||||
+ * in the server doesn't correspond 1-for-1, and so
|
||||
+ * may still be only half way across the screen. Without
|
||||
+ * this warp, the server pointer would thus appear to hit
|
||||
+ * an invisible wall */
|
||||
if (x == 0) x += 200;
|
||||
if (y == 0) y += 200;
|
||||
if (x == (gdk_screen_get_width(screen) - 1)) x -= 200;
|
||||
@@ -611,11 +647,20 @@ static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Finally send the event to server */
|
||||
if (priv->last_x != -1) {
|
||||
+ int dx, dy;
|
||||
if (priv->absolute) {
|
||||
dx = (int)motion->x;
|
||||
dy = (int)motion->y;
|
||||
+
|
||||
+ /* Drop out of bounds motion to avoid upsetting
|
||||
+ * the server */
|
||||
+ if (dx < 0 || dx >= priv->fb.width ||
|
||||
+ dy < 0 || dy >= priv->fb.height)
|
||||
+ return FALSE;
|
||||
} else {
|
||||
+ /* Just send the delta since last motion event */
|
||||
dx = (int)motion->x + 0x7FFF - priv->last_x;
|
||||
dy = (int)motion->y + 0x7FFF - priv->last_y;
|
||||
}
|
@ -7,10 +7,11 @@
|
||||
Summary: A GTK widget for VNC clients
|
||||
Name: gtk-vnc
|
||||
Version: 0.3.8
|
||||
Release: 3%{?dist}
|
||||
Release: 4%{?dist}
|
||||
License: LGPLv2+
|
||||
Group: Development/Libraries
|
||||
Source: http://ftp.gnome.org/pub/GNOME/sources/%{name}/0.3/%{name}-%{version}.tar.gz
|
||||
Patch1: %{name}-%{version}-relative-mouse.patch
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
URL: http://live.gnome.org/gtk-vnc
|
||||
BuildRequires: gtk2-devel pygtk2-devel python-devel zlib-devel
|
||||
@ -67,6 +68,7 @@ browsers.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
%patch1 -p1
|
||||
|
||||
%build
|
||||
%if %{with_plugin}
|
||||
@ -120,7 +122,10 @@ rm -fr %{buildroot}
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Tue Feb 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.3.8-3
|
||||
* Thu Feb 26 2009 Daniel P. Berrange <berrange@redhat.com> - 0.3.8-4.fc11
|
||||
- Fix relative mouse handling to avoid 'invisible wall'
|
||||
|
||||
* Tue Feb 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.3.8-3.fc11
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
|
||||
|
||||
* Tue Feb 24 2009 Daniel P. Berrange <berrange@redhat.com> - 0.3.8-2.fc11
|
||||
|
Loading…
Reference in New Issue
Block a user