<div style="line-height:1.7;color:#000000;font-size:14px;font-family:arial"><div>my comment tells the reason.</div><div>there are only one or two oppotunity to sync lock status. </div><div>when channel_new and windows get focus. but some use cases do not encounter the latter one, because they use spice</div><div>as desktop(maxmized when launched), no get-focus event will be catched, so if after input channel created but lock status is not identical , in this case lock status will never been corrected. you have to shutdown remote-viewer, and start it again.</div><div>like you press keyboard during your computer start up, all the keyboard press event will be dropped . because OS is not ready and can not responde to keyboard interrupt. so there is a gap, you really press keyboard, but the event is dropped.</div><div> </div><div>reproduct steps: require spice window maxmized when connect to vm.</div><div>1. start vm</div><div>2.launch remote-viewer (window maxmized) right after start vm. let suppose CAPLK is down</div><div>3.press CAPLK(CAPLK=1)</div><div>4. wait vm finish start up . login in vm and edit a file, you will see all characters is small-capital-contrary.</div><div> </div><div>i am not sure if you can reproduct it, the key point is that there is a gap allow you to change lock status, but the changing is after channel connection and before vm can process interrupt.</div><div>sync_keyboard_lock_modifiers does not make sure that lock status is identical after vm started.</div><div> </div><div>thanks</div><div></div><div id="divNeteaseMailCard"></div><div><br></div><pre><br>At 2014-03-27 05:15:27,"Jonathon Jongsma" <jjongsma@redhat.com> wrote:
>Hello,
>
>Thanks for the patch. First, a general comment: it's helpful if you
>write a few more details in the commit message. I can't tell exactly
>what bug you are trying to fix, what conditions trigger the bug, or what
>the expected behavior is. Knowing these things will make it easier to
>review the patch.
>
>More detailed comments below.
>
>
>On Wed, 2014-03-26 at 23:10 +0800, bigclouds wrote:
>
>
>> From cdfcb3083825836e69f3e8d9ef18323117e43015 Mon Sep 17 00:00:00 2001
>> From: "longguang.yue" <longguang.yue@gmail.com>
>> Date: Wed, 26 Mar 2014 22:28:55 +0800
>> Subject: [PATCH] there is only few oppotunity (one or two) to sync keybloard
>> lock status, in case lock status is not corrected after
>> that it will never be synced if window is maximized
>>
>> ---
>> gtk/channel-inputs.c | 15 ++++++++++++++-
>> gtk/channel-inputs.h | 1 +
>> gtk/spice-widget.c | 28 +++++++++++++++++++++++++++-
>> 3 files changed, 42 insertions(+), 2 deletions(-)
>>
>> diff --git a/gtk/channel-inputs.c b/gtk/channel-inputs.c
>> index 8a726e0..1a3e584 100644
>> --- a/gtk/channel-inputs.c
>> +++ b/gtk/channel-inputs.c
>> @@ -63,7 +63,7 @@ enum {
>> /* Signals */
>> enum {
>> SPICE_INPUTS_MODIFIERS,
>> -
>> + SPICE_DISPLAY_MODIFIER_SYNC,
>> SPICE_INPUTS_LAST_SIGNAL,
>> };
>>
>> @@ -142,6 +142,17 @@ static void spice_inputs_channel_class_init(SpiceInputsChannelClass *klass)
>> g_cclosure_marshal_VOID__VOID,
>> G_TYPE_NONE,
>> 0);
>> + /*sync led status in case they are not identical after channel connection*/
>> + signals[SPICE_DISPLAY_MODIFIER_SYNC] =
>> + g_signal_new("modifier-sync",
>> + G_OBJECT_CLASS_TYPE(gobject_class),
>> + G_SIGNAL_RUN_FIRST|G_SIGNAL_ACTION,
>> + G_STRUCT_OFFSET(SpiceInputsChannelClass, modifier_sync),
>> + NULL, NULL,
>> + g_cclosure_marshal_VOID__UINT,
>> + G_TYPE_NONE,
>> + 1,
>> + G_TYPE_INT);
>>
>> g_type_class_add_private(klass, sizeof(SpiceInputsChannelPrivate));
>> channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
>> @@ -262,6 +273,8 @@ static void inputs_handle_modifiers(SpiceChannel *channel, SpiceMsgIn *in)
>>
>> c->modifiers = modifiers->modifiers;
>> emit_main_context(channel, SPICE_INPUTS_MODIFIERS);
>> + SPICE_DEBUG("get modifier key=0x%x, channelObject=%p", modifiers->modifiers, channel);
>
>Incorrect indentation: use spaces instead of tabs
>
>> + g_signal_emit(channel, signals[SPICE_DISPLAY_MODIFIER_SYNC], 0, modifiers->modifiers);
>
>This code is running within a coroutine context, and emitting the
>signal within the coroutine context is not necessarily safe. Note that
>just before your additions, we emit another signal, but we emit it in
>the main context (by calling emit_main_context()) rather than within
>the coroutine context.
>
>But more fundamentally, I'm struggling to see why this new signal is
>necessary, since we're already emitting the 'inputs-modifiers' signal in
>the exact same place. Why couldn't you simply use that signal instead?
>
>
>>
>> }
>>
>> /* coroutine context */
>> diff --git a/gtk/channel-inputs.h b/gtk/channel-inputs.h
>> index 3179a76..83fce65 100644
>> --- a/gtk/channel-inputs.h
>> +++ b/gtk/channel-inputs.h
>> @@ -64,6 +64,7 @@ struct _SpiceInputsChannelClass {
>>
>> /* signals */
>> void (*inputs_modifiers)(SpiceChannel *channel);
>> + void (*modifier_sync)(SpiceChannel *channel, uint32_t v);
>>
>>
>
>improper indentation again, but this function pointer is probably not
>necessary as mentioned above.
>
>>
>> /*< private >*/
>> /* Do not add fields to this struct */
>> diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
>> index 0e4a0de..40dfbfb 100644
>> --- a/gtk/spice-widget.c
>> +++ b/gtk/spice-widget.c
>> @@ -135,7 +135,7 @@ static void sync_keyboard_lock_modifiers(SpiceDisplay *display);
>> static void cursor_invalidate(SpiceDisplay *display);
>> static void update_area(SpiceDisplay *display, gint x, gint y, gint width, gint height);
>> static void release_keys(SpiceDisplay *display);
>> -
>> +static void modifier_sync(SpiceChannel *channel, uint32_t v, SpiceDisplay *display);
>> /* ---------------------------------------------------------------- */
>>
>> static void spice_display_get_property(GObject *object,
>> @@ -2410,6 +2410,7 @@ static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data)
>>
>> if (SPICE_IS_INPUTS_CHANNEL(channel)) {
>> d->inputs = SPICE_INPUTS_CHANNEL(channel);
>> + g_signal_connect(channel, "modifier-sync", G_CALLBACK(modifier_sync), display);
>
>So what you're doing here is connecting to a signal that is emitted
>whenever the guest reports that its modifiers have changed. In response
>to this signal, you call a function which then resets the modifiers of
>the guest to be equal to the modifiers on the host. Is that what you
>intended?
>
>
>>
>> spice_channel_connect(channel);
>> sync_keyboard_lock_modifiers(display);
>> return;
>> @@ -2686,3 +2687,28 @@ static void sync_keyboard_lock_modifiers(SpiceDisplay *display)
>> g_warning("sync_keyboard_lock_modifiers not implemented");
>> }
>> #endif // HAVE_X11_XKBLIB_H
>> +
>> +static void modifier_sync(SpiceChannel *channel, uint32_t v, SpiceDisplay *display)
>> +{
>> + Display *x_display;
>> + SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
>> + guint32 modifiers;
>> + GdkWindow *w;
>> +
>> + if (d->disable_inputs)
>> + return;
>> +
>> + w = gtk_widget_get_parent_window(GTK_WIDGET(display));
>> + if (w == NULL) /* it can happen if the display is not yet shown */
>> + return;
>> +
>> + x_display = GDK_WINDOW_XDISPLAY(w);
>> + #if HAVE_X11_XKBLIB_H
>> + modifiers = get_keyboard_lock_modifiers(x_display);
>> + #elif defined (WIN32)
>> + modifiers = get_keyboard_lock_modifiers();
>> + #endif
>> + SPICE_DEBUG("modifier_sync 0x%x, 0x%x", modifiers, v);
>> + if(modifiers != v && d->inputs)
>> + spice_inputs_set_key_locks(d->inputs, modifiers);
>> +}
>> \ No newline at end of file
>> --
>> 1.7.11.msysgit.1
>
>
>This function looks almost identical to sync_keyboard_lock_modifiers(),
>the main difference is that it won't work on windows (e.g. Display*
>doesn't exist, etc). Is there a reason that you didn't simply use the
>existing function instead?
>
>Jonathon
>
>_______________________________________________
>Spice-devel mailing list
>Spice-devel@lists.freedesktop.org
>http://lists.freedesktop.org/mailman/listinfo/spice-devel
</pre></div><br><br><span title="neteasefooter"><span id="netease_mail_footer"></span></span>