Re: [Spice-devel] 0001-a patch for syncing keyboard lock status

2014-04-02 Thread Jonathon Jongsma
How about this alternative approach?  It introduces a new central keyboard
monitor object which can keep the registered input channels in sync with the
client keyboard state. This object has an 'override-guest-modifiers' property
which controls whether it will connect to the 'inputs-modifiers' signal on the
inputs channels and override detected changes on the guest with the current
state of the client modifiers. This is the core functionality introduced by the
previous patch, but it is done here in a way that guarantees that the signal
handler is only triggered once. This property is enabled by default.

[PATCH 1/2] Ensure keyboard modifiers are synchronized properly
[PATCH 2/2] Use GdkKeymap to listen for keyboard modifier changes
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] 0001-a patch for syncing keyboard lock status

2014-03-31 Thread Jonathon Jongsma
Fair enough, my patch isn't exactly the same as yours, but 
sync_keyboard_lock_modifiers() could certainly be changed to check whether the 
keyboard modifiers had changed before sending down a new value.  

But there's still a problem with this approach. There can be multiple 
SpiceDisplay widgets associated with each input channel object (and in 
virt-viewer, there are regularly 4 display objects associated with each input 
channel). So I don't think that the SpiceDisplay is the right object to be 
responsible for this functionality. Otherwise when the inputs-modifiers signal 
is triggered, 4 handlers will be triggered in sequence, and they will all send 
messages to the spice server. In my testing, the act of sending rapid-fire 
modifier updates messages to the spice server seemed to cause problems.  So if 
we do want this functionality, it should probably live somewhere other than 
inside SpiceDisplay so that we can guarantee that the handler will only be 
triggered once. 

Jonathon



- Original Message -
 From: longguang.yue bigclo...@163.com
 To: Jonathon Jongsma jjong...@redhat.com
 Cc: spice-devel@lists.freedesktop.org
 Sent: Thursday, March 27, 2014 8:41:07 PM
 Subject: Re:Re: [Spice-devel] 0001-a patch for syncing keyboard lock status
 
 that is not enough.
 in that case server and client will keep syncing lock status all the time.
  
  
 we have to judge if two ends are identical already.
 my patch avoid modifying old functions, but  for the sake of brevity, we have
 to modify old functions.
 sync_keyboard_lock_modifiers and where it emits inputs-modifiers sginal.
  
 thanks
 
 
 
 
  
 
 At 2014-03-28 00:31:32,Jonathon Jongsma jjong...@redhat.com wrote:
 Thank you for the additional details.  I can indeed reproduce the issue
 here.  However, my comments below still stand.  You can essentially replace
 your entire patch with the following and it should behave exactly the same
 (and has the advantage of also building on windows):
 
 
 diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
 index f5adf66..9d1db6e 100644
 --- a/gtk/spice-widget.c
 +++ b/gtk/spice-widget.c
 @@ -2412,6 +2412,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, inputs-modifiers,
 G_CALLBACK(sync_keyboard_lock_modifiers), display);
  spice_channel_connect(channel);
  sync_keyboard_lock_modifiers(display);
  return;
 
 
 However, I still need to look into the details a bit more to see if this is
 really the right way to handle this particular bug.
 
 Jonathon
 
 
 
 - Original Message -
  From: longguang.yue bigclo...@163.com
  To: Jonathon Jongsma jjong...@redhat.com
  Cc: spice-devel@lists.freedesktop.org
  Sent: Thursday, March 27, 2014 9:05:19 AM
  Subject: Re:Re: [Spice-devel] 0001-a patch for syncing keyboard lock
  status
  
  my comment tells the reason.
  there are only  one or two oppotunity to sync lock status.
  when channel_new and windows get focus.  but  some use cases do not
  encounter
  the latter one, because they use spice
  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.
  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.
   
  reproduct steps:  require spice window maxmized when connect to vm.
  1. start vm
  2.launch remote-viewer (window maxmized)  right after start vm. let
  suppose
  CAPLK is down
  3.press CAPLK(CAPLK=1)
  4. wait vm finish start up . login in vm and edit a file, you will see all
  characters is small-capital-contrary.
   
  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.
  sync_keyboard_lock_modifiers does not make sure that lock status is
  identical
  after vm started.
   
  thanks
  
  
  
  At 2014-03-27 05:15:27,Jonathon Jongsma jjong...@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@gmail.com
   Date: Wed, 26 Mar 2014

