aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1993-08-01 18:48:20 +0000
committerRichard M. Stallman1993-08-01 18:48:20 +0000
commit559f9d04059f2a4f45f12be775a144b29fbd34a1 (patch)
tree1d64e9766e70434a0e2386284817ce7be0392434
parent7f3e80e3b4ee05605a38e95e292796a1fea5a0cb (diff)
downloademacs-559f9d04059f2a4f45f12be775a144b29fbd34a1.tar.gz
emacs-559f9d04059f2a4f45f12be775a144b29fbd34a1.zip
(last_mouse_button): Renamed from button_up_button.
(last_mouse_x, last_mouse_y): Likewise. (button_down_time): Replaces button_up_time. (make_lispy_event): Set button_down_time. Detect and report double-down and double-drag events. (apply_modifiers_uncached): Put `double' or `triple' first. (read_key_sequence): Convert unbound double-drag/down to drag/down.
-rw-r--r--src/keyboard.c184
1 files changed, 99 insertions, 85 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index 5714ec6ac13..9614a967b89 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -2180,10 +2180,10 @@ static Lisp_Object button_down_location;
2180/* Information about the most recent up-going button event: Which 2180/* Information about the most recent up-going button event: Which
2181 button, what location, and what time. */ 2181 button, what location, and what time. */
2182 2182
2183static int button_up_button; 2183static int last_mouse_button;
2184static int button_up_x; 2184static int last_mouse_x;
2185static int button_up_y; 2185static int last_mouse_y;
2186static unsigned long button_up_time; 2186static unsigned long button_down_time;
2187 2187
2188/* The maximum time between clicks to make a double-click, 2188/* The maximum time between clicks to make a double-click,
2189 or Qnil to disable double-click detection, 2189 or Qnil to disable double-click detection,
@@ -2227,14 +2227,14 @@ make_lispy_event (event)
2227 c |= (event->modifiers 2227 c |= (event->modifiers
2228 & (meta_modifier | alt_modifier 2228 & (meta_modifier | alt_modifier
2229 | hyper_modifier | super_modifier)); 2229 | hyper_modifier | super_modifier));
2230 button_up_time = 0; 2230 button_down_time = 0;
2231 return c; 2231 return c;
2232 } 2232 }
2233 2233
2234 /* A function key. The symbol may need to have modifier prefixes 2234 /* A function key. The symbol may need to have modifier prefixes
2235 tacked onto it. */ 2235 tacked onto it. */
2236 case non_ascii_keystroke: 2236 case non_ascii_keystroke:
2237 button_up_time = 0; 2237 button_down_time = 0;
2238 return modify_event_symbol (XFASTINT (event->code), event->modifiers, 2238 return modify_event_symbol (XFASTINT (event->code), event->modifiers,
2239 Qfunction_key, 2239 Qfunction_key,
2240 lispy_function_keys, &func_key_syms, 2240 lispy_function_keys, &func_key_syms,
@@ -2248,6 +2248,7 @@ make_lispy_event (event)
2248 case scroll_bar_click: 2248 case scroll_bar_click:
2249 { 2249 {
2250 int button = XFASTINT (event->code); 2250 int button = XFASTINT (event->code);
2251 int is_double;
2251 Lisp_Object position; 2252 Lisp_Object position;
2252 Lisp_Object *start_pos_ptr; 2253 Lisp_Object *start_pos_ptr;
2253 Lisp_Object start_pos; 2254 Lisp_Object start_pos;
@@ -2339,10 +2340,34 @@ make_lispy_event (event)
2339 start_pos = *start_pos_ptr; 2340 start_pos = *start_pos_ptr;
2340 *start_pos_ptr = Qnil; 2341 *start_pos_ptr = Qnil;
2341 2342
2343 is_double = (button == last_mouse_button
2344 && XINT (event->x) == last_mouse_x
2345 && XINT (event->y) == last_mouse_y
2346 && button_down_time != 0
2347 && (EQ (Vdouble_click_time, Qt)
2348 || (INTEGERP (Vdouble_click_time)
2349 && ((int)(event->timestamp - button_down_time)
2350 < XINT (Vdouble_click_time)))));
2351 last_mouse_button = button;
2352 last_mouse_x = XINT (event->x);
2353 last_mouse_y = XINT (event->y);
2354
2342 /* If this is a button press, squirrel away the location, so 2355 /* If this is a button press, squirrel away the location, so
2343 we can decide later whether it was a click or a drag. */ 2356 we can decide later whether it was a click or a drag. */
2344 if (event->modifiers & down_modifier) 2357 if (event->modifiers & down_modifier)
2345 *start_pos_ptr = Fcopy_alist (position); 2358 {
2359 if (is_double)
2360 {
2361 double_click_count++;
2362 event->modifiers |= ((double_click_count > 2)
2363 ? triple_modifier
2364 : double_modifier);
2365 }
2366 else
2367 double_click_count = 1;
2368 button_down_time = event->timestamp;
2369 *start_pos_ptr = Fcopy_alist (position);
2370 }
2346 2371
2347 /* Now we're releasing a button - check the co-ordinates to 2372 /* Now we're releasing a button - check the co-ordinates to
2348 see if this was a click or a drag. */ 2373 see if this was a click or a drag. */
@@ -2372,33 +2397,16 @@ make_lispy_event (event)
2372 if (EQ (event->x, XCONS (down)->car) 2397 if (EQ (event->x, XCONS (down)->car)
2373 && EQ (event->y, XCONS (down)->cdr)) 2398 && EQ (event->y, XCONS (down)->cdr))
2374 { 2399 {
2375 if (button == button_up_button 2400 if (is_double && double_click_count > 1)
2376 && XINT (event->x) == button_up_x 2401 event->modifiers |= ((double_click_count > 2)
2377 && XINT (event->y) == button_up_y 2402 ? triple_modifier
2378 && button_up_time != 0 2403 : double_modifier);
2379 && (EQ (Vdouble_click_time, Qt)
2380 || (INTEGERP (Vdouble_click_time)
2381 && ((int)(event->timestamp - button_up_time)
2382 < XINT (Vdouble_click_time)))))
2383 {
2384 double_click_count++;
2385 event->modifiers |= ((double_click_count > 2)
2386 ? triple_modifier
2387 : double_modifier);
2388 }
2389 else 2404 else
2390 { 2405 event->modifiers |= click_modifier;
2391 double_click_count = 1;
2392 event->modifiers |= click_modifier;
2393 }
2394 button_up_button = button;
2395 button_up_x = XINT (event->x);
2396 button_up_y = XINT (event->y);
2397 button_up_time = event->timestamp;
2398 } 2406 }
2399 else 2407 else
2400 { 2408 {
2401 button_up_time = 0; 2409 button_down_time = 0;
2402 event->modifiers |= drag_modifier; 2410 event->modifiers |= drag_modifier;
2403 } 2411 }
2404 } 2412 }
@@ -2658,10 +2666,10 @@ apply_modifiers_uncached (modifiers, base, base_len)
2658 if (modifiers & meta_modifier) { *p++ = 'M'; *p++ = '-'; } 2666 if (modifiers & meta_modifier) { *p++ = 'M'; *p++ = '-'; }
2659 if (modifiers & shift_modifier) { *p++ = 'S'; *p++ = '-'; } 2667 if (modifiers & shift_modifier) { *p++ = 'S'; *p++ = '-'; }
2660 if (modifiers & super_modifier) { *p++ = 's'; *p++ = '-'; } 2668 if (modifiers & super_modifier) { *p++ = 's'; *p++ = '-'; }
2661 if (modifiers & down_modifier) { strcpy (p, "down-"); p += 5; }
2662 if (modifiers & drag_modifier) { strcpy (p, "drag-"); p += 5; }
2663 if (modifiers & double_modifier) { strcpy (p, "double-"); p += 7; } 2669 if (modifiers & double_modifier) { strcpy (p, "double-"); p += 7; }
2664 if (modifiers & triple_modifier) { strcpy (p, "triple-"); p += 7; } 2670 if (modifiers & triple_modifier) { strcpy (p, "triple-"); p += 7; }
2671 if (modifiers & down_modifier) { strcpy (p, "down-"); p += 5; }
2672 if (modifiers & drag_modifier) { strcpy (p, "drag-"); p += 5; }
2665 /* The click modifier is denoted by the absence of other modifiers. */ 2673 /* The click modifier is denoted by the absence of other modifiers. */
2666 2674
2667 *p = '\0'; 2675 *p = '\0';
@@ -4064,65 +4072,71 @@ read_key_sequence (keybuf, bufsize, prompt)
4064 Lisp_Object breakdown = parse_modifiers (head); 4072 Lisp_Object breakdown = parse_modifiers (head);
4065 int modifiers = XINT (XCONS (XCONS (breakdown)->cdr)->car); 4073 int modifiers = XINT (XCONS (XCONS (breakdown)->cdr)->car);
4066 4074
4067 /* We drop unbound `down-' events altogether. */ 4075 /* Attempt to reduce an unbound mouse event to a simpler
4068 if (modifiers & down_modifier) 4076 event that is bound:
4077 Drags reduce to clicks.
4078 Double-clicks reduce to clicks.
4079 Triple-clicks reduce to double-clicks, then to clicks.
4080 Down-clicks are eliminated.
4081 Double-downs reduce to downs, then are eliminated.
4082 Triple-downs reduce to double-downs, then to downs,
4083 then are eliminated. */
4084 if (modifiers & (down_modifier | drag_modifier
4085 | double_modifier | triple_modifier))
4069 { 4086 {
4070 /* Dispose of this event by simply jumping back to 4087 while (modifiers & (down_modifier | drag_modifier
4071 replay_key, to get another event. 4088 | double_modifier | triple_modifier))
4072
4073 Note that if this event came from mock input,
4074 then just jumping back to replay_key will just
4075 hand it to us again. So we have to wipe out any
4076 mock input.
4077
4078 We could delete keybuf[t] and shift everything
4079 after that to the left by one spot, but we'd also
4080 have to fix up any variable that points into
4081 keybuf, and shifting isn't really necessary
4082 anyway.
4083
4084 Adding prefixes for non-textual mouse clicks
4085 creates two characters of mock input, and both
4086 must be thrown away. If we're only looking at
4087 the prefix now, we can just jump back to
4088 replay_key. On the other hand, if we've already
4089 processed the prefix, and now the actual click
4090 itself is giving us trouble, then we've lost the
4091 state of the keymaps we want to backtrack to, and
4092 we need to replay the whole sequence to rebuild
4093 it.
4094
4095 Beyond that, only function key expansion could
4096 create more than two keys, but that should never
4097 generate mouse events, so it's okay to zero
4098 mock_input in that case too.
4099
4100 Isn't this just the most wonderful code ever? */
4101 if (t == last_real_key_start)
4102 {
4103 mock_input = 0;
4104 goto replay_key;
4105 }
4106 else
4107 {
4108 mock_input = last_real_key_start;
4109 goto replay_sequence;
4110 }
4111 }
4112
4113 /* We turn unbound `drag-' events into `click-'
4114 events, if the click would be bound. */
4115 else if (modifiers & (drag_modifier | double_modifier
4116 | triple_modifier))
4117 {
4118 while (modifiers & (drag_modifier | double_modifier
4119 | triple_modifier))
4120 { 4089 {
4121 Lisp_Object new_head, new_click; 4090 Lisp_Object new_head, new_click;
4122 if (modifiers & triple_modifier) 4091 if (modifiers & triple_modifier)
4123 modifiers ^= (double_modifier | triple_modifier); 4092 modifiers ^= (double_modifier | triple_modifier);
4124 else 4093 else if (modifiers & (drag_modifier | double_modifier))
4125 modifiers &= ~(drag_modifier | double_modifier); 4094 modifiers &= ~(drag_modifier | double_modifier);
4095 else
4096 {
4097 /* Dispose of this `down' event by simply jumping
4098 back to replay_key, to get another event.
4099
4100 Note that if this event came from mock input,
4101 then just jumping back to replay_key will just
4102 hand it to us again. So we have to wipe out any
4103 mock input.
4104
4105 We could delete keybuf[t] and shift everything
4106 after that to the left by one spot, but we'd also
4107 have to fix up any variable that points into
4108 keybuf, and shifting isn't really necessary
4109 anyway.
4110
4111 Adding prefixes for non-textual mouse clicks
4112 creates two characters of mock input, and both
4113 must be thrown away. If we're only looking at
4114 the prefix now, we can just jump back to
4115 replay_key. On the other hand, if we've already
4116 processed the prefix, and now the actual click
4117 itself is giving us trouble, then we've lost the
4118 state of the keymaps we want to backtrack to, and
4119 we need to replay the whole sequence to rebuild
4120 it.
4121
4122 Beyond that, only function key expansion could
4123 create more than two keys, but that should never
4124 generate mouse events, so it's okay to zero
4125 mock_input in that case too.
4126
4127 Isn't this just the most wonderful code ever? */
4128 if (t == last_real_key_start)
4129 {
4130 mock_input = 0;
4131 goto replay_key;
4132 }
4133 else
4134 {
4135 mock_input = last_real_key_start;
4136 goto replay_sequence;
4137 }
4138 }
4139
4126 new_head = 4140 new_head =
4127 apply_modifiers (modifiers, XCONS (breakdown)->car); 4141 apply_modifiers (modifiers, XCONS (breakdown)->car);
4128 new_click = 4142 new_click =