summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdk/win32/gdkevents-win32.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index eed1bc6e5d..82e9368fd5 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -136,6 +136,8 @@ static UINT sync_timer = 0;
static int debug_indent = 0;
+static int both_shift_pressed[2]; /* to store keycodes for shift keys */
+
static void
assign_object (gpointer lhsp,
gpointer rhs)
@@ -2110,6 +2112,38 @@ gdk_event_translate (MSG *msg,
fill_key_event_string (event);
+ /* Only one release key event is fired when both shift keys are pressed together
+ and then released. In order to send the missing event, press events for shift
+ keys are recorded and sent together when the release event occurs.
+ Other modifiers (e.g. ctrl, alt) don't have this problem. */
+ if (msg->message == WM_KEYDOWN && msg->wParam == VK_SHIFT)
+ {
+ int pressed_shift = msg->lParam & 0xffffff; /* mask shift modifier */
+ if (both_shift_pressed[0] == 0)
+ both_shift_pressed[0] = pressed_shift;
+ else if (both_shift_pressed[0] != pressed_shift)
+ both_shift_pressed[1] = pressed_shift;
+ }
+
+ if (msg->message == WM_KEYUP && msg->wParam == VK_SHIFT)
+ {
+ if (both_shift_pressed[0] != 0 && both_shift_pressed[1] != 0)
+ {
+ gint tmp_retval;
+ MSG fake_release = *msg;
+ int pressed_shift = msg->lParam & 0xffffff;
+
+ if (both_shift_pressed[0] == pressed_shift)
+ fake_release.lParam = both_shift_pressed[1];
+ else
+ fake_release.lParam = both_shift_pressed[0];
+
+ both_shift_pressed[0] = both_shift_pressed[1] = 0;
+ gdk_event_translate (&fake_release, &tmp_retval);
+ }
+ both_shift_pressed[0] = both_shift_pressed[1] = 0;
+ }
+
/* Reset MOD1_MASK if it is the Alt key itself */
if (msg->wParam == VK_MENU)
event->key.state &= ~GDK_MOD1_MASK;