Re: [Spice-devel] 0001-a patch for syncing keyboard lock status

2014-03-27 Thread longguang.yue
my comment tells the reason.
there are only  one or two oppotunity to sync lock status.
when channel_new and windows get focus.  but  some use cases do not encounter 
the latter one, because they use spice
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.
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.
 
reproduct steps:  require spice window maxmized when connect to vm.
1. start vm
2.launch remote-viewer (window maxmized)  right after start vm. let suppose 
CAPLK is down
3.press CAPLK(CAPLK=1)
4. wait vm finish start up . login in vm and edit a file, you will see all 
characters is small-capital-contrary.
 
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.
sync_keyboard_lock_modifiers does not make sure that lock status is identical 
after vm started.
 
thanks



At 2014-03-27 05:15:27,Jonathon Jongsma jjong...@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@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 

Re: [Spice-devel] 0001-a patch for syncing keyboard lock status

2014-03-27 Thread longguang.yue
that is not enough.
in that case server and client will keep syncing lock status all the time.
 
 
we have to judge if two ends are identical already.
my patch avoid modifying old functions, but  for the sake of brevity, we have 
to modify old functions.
sync_keyboard_lock_modifiers and where it emits inputs-modifiers sginal.
 
thanks




 

At 2014-03-28 00:31:32,Jonathon Jongsma jjong...@redhat.com wrote:
Thank you for the additional details.  I can indeed reproduce the issue here.  
However, my comments below still stand.  You can essentially replace your 
entire patch with the following and it should behave exactly the same (and has 
the advantage of also building on windows):


diff --git a/gtk/spice-widget.c b/gtk/spice-widget.c
index f5adf66..9d1db6e 100644
--- a/gtk/spice-widget.c
+++ b/gtk/spice-widget.c
@@ -2412,6 +2412,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, inputs-modifiers, 
G_CALLBACK(sync_keyboard_lock_modifiers), display);
 spice_channel_connect(channel);
 sync_keyboard_lock_modifiers(display);
 return;


However, I still need to look into the details a bit more to see if this is 
really the right way to handle this particular bug.

Jonathon



- Original Message -
 From: longguang.yue bigclo...@163.com
 To: Jonathon Jongsma jjong...@redhat.com
 Cc: spice-devel@lists.freedesktop.org
 Sent: Thursday, March 27, 2014 9:05:19 AM
 Subject: Re:Re: [Spice-devel] 0001-a patch for syncing keyboard lock status
 
 my comment tells the reason.
 there are only  one or two oppotunity to sync lock status.
 when channel_new and windows get focus.  but  some use cases do not encounter
 the latter one, because they use spice
 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.
 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.
  
 reproduct steps:  require spice window maxmized when connect to vm.
 1. start vm
 2.launch remote-viewer (window maxmized)  right after start vm. let suppose
 CAPLK is down
 3.press CAPLK(CAPLK=1)
 4. wait vm finish start up . login in vm and edit a file, you will see all
 characters is small-capital-contrary.
  
 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.
 sync_keyboard_lock_modifiers does not make sure that lock status is identical
 after vm started.
  
 thanks
 
 
 
 At 2014-03-27 05:15:27,Jonathon Jongsma jjong...@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@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

[Spice-devel] 0001-a patch for syncing keyboard lock status

2014-03-26 Thread bigclouds
thanks

0001-there-is-only-few-oppotunity-one-or-two-to-sync-keyb.patch
Description: Binary data
___
Spice-devel mailing list
Spice-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/spice-devel


Re: [Spice-devel] 0001-a patch for syncing keyboard lock status

2014-03-26 Thread Jonathon Jongsma
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@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);