Re: PATCH: Add configurable key grab sequences (v3)
- From: "Daniel P. Berrange" <dan berrange com>
- To: Michal Novotny <minovotn redhat com>
- Cc: gtk-vnc-list gnome org
- Subject: Re: PATCH: Add configurable key grab sequences (v3)
- Date: Fri, 18 Jun 2010 12:53:34 +0100
On Fri, Jun 18, 2010 at 01:35:46PM +0200, Michal Novotny wrote:
>> @@ -216,6 +226,145 @@ static void do_scaling(GtkWidget *menu, GtkWidget *vncdisplay)
>> vnc_display_set_scaling(VNC_DISPLAY(vncdisplay), FALSE);
>> }
>>
>> +static void dialog_update_keysyms(GtkWidget *window, guint *keysyms, guint numsyms)
>> +{
>> + gchar *keys;
>> + int i;
>> +
>> + keys = g_strdup("");
>> + for (i = 0; i< numsyms; i++)
>> + {
>> + keys = g_strdup_printf("%s%s%s", keys,
>> + (strlen(keys)> 0) ? "+" : " ", gdk_keyval_name(keysyms[i]));
>> + }
>> +
>> + gtk_label_set_text( GTK_LABEL(window), keys);
>> +}
>> +
>> +static gboolean dialog_key_ignore(int keyval)
>> +{
>> + switch (keyval) {
>> + case GDK_Return:
>> + case GDK_Escape:
>> + return TRUE;
>> + }
>> +
>> + return FALSE;
>> +}
>>
>
> Maybe we may define some other in the future. However the main reason
> for this is that usually when starting Fedora (11) that I used for
> testing I've noticed that when the sequence is being set as Ctrl + Enter
> it grabs the enter and boots the entry in the Grub bootloader. For Ctrl
> + Esc it returns to the main Grub bootloader menu when editing the grub
> boot commands.
These examples/gvncviewer.{c,py} files are just examples of usage, so I
don't think we need to worry too much about getting things perfect in
their code. They just show people how todo interesting things with GTK-VNC
code.
>
>> +
>> +static gboolean dialog_key_press(GtkWidget *window G_GNUC_UNUSED,
>> + GdkEvent *ev, VncGrabDefs *defs)
>> +{
>> + gboolean keySymExists;
>> + int i;
>> +
>> + if (dialog_key_ignore(ev->key.keyval))
>> + return FALSE;
>> +
>> + if (defs->set&& defs->curkeys)
>> + return FALSE;
>> +
>> + /* Check whether we already have keysym in array - i.e. it was handler by something else */
>> + keySymExists = FALSE;
>> + for (i = 0; i< defs->curkeys; i++) {
>> + if (defs->keysyms[i] == ev->key.keyval)
>> + keySymExists = TRUE;
>> + }
>> +
>> + if (!keySymExists) {
>> + defs->keysyms = g_renew(guint, defs->keysyms, defs->curkeys + 1);
>> + defs->keysyms[defs->curkeys] = ev->key.keyval;
>> + defs->curkeys++;
>> + }
>> +
>> + dialog_update_keysyms(defs->label, defs->keysyms, defs->curkeys);
>> +
>> + if (!ev->key.is_modifier) {
>> + defs->set = TRUE;
>> + defs->numkeys = defs->curkeys;
>> + defs->curkeys--;
>> + }
>> +
>> + return FALSE;
>> +}
>> +
>>
>
> Just a note about this one since this is my original code: This expects
> user to press modifiers and end it with some non-modifier key. Like Ctrl
> + Alt + G for example. It doesn't accept Ctrl + Alt only since both the
> keys are modifiers. Nevertheless, since we have a good version of the
> patch now we can play with this when having time for that so we can
> watch for the curkeys counter count and if the value decremented this
> means one key has been released and therefore the sequence with this key
> could be the one to be set, e.g. press and release Ctrl + Alt and this
> will be registered/triggered:
>
> 1. press Ctrl (curkeys = 0 + 1 => 1)
> 2. press Alt (curkeys = 1 + 1 => 2)
> 3. release Ctrl (curkeys = 2 -1 => 1)
> 4. curkeys number decremented, trigger
> 4.1. save the remaining key in the sequence (Alt)
> 4.2. save the key that's been released now (Ctrl)
> 5. save the sequence to some list and use it for vnc_set_grab_keys()
>
> What do you think about this Daniel?
It took me a while to realize that it required you to enter at least
one non-modifier key, but I think this is absolutely fine for the
example program. Something like Vinagre would want to make it more
flexible to allow any key sequence.
>> + keystr = None
>> + for k in keys:
>> + if keystr is None:
>> + keystr = gtk.gdk.keyval_name(k)
>> + else:
>> + keystr = keystr + "+" + gtk.gdk.keyval_name(k)
>> if grabbed:
>> - subtitle = "(Press Ctrl+Alt to release pointer) "
>> + subtitle = "(Press %s to release pointer) " % keystr
>> else:
>> subtitle = ""
>>
>> @@ -173,6 +180,11 @@ layout.add(vnc)
>> vnc.realize()
>> vnc.set_pointer_grab(True)
>> vnc.set_keyboard_grab(True)
>> +
>> +# Example to change grab key combination to Ctrl+Alt+g
>> +grab_keys = [ gtk.keysyms.Control_L, gtk.keysyms.Alt_L, gtk.keysyms.g ]
>>
>
> Oh. Thanks. This is what I wrote above that I've been looking for. It's
> not being defined as "gtk.gdk.Alt_L" but like "gtk.keysyms.Alt_L"
> instead. Thanks for this code. It may be useful to know that some time.
It took me alot of googling to fine out that they were under
gtk.keysyms instead of gtk.gdk !
>> diff --git a/src/vncdisplay.c b/src/vncdisplay.c
>> index 71e158b..8eeb243 100644
>> --- a/src/vncdisplay.c
>> +++ b/src/vncdisplay.c
>> @@ -85,6 +85,9 @@ struct _VncDisplayPrivate
>>
>> GSList *preferable_auths;
>> const guint8 const *keycode_map;
>> +
>> + VncGrabSequence *vncgrabseq; /* the configured key sequence */
>> + gboolean *vncactiveseq; /* the currently pressed keys */
>>
>
> Ok, you did rename it to vncactiveseq. That's good. But what is this
> gboolean? Shouldn't this be the currently active sequence defined by
> keys pressed and numkeys/curkeys to identify number of keys being
> currently pressed?
I realized that with the two VncGrabSequence objects, we need to
iterate over both arrays, to detect a key grab sequence, since
keys can be pressed in any order. By changing to a boolean we
can just track up/down state directly and not worry about ordering
>
>> };
>>
>> G_DEFINE_TYPE(VncDisplay, vnc_display, GTK_TYPE_DRAWING_AREA)
>> @@ -104,7 +107,8 @@ enum
>> PROP_SCALING,
>> PROP_SHARED_FLAG,
>> PROP_FORCE_SIZE,
>> - PROP_DEPTH
>> + PROP_DEPTH,
>> + PROP_GRAB_KEYS,
>> };
>>
>> /* Signals */
>> @@ -198,6 +202,9 @@ vnc_display_get_property (GObject *object,
>> case PROP_DEPTH:
>> g_value_set_enum (value, vnc->priv->depth);
>> break;
>> + case PROP_GRAB_KEYS:
>> + g_value_set_boxed(value, vnc->priv->vncgrabseq);
>> + break;
>>
>
> Honestly I don't know what does this one do. Could you please explain?
>
>> default:
>> G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
>> break;
>> @@ -241,6 +248,9 @@ vnc_display_set_property (GObject *object,
>> case PROP_DEPTH:
>> vnc_display_set_depth (vnc, g_value_get_enum (value));
>> break;
>> + case PROP_GRAB_KEYS:
>> + vnc_display_set_grab_keys(vnc, g_value_get_boxed(value));
>> + break;
>>
>
> Same as above.
Properties are a feature that is nice for non-C languages using
glib. It lets people write bindings to enable code like
vnc.grab_keys = [ gtk.keysyms.Control_L ]
instead of having to invoke
vnc.set_grab_keys([ gtk.keysyms.Control_L ])
functionally both end up doing the same thing though!
>
>> default:
>> G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
>> break;
>> @@ -673,6 +683,37 @@ static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
>> return TRUE;
>> }
>>
>> +
>> +static gboolean check_for_grab_key(GtkWidget *widget, int type, int keyval)
>> +{
>> + VncDisplayPrivate *priv = VNC_DISPLAY(widget)->priv;
>> + int i;
>> +
>> + if (!priv->vncgrabseq->nkeysyms)
>> + return FALSE;
>> +
>> + if (type == GDK_KEY_RELEASE) {
>> + /* Any key release resets the whole grab sequence */
>> + memset(priv->vncactiveseq, 0,
>> + sizeof(gboolean)*priv->vncgrabseq->nkeysyms);
>>
>
> Resets the whole grab sequence? Shouldn't it remove only the keysym
> that's currently being pressed? But this is OK. This should work as well.
The problem I saw was that if you did a sequence of
Press(ctrl)
Press(f)
Release(f)
Press(alt)
then it would trigger the Ctrl-Alt grab sequence. IMHO it should
only trigger the grab sequence if you immediately press the
required sequence with no other key press/release in between
eg only allow
Press(ctrl)
Press(alt)
or
Press(alt)
Press(ctrl)
Thanks for your additional review !
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]