Re: gvncviewer improvement - input grab problems
- From: Michal Suchanek <hramrach centrum cz>
- To: "Daniel P. Berrange" <dan berrange com>
- Cc: gtk-vnc-list gnome org
- Subject: Re: gvncviewer improvement - input grab problems
- Date: Fri, 28 Aug 2009 16:20:00 +0200
Hello
Thanks for applying the default hostname patch.
2009/8/21 Daniel P. Berrange <dan berrange com>:
> On Fri, Aug 21, 2009 at 06:51:15PM +0200, Michal Suchanek wrote:
>> 2009/8/21 Daniel P. Berrange <dan berrange com>:
>> > On Tue, Aug 18, 2009 at 11:04:02PM +0200, Michal Suchanek wrote:
>> >> 2009/8/17 Michal Suchanek <hramrach centrum cz>:
>> Firstly I only use absolute mouse or no mouse at all, and I do not see
>> mouse grabbed except by this key combination. It clearly gets in my
>> way and provides no benefit for my configuration. The key combination
>> clashes in the sense that I might want to press Ctrl+Alt+some other
>> key (most often Delete) which toggles the grab and locks me inside the
>> viewer.
>
> If you only use absolute mouse, then we should provide a way to turn
> off the relative mouse mode extension - that would implicitly then
> disable the grab sequence.
Sending a patch that allows disabling the relative pointer extension.
It works for me but it could use some testing as the relative mode is
checked in quite a few places.
I have no idea how the other suggestions mentioned here would be
implemented in gtk-vnc and I really use only the two menu items (or
rather the corresponding command line switches).
While I can patch the viewer locally it would be nice to get into the
official sources because I use multiple architectures which makes
applying patches somewhat tedious.
The attached patch should apply over the previous menuitem patch.
Thanks
Michal
diff --git a/examples/gvncviewer.c b/examples/gvncviewer.c
index a4fbe99..47299c0 100644
--- a/examples/gvncviewer.c
+++ b/examples/gvncviewer.c
@@ -33,8 +33,13 @@
static gchar **args = NULL;
static gboolean keyboard_grab = TRUE;
+static gboolean relative_pointer = TRUE;
static const GOptionEntry options [] =
{
+ { "absolute", 'a', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE,
+ &relative_pointer, "Turn off relative pointer extension", NULL },
+ { "relative", 'r', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE,
+ &relative_pointer, "Turn on relative pointer extension", NULL },
{ "no-keyboard-grab", 'k', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE,
&keyboard_grab, "Turn off keyboard grab", NULL },
{ "keyboard-grab", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE,
@@ -231,6 +236,16 @@ static void do_keyboard_grab(GtkWidget *menu, GtkWidget *vncdisplay)
vnc_display_set_keyboard_grab(VNC_DISPLAY(vncdisplay), keyboard_grab);;
}
+static void do_relative(GtkWidget *menu, GtkWidget *vncdisplay)
+{
+ if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu)))
+ relative_pointer = TRUE;
+ else
+ relative_pointer = FALSE;
+
+ vnc_display_set_pointer_allow_relative(VNC_DISPLAY(vncdisplay), relative_pointer);
+}
+
static void vnc_credential(GtkWidget *vncdisplay, GValueArray *credList)
{
GtkWidget *dialog = NULL;
@@ -383,6 +398,7 @@ int main(int argc, char **argv)
GtkWidget *fullscreen;
GtkWidget *scaling;
GtkWidget *grab_toggle;
+ GtkWidget *relative_toggle;
const char *help_msg = "Run 'gvncviewer --help' to see a full list of available command line options";
/* Setup command line options */
@@ -457,10 +473,14 @@ int main(int argc, char **argv)
gtk_menu_item_set_submenu(GTK_MENU_ITEM(view), submenu);
- grab_toggle = gtk_check_menu_item_new_with_mnemonic("Allow Keyboard _Grab");
+ grab_toggle = gtk_check_menu_item_new_with_mnemonic("Keyboard _Grab");
gtk_menu_bar_append(GTK_MENU_BAR(menubar), grab_toggle);
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(grab_toggle), keyboard_grab);
+ relative_toggle = gtk_check_menu_item_new_with_mnemonic("_Relative Pointer");
+ gtk_menu_bar_append(GTK_MENU_BAR(menubar), relative_toggle);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(relative_toggle), relative_pointer);
+
#if WITH_LIBVIEW
ViewAutoDrawer_SetActive(VIEW_AUTODRAWER(layout), FALSE);
ViewOvBox_SetOver(VIEW_OV_BOX(layout), menubar);
@@ -486,6 +506,7 @@ int main(int argc, char **argv)
vnc_display_open_host(VNC_DISPLAY(vnc), hostname, port);
vnc_display_set_keyboard_grab(VNC_DISPLAY(vnc), keyboard_grab);;
vnc_display_set_pointer_grab(VNC_DISPLAY(vnc), TRUE);
+ vnc_display_set_pointer_allow_relative(VNC_DISPLAY(vnc), relative_pointer);
if (!gtk_widget_is_composited(window)) {
vnc_display_set_scaling(VNC_DISPLAY(vnc), TRUE);
@@ -542,6 +563,8 @@ int main(int argc, char **argv)
G_CALLBACK(do_scaling), vnc);
g_signal_connect(grab_toggle, "toggled",
G_CALLBACK(do_keyboard_grab), vnc);
+ g_signal_connect(relative_toggle, "toggled",
+ G_CALLBACK(do_relative), vnc);
#if WITH_LIBVIEW
g_signal_connect(window, "window-state-event",
G_CALLBACK(window_state_event), layout);
diff --git a/src/vncdisplay.c b/src/vncdisplay.c
index 1f080fe..757616c 100644
--- a/src/vncdisplay.c
+++ b/src/vncdisplay.c
@@ -80,6 +80,7 @@ struct _VncDisplayPrivate
int last_y;
gboolean absolute;
+ gboolean allow_relative;
gboolean grab_pointer;
gboolean grab_keyboard;
@@ -93,6 +94,11 @@ struct _VncDisplayPrivate
GSList *preferable_auths;
};
+inline static gboolean absolute(const struct _VncDisplayPrivate * priv)
+{
+ return priv->absolute || !priv->allow_relative;
+}
+
/* Delayed signal emission.
*
* We want signals to be delivered in the system coroutine. This helps avoid
@@ -131,7 +137,8 @@ enum
PROP_LOSSY_ENCODING,
PROP_SCALING,
PROP_SHARED_FLAG,
- PROP_FORCE_SIZE
+ PROP_FORCE_SIZE,
+ PROP_POINTER_ALLOW_RELATIVE
};
/* Signals */
@@ -190,6 +197,9 @@ vnc_display_get_property (GObject *object,
case PROP_KEYBOARD_GRAB:
g_value_set_boolean (value, vnc->priv->grab_keyboard);
break;
+ case PROP_POINTER_ALLOW_RELATIVE:
+ g_value_set_boolean (value, vnc->priv->allow_relative);
+ break;
case PROP_READ_ONLY:
g_value_set_boolean (value, vnc->priv->read_only);
break;
@@ -239,6 +249,8 @@ vnc_display_set_property (GObject *object,
case PROP_KEYBOARD_GRAB:
vnc_display_set_keyboard_grab (vnc, g_value_get_boolean (value));
break;
+ case PROP_POINTER_ALLOW_RELATIVE:
+ vnc_display_set_pointer_allow_relative (vnc, g_value_get_boolean (value));
case PROP_READ_ONLY:
vnc_display_set_read_only (vnc, g_value_get_boolean (value));
break;
@@ -475,7 +487,7 @@ static void do_pointer_ungrab(VncDisplay *obj, gboolean quiet)
gdk_pointer_ungrab(GDK_CURRENT_TIME);
priv->in_pointer_grab = FALSE;
- if (priv->absolute)
+ if (absolute(priv))
do_pointer_hide(obj);
if (!quiet)
@@ -503,7 +515,7 @@ static gboolean button_event(GtkWidget *widget, GdkEventButton *button)
gtk_widget_grab_focus (widget);
- if (priv->grab_pointer && !priv->absolute && !priv->in_pointer_grab &&
+ if (priv->grab_pointer && !absolute(priv) && !priv->in_pointer_grab &&
button->button == 1 && button->type == GDK_BUTTON_PRESS)
do_pointer_grab(VNC_DISPLAY(widget), FALSE);
@@ -513,7 +525,7 @@ static gboolean button_event(GtkWidget *widget, GdkEventButton *button)
else if (button->type == GDK_BUTTON_RELEASE)
priv->button_mask &= ~n;
- if (priv->absolute) {
+ if (absolute(priv)) {
gvnc_pointer_event(priv->gvnc, priv->button_mask,
priv->last_x, priv->last_y);
} else {
@@ -546,7 +558,7 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *scroll)
else
return FALSE;
- if (priv->absolute) {
+ if (absolute(priv)) {
gvnc_pointer_event(priv->gvnc, priv->button_mask | mask,
priv->last_x, priv->last_y);
gvnc_pointer_event(priv->gvnc, priv->button_mask,
@@ -588,7 +600,7 @@ static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
/* In relative mode, only move the server mouse pointer
* if the client grab is active */
- if (!priv->absolute && !priv->in_pointer_grab)
+ if (!absolute(priv) && !priv->in_pointer_grab)
return FALSE;
if (priv->read_only)
@@ -622,7 +634,7 @@ static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
}
/* Next adjust the real client pointer */
- if (!priv->absolute) {
+ if (!absolute(priv)) {
GdkDrawable *drawable = GDK_DRAWABLE(widget->window);
GdkDisplay *display = gdk_drawable_get_display(drawable);
GdkScreen *screen = gdk_drawable_get_screen(drawable);
@@ -652,7 +664,7 @@ 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) {
+ if (absolute(priv)) {
dx = (int)motion->x;
dy = (int)motion->y;
@@ -756,7 +768,7 @@ static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
(keyval == GDK_Alt_L && (key->state & GDK_CONTROL_MASK)))) {
if (priv->in_pointer_grab)
do_pointer_ungrab(VNC_DISPLAY(widget), FALSE);
- else if (!priv->grab_keyboard || !priv->absolute)
+ else if (!priv->grab_keyboard || !absolute(priv))
do_pointer_grab(VNC_DISPLAY(widget), FALSE);
}
@@ -980,7 +992,7 @@ static gboolean do_resize(void *opaque, int width, int height, gboolean quiet)
priv->null_cursor = create_null_cursor();
if (priv->local_pointer)
do_pointer_show(obj);
- else if (priv->in_pointer_grab || priv->absolute)
+ else if (priv->in_pointer_grab || absolute(priv))
do_pointer_hide(obj);
priv->gc = gdk_gc_new(GTK_WIDGET(obj)->window);
}
@@ -1034,17 +1046,17 @@ static gboolean on_get_preferred_pixel_format(void *opaque,
return TRUE;
}
-static gboolean on_pointer_type_change(void *opaque, int absolute)
+static gboolean on_pointer_type_change(void *opaque, int _absolute)
{
VncDisplay *obj = VNC_DISPLAY(opaque);
VncDisplayPrivate *priv = obj->priv;
- if (absolute && priv->in_pointer_grab && priv->grab_pointer)
- do_pointer_ungrab(obj, FALSE);
+ priv->absolute = _absolute;
- priv->absolute = absolute;
+ if (absolute(priv) && priv->in_pointer_grab && priv->grab_pointer)
+ do_pointer_ungrab(obj, FALSE);
- if (!priv->in_pointer_grab && !priv->absolute)
+ if (!priv->in_pointer_grab && !absolute(priv))
do_pointer_show(obj);
return TRUE;
@@ -1210,7 +1222,7 @@ static gboolean on_local_cursor(void *opaque, int x, int y, int width, int heigh
if (priv->in_pointer_grab) {
do_pointer_ungrab(obj, TRUE);
do_pointer_grab(obj, TRUE);
- } else if (priv->absolute) {
+ } else if (absolute(priv)) {
do_pointer_hide(obj);
}
@@ -1532,7 +1544,7 @@ void vnc_display_send_pointer(VncDisplay *obj, gint x, gint y, int button_mask)
if (priv->gvnc == NULL || !gvnc_is_open(obj->priv->gvnc))
return;
- if (priv->absolute) {
+ if (absolute(priv)) {
priv->button_mask = button_mask;
priv->last_x = x;
priv->last_y = y;
@@ -1628,6 +1640,17 @@ static void vnc_display_class_init(VncDisplayClass *klass)
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
g_object_class_install_property (object_class,
+ PROP_POINTER_ALLOW_RELATIVE,
+ g_param_spec_boolean ( "allow-relative-pointer",
+ "Allow Relative Pointer Extension",
+ "Whether we should allow relative mouse reportnig",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB));
+ g_object_class_install_property (object_class,
PROP_READ_ONLY,
g_param_spec_boolean ( "read-only",
"Read Only",
@@ -1897,6 +1920,7 @@ static void vnc_display_init(VncDisplay *display)
priv->last_x = -1;
priv->last_y = -1;
priv->absolute = 1;
+ priv->allow_relative = TRUE;
priv->fd = -1;
priv->read_only = FALSE;
priv->allow_lossy = FALSE;
@@ -2042,6 +2066,14 @@ void vnc_display_set_keyboard_grab(VncDisplay *obj, gboolean enable)
do_keyboard_ungrab(obj, FALSE);
}
+void vnc_display_set_pointer_allow_relative(VncDisplay *obj, gboolean enable)
+{
+ VncDisplayPrivate *priv = obj->priv;
+
+ priv->allow_relative = enable;
+ on_pointer_type_change(obj, priv->absolute);
+}
+
void vnc_display_set_read_only(VncDisplay *obj, gboolean enable)
{
obj->priv->read_only = enable;
@@ -2234,7 +2266,7 @@ gboolean vnc_display_get_read_only(VncDisplay *obj)
gboolean vnc_display_is_pointer_absolute(VncDisplay *obj)
{
- return obj->priv->absolute;
+ return absolute(obj->priv);
}
GOptionGroup *
diff --git a/src/vncdisplay.h b/src/vncdisplay.h
index 7c6a64e..2794404 100644
--- a/src/vncdisplay.h
+++ b/src/vncdisplay.h
@@ -106,6 +106,9 @@ gboolean vnc_display_get_pointer_local(VncDisplay *obj);
void vnc_display_set_pointer_grab(VncDisplay *obj, gboolean enable);
gboolean vnc_display_get_pointer_grab(VncDisplay *obj);
+void vnc_display_set_pointer_allow_relative(VncDisplay *obj, gboolean enable);
+gboolean vnc_display_get_pointer_allow_relative(VncDisplay *obj);
+
void vnc_display_set_keyboard_grab(VncDisplay *obj, gboolean enable);
gboolean vnc_display_get_keyboard_grab(VncDisplay *obj);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]