diff options
| author | Karl Heuer | 1996-05-25 17:49:03 +0000 |
|---|---|---|
| committer | Karl Heuer | 1996-05-25 17:49:03 +0000 |
| commit | 84fb1139e681c525a88df509404422615ed7ad86 (patch) | |
| tree | 3291be5eb5181e552573a0b8922032ca1d84aa84 /src | |
| parent | 063b17e5dfe6c80a8a0154e7ad4b5d1063288cdd (diff) | |
| download | emacs-84fb1139e681c525a88df509404422615ed7ad86.tar.gz emacs-84fb1139e681c525a88df509404422615ed7ad86.zip | |
(Vwin32_mouse_move_interval): New lisp variable.
(syms_of_win32fns): Add Vwin32_mouse_move_interval to syms.
(saved_mouse_msg): Renamed to saved_mouse_button_msg.
(timer_id): Renamed to mouse_button_timer.
(saved_mouse_move_msg, mouse_move_timer): New variables.
(win_msg_worker): Delete WM_TIMER code.
(win32_wnd_proc): Handle WM_TIMER events here. Use separate timers
for mouse down and mouse move (including scroll bar drag) events.
Add new handling code for WM_VSCROLL and WM_MOUSEMOVE events.
Only filter WM_MOUSEMOVE events when a button is held down.
Always pass on message to DefWindowProc after calling
TranslateMessage. Reset keyboard modifiers when losing focus.
(win32_wnd_proc): When passing modifier keystrokes back
to Windows, invoke TranslateMessage on them.
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32fns.c | 166 |
1 files changed, 113 insertions, 53 deletions
diff --git a/src/w32fns.c b/src/w32fns.c index 9a1a4cae213..b205baf4bbc 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -64,6 +64,10 @@ Lisp_Object Vwin32_enable_palette; | |||
| 64 | be converted to a middle button down event. */ | 64 | be converted to a middle button down event. */ |
| 65 | Lisp_Object Vwin32_mouse_button_tolerance; | 65 | Lisp_Object Vwin32_mouse_button_tolerance; |
| 66 | 66 | ||
| 67 | /* Minimum interval between mouse movement (and scroll bar drag) | ||
| 68 | events that are passed on to the event loop. */ | ||
| 69 | Lisp_Object Vwin32_mouse_move_interval; | ||
| 70 | |||
| 67 | /* The name we're using in resource queries. */ | 71 | /* The name we're using in resource queries. */ |
| 68 | Lisp_Object Vx_resource_name; | 72 | Lisp_Object Vx_resource_name; |
| 69 | 73 | ||
| @@ -157,8 +161,13 @@ Lisp_Object Qdisplay; | |||
| 157 | #define RMOUSE 4 | 161 | #define RMOUSE 4 |
| 158 | 162 | ||
| 159 | static int button_state = 0; | 163 | static int button_state = 0; |
| 160 | static Win32Msg saved_mouse_msg; | 164 | static Win32Msg saved_mouse_button_msg; |
| 161 | static unsigned timer_id; /* non-zero when timer is active */ | 165 | static unsigned mouse_button_timer; /* non-zero when timer is active */ |
| 166 | static Win32Msg saved_mouse_move_msg; | ||
| 167 | static unsigned mouse_move_timer; | ||
| 168 | |||
| 169 | #define MOUSE_BUTTON_ID 1 | ||
| 170 | #define MOUSE_MOVE_ID 2 | ||
| 162 | 171 | ||
| 163 | /* The below are defined in frame.c. */ | 172 | /* The below are defined in frame.c. */ |
| 164 | extern Lisp_Object Qheight, Qminibuffer, Qname, Qonly, Qwidth; | 173 | extern Lisp_Object Qheight, Qminibuffer, Qname, Qonly, Qwidth; |
| @@ -2841,14 +2850,6 @@ win_msg_worker (dw) | |||
| 2841 | { | 2850 | { |
| 2842 | switch (msg.message) | 2851 | switch (msg.message) |
| 2843 | { | 2852 | { |
| 2844 | case WM_TIMER: | ||
| 2845 | if (saved_mouse_msg.msg.hwnd) | ||
| 2846 | { | ||
| 2847 | post_msg (&saved_mouse_msg); | ||
| 2848 | saved_mouse_msg.msg.hwnd = 0; | ||
| 2849 | } | ||
| 2850 | timer_id = 0; | ||
| 2851 | break; | ||
| 2852 | case WM_EMACS_CREATEWINDOW: | 2853 | case WM_EMACS_CREATEWINDOW: |
| 2853 | win32_createwindow ((struct frame *) msg.wParam); | 2854 | win32_createwindow ((struct frame *) msg.wParam); |
| 2854 | PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0); | 2855 | PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0); |
| @@ -2888,7 +2889,8 @@ win32_wnd_proc (hwnd, msg, wParam, lParam) | |||
| 2888 | LRESULT ret = 1; | 2889 | LRESULT ret = 1; |
| 2889 | struct win32_display_info *dpyinfo = &one_win32_display_info; | 2890 | struct win32_display_info *dpyinfo = &one_win32_display_info; |
| 2890 | Win32Msg wmsg; | 2891 | Win32Msg wmsg; |
| 2891 | 2892 | int windows_translate; | |
| 2893 | |||
| 2892 | switch (msg) | 2894 | switch (msg) |
| 2893 | { | 2895 | { |
| 2894 | case WM_ERASEBKGND: | 2896 | case WM_ERASEBKGND: |
| @@ -2930,25 +2932,26 @@ win32_wnd_proc (hwnd, msg, wParam, lParam) | |||
| 2930 | record_keydown (wParam, lParam); | 2932 | record_keydown (wParam, lParam); |
| 2931 | 2933 | ||
| 2932 | wParam = map_keypad_keys (wParam, lParam); | 2934 | wParam = map_keypad_keys (wParam, lParam); |
| 2933 | 2935 | ||
| 2936 | windows_translate = 0; | ||
| 2934 | switch (wParam) { | 2937 | switch (wParam) { |
| 2935 | case VK_LWIN: | 2938 | case VK_LWIN: |
| 2936 | case VK_RWIN: | 2939 | case VK_RWIN: |
| 2937 | case VK_APPS: | 2940 | case VK_APPS: |
| 2938 | /* More support for these keys will likely be necessary. */ | 2941 | /* More support for these keys will likely be necessary. */ |
| 2939 | if (!NILP (Vwin32_pass_optional_keys_to_system)) | 2942 | if (!NILP (Vwin32_pass_optional_keys_to_system)) |
| 2940 | goto dflt; | 2943 | windows_translate = 1; |
| 2941 | break; | 2944 | break; |
| 2942 | case VK_MENU: | 2945 | case VK_MENU: |
| 2943 | if (NILP (Vwin32_pass_alt_to_system)) | 2946 | if (NILP (Vwin32_pass_alt_to_system)) |
| 2944 | return 0; | 2947 | return 0; |
| 2945 | else | 2948 | windows_translate = 1; |
| 2946 | goto dflt; | 2949 | break; |
| 2947 | case VK_CONTROL: | 2950 | case VK_CONTROL: |
| 2948 | case VK_CAPITAL: | 2951 | case VK_CAPITAL: |
| 2949 | case VK_SHIFT: | 2952 | case VK_SHIFT: |
| 2950 | /* Pass on to Windows. */ | 2953 | windows_translate = 1; |
| 2951 | goto dflt; | 2954 | break; |
| 2952 | default: | 2955 | default: |
| 2953 | /* If not defined as a function key, change it to a WM_CHAR message. */ | 2956 | /* If not defined as a function key, change it to a WM_CHAR message. */ |
| 2954 | if (lispy_function_keys[wParam] == 0) | 2957 | if (lispy_function_keys[wParam] == 0) |
| @@ -2956,6 +2959,15 @@ win32_wnd_proc (hwnd, msg, wParam, lParam) | |||
| 2956 | break; | 2959 | break; |
| 2957 | } | 2960 | } |
| 2958 | 2961 | ||
| 2962 | if (windows_translate) | ||
| 2963 | { | ||
| 2964 | MSG winmsg = { hwnd, msg, wParam, lParam, 0, {0,0} }; | ||
| 2965 | |||
| 2966 | winmsg.time = GetMessageTime (); | ||
| 2967 | TranslateMessage (&winmsg); | ||
| 2968 | goto dflt; | ||
| 2969 | } | ||
| 2970 | |||
| 2959 | /* Fall through */ | 2971 | /* Fall through */ |
| 2960 | 2972 | ||
| 2961 | case WM_SYSCHAR: | 2973 | case WM_SYSCHAR: |
| @@ -3003,10 +3015,10 @@ win32_wnd_proc (hwnd, msg, wParam, lParam) | |||
| 3003 | 3015 | ||
| 3004 | if (button_state & other) | 3016 | if (button_state & other) |
| 3005 | { | 3017 | { |
| 3006 | if (timer_id) | 3018 | if (mouse_button_timer) |
| 3007 | { | 3019 | { |
| 3008 | KillTimer (NULL, timer_id); | 3020 | KillTimer (hwnd, mouse_button_timer); |
| 3009 | timer_id = 0; | 3021 | mouse_button_timer = 0; |
| 3010 | 3022 | ||
| 3011 | /* Generate middle mouse event instead. */ | 3023 | /* Generate middle mouse event instead. */ |
| 3012 | msg = WM_MBUTTONDOWN; | 3024 | msg = WM_MBUTTONDOWN; |
| @@ -3023,25 +3035,25 @@ win32_wnd_proc (hwnd, msg, wParam, lParam) | |||
| 3023 | else | 3035 | else |
| 3024 | { | 3036 | { |
| 3025 | /* Flush out saved message. */ | 3037 | /* Flush out saved message. */ |
| 3026 | post_msg (&saved_mouse_msg); | 3038 | post_msg (&saved_mouse_button_msg); |
| 3027 | } | 3039 | } |
| 3028 | wmsg.dwModifiers = win32_get_modifiers (); | 3040 | wmsg.dwModifiers = win32_get_modifiers (); |
| 3029 | my_post_msg (&wmsg, hwnd, msg, wParam, lParam); | 3041 | my_post_msg (&wmsg, hwnd, msg, wParam, lParam); |
| 3030 | 3042 | ||
| 3031 | /* Clear message buffer. */ | 3043 | /* Clear message buffer. */ |
| 3032 | saved_mouse_msg.msg.hwnd = 0; | 3044 | saved_mouse_button_msg.msg.hwnd = 0; |
| 3033 | } | 3045 | } |
| 3034 | else | 3046 | else |
| 3035 | { | 3047 | { |
| 3036 | /* Hold onto message for now. */ | 3048 | /* Hold onto message for now. */ |
| 3037 | timer_id = | 3049 | mouse_button_timer = |
| 3038 | SetTimer (NULL, 0, XINT (Vwin32_mouse_button_tolerance), NULL); | 3050 | SetTimer (hwnd, MOUSE_BUTTON_ID, XINT (Vwin32_mouse_button_tolerance), NULL); |
| 3039 | saved_mouse_msg.msg.hwnd = hwnd; | 3051 | saved_mouse_button_msg.msg.hwnd = hwnd; |
| 3040 | saved_mouse_msg.msg.message = msg; | 3052 | saved_mouse_button_msg.msg.message = msg; |
| 3041 | saved_mouse_msg.msg.wParam = wParam; | 3053 | saved_mouse_button_msg.msg.wParam = wParam; |
| 3042 | saved_mouse_msg.msg.lParam = lParam; | 3054 | saved_mouse_button_msg.msg.lParam = lParam; |
| 3043 | saved_mouse_msg.msg.time = GetMessageTime (); | 3055 | saved_mouse_button_msg.msg.time = GetMessageTime (); |
| 3044 | saved_mouse_msg.dwModifiers = win32_get_modifiers (); | 3056 | saved_mouse_button_msg.dwModifiers = win32_get_modifiers (); |
| 3045 | } | 3057 | } |
| 3046 | } | 3058 | } |
| 3047 | return 0; | 3059 | return 0; |
| @@ -3076,18 +3088,18 @@ win32_wnd_proc (hwnd, msg, wParam, lParam) | |||
| 3076 | else | 3088 | else |
| 3077 | { | 3089 | { |
| 3078 | /* Flush out saved message if necessary. */ | 3090 | /* Flush out saved message if necessary. */ |
| 3079 | if (saved_mouse_msg.msg.hwnd) | 3091 | if (saved_mouse_button_msg.msg.hwnd) |
| 3080 | { | 3092 | { |
| 3081 | post_msg (&saved_mouse_msg); | 3093 | post_msg (&saved_mouse_button_msg); |
| 3082 | } | 3094 | } |
| 3083 | } | 3095 | } |
| 3084 | wmsg.dwModifiers = win32_get_modifiers (); | 3096 | wmsg.dwModifiers = win32_get_modifiers (); |
| 3085 | my_post_msg (&wmsg, hwnd, msg, wParam, lParam); | 3097 | my_post_msg (&wmsg, hwnd, msg, wParam, lParam); |
| 3086 | 3098 | ||
| 3087 | /* Always clear message buffer and cancel timer. */ | 3099 | /* Always clear message buffer and cancel timer. */ |
| 3088 | saved_mouse_msg.msg.hwnd = 0; | 3100 | saved_mouse_button_msg.msg.hwnd = 0; |
| 3089 | KillTimer (NULL, timer_id); | 3101 | KillTimer (hwnd, mouse_button_timer); |
| 3090 | timer_id = 0; | 3102 | mouse_button_timer = 0; |
| 3091 | 3103 | ||
| 3092 | if (button_state == 0) | 3104 | if (button_state == 0) |
| 3093 | ReleaseCapture (); | 3105 | ReleaseCapture (); |
| @@ -3111,33 +3123,73 @@ win32_wnd_proc (hwnd, msg, wParam, lParam) | |||
| 3111 | my_post_msg (&wmsg, hwnd, msg, wParam, lParam); | 3123 | my_post_msg (&wmsg, hwnd, msg, wParam, lParam); |
| 3112 | return 0; | 3124 | return 0; |
| 3113 | 3125 | ||
| 3114 | #if 0 | 3126 | case WM_VSCROLL: |
| 3115 | case WM_MOUSEMOVE: | 3127 | case WM_MOUSEMOVE: |
| 3116 | /* Flush out saved message if necessary. */ | 3128 | if (XINT (Vwin32_mouse_move_interval) <= 0 |
| 3117 | if (saved_mouse_msg.msg.hwnd) | 3129 | || (msg == WM_MOUSEMOVE && button_state == 0)) |
| 3130 | { | ||
| 3131 | wmsg.dwModifiers = win32_get_modifiers (); | ||
| 3132 | my_post_msg (&wmsg, hwnd, msg, wParam, lParam); | ||
| 3133 | return 0; | ||
| 3134 | } | ||
| 3135 | |||
| 3136 | /* Hang onto mouse move and scroll messages for a bit, to avoid | ||
| 3137 | sending such events to Emacs faster than it can process them. | ||
| 3138 | If we get more events before the timer from the first message | ||
| 3139 | expires, we just replace the first message. */ | ||
| 3140 | |||
| 3141 | if (saved_mouse_move_msg.msg.hwnd == 0) | ||
| 3142 | mouse_move_timer = | ||
| 3143 | SetTimer (hwnd, MOUSE_MOVE_ID, XINT (Vwin32_mouse_move_interval), NULL); | ||
| 3144 | |||
| 3145 | /* Hold onto message for now. */ | ||
| 3146 | saved_mouse_move_msg.msg.hwnd = hwnd; | ||
| 3147 | saved_mouse_move_msg.msg.message = msg; | ||
| 3148 | saved_mouse_move_msg.msg.wParam = wParam; | ||
| 3149 | saved_mouse_move_msg.msg.lParam = lParam; | ||
| 3150 | saved_mouse_move_msg.msg.time = GetMessageTime (); | ||
| 3151 | saved_mouse_move_msg.dwModifiers = win32_get_modifiers (); | ||
| 3152 | |||
| 3153 | return 0; | ||
| 3154 | |||
| 3155 | case WM_TIMER: | ||
| 3156 | /* Flush out saved messages if necessary. */ | ||
| 3157 | if (wParam == mouse_button_timer) | ||
| 3118 | { | 3158 | { |
| 3119 | wmsg = saved_mouse_msg; | 3159 | if (saved_mouse_button_msg.msg.hwnd) |
| 3120 | my_post_msg (&wmsg, wmsg.msg.hwnd, wmsg.msg.message, | 3160 | { |
| 3121 | wmsg.msg.wParam, wmsg.msg.lParam); | 3161 | post_msg (&saved_mouse_button_msg); |
| 3162 | saved_mouse_button_msg.msg.hwnd = 0; | ||
| 3163 | } | ||
| 3164 | KillTimer (hwnd, mouse_button_timer); | ||
| 3165 | mouse_button_timer = 0; | ||
| 3166 | } | ||
| 3167 | else if (wParam == mouse_move_timer) | ||
| 3168 | { | ||
| 3169 | if (saved_mouse_move_msg.msg.hwnd) | ||
| 3170 | { | ||
| 3171 | post_msg (&saved_mouse_move_msg); | ||
| 3172 | saved_mouse_move_msg.msg.hwnd = 0; | ||
| 3173 | } | ||
| 3174 | KillTimer (hwnd, mouse_move_timer); | ||
| 3175 | mouse_move_timer = 0; | ||
| 3122 | } | 3176 | } |
| 3123 | wmsg.dwModifiers = win32_get_modifiers (); | ||
| 3124 | my_post_msg (&wmsg, hwnd, msg, wParam, lParam); | ||
| 3125 | |||
| 3126 | /* Always clear message buffer and cancel timer. */ | ||
| 3127 | saved_mouse_msg.msg.hwnd = 0; | ||
| 3128 | KillTimer (NULL, timer_id); | ||
| 3129 | timer_id = 0; | ||
| 3130 | |||
| 3131 | return 0; | 3177 | return 0; |
| 3132 | #endif | 3178 | |
| 3179 | case WM_NCACTIVATE: | ||
| 3180 | /* Windows doesn't send us focus messages when putting up and | ||
| 3181 | taking down a system popup dialog as for Ctrl-Alt-Del on Win95. | ||
| 3182 | The only indication we get that something happened is receiving | ||
| 3183 | this message afterwards. So this is a good time to reset our | ||
| 3184 | keyboard modifiers' state. */ | ||
| 3185 | reset_modifiers (); | ||
| 3186 | goto dflt; | ||
| 3133 | 3187 | ||
| 3188 | case WM_KILLFOCUS: | ||
| 3134 | case WM_SETFOCUS: | 3189 | case WM_SETFOCUS: |
| 3135 | reset_modifiers (); | 3190 | reset_modifiers (); |
| 3136 | case WM_MOUSEMOVE: | ||
| 3137 | case WM_MOVE: | 3191 | case WM_MOVE: |
| 3138 | case WM_SIZE: | 3192 | case WM_SIZE: |
| 3139 | case WM_KILLFOCUS: | ||
| 3140 | case WM_VSCROLL: | ||
| 3141 | case WM_SYSCOMMAND: | 3193 | case WM_SYSCOMMAND: |
| 3142 | case WM_COMMAND: | 3194 | case WM_COMMAND: |
| 3143 | wmsg.dwModifiers = win32_get_modifiers (); | 3195 | wmsg.dwModifiers = win32_get_modifiers (); |
| @@ -4927,6 +4979,14 @@ If both mouse buttons are depressed within this interval, a middle mouse\n\ | |||
| 4927 | button down event is generated instead."); | 4979 | button down event is generated instead."); |
| 4928 | XSETINT (Vwin32_mouse_button_tolerance, GetDoubleClickTime () / 2); | 4980 | XSETINT (Vwin32_mouse_button_tolerance, GetDoubleClickTime () / 2); |
| 4929 | 4981 | ||
| 4982 | DEFVAR_INT ("win32-mouse-move-interval", | ||
| 4983 | &Vwin32_mouse_move_interval, | ||
| 4984 | "Minimum interval between mouse move events.\n\ | ||
| 4985 | The value is the minimum time in milliseconds that must elapse between\n\ | ||
| 4986 | successive mouse move (or scroll bar drag) events before they are\n\ | ||
| 4987 | reported as lisp events."); | ||
| 4988 | XSETINT (Vwin32_mouse_move_interval, 50); | ||
| 4989 | |||
| 4930 | init_x_parm_symbols (); | 4990 | init_x_parm_symbols (); |
| 4931 | 4991 | ||
| 4932 | DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path, | 4992 | DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path, |