diff options
| author | Jan Djärv | 2007-01-08 17:56:31 +0000 |
|---|---|---|
| committer | Jan Djärv | 2007-01-08 17:56:31 +0000 |
| commit | 1c8591d04ca0c88d816e1498f058db7fe948fb63 (patch) | |
| tree | a3cfed52e85cf41ca326b172117723eaa5d31337 /src | |
| parent | af5debda9205ed0fe0c0d7cf523b503675afa261 (diff) | |
| download | emacs-1c8591d04ca0c88d816e1498f058db7fe948fb63.tar.gz emacs-1c8591d04ca0c88d816e1498f058db7fe948fb63.zip | |
New variable last_user_time.
(handle_one_xevent): Set last_user_time from events that have Time.
Set net_supported_window to 0 when reparented.
(wm_supports): New function.
(do_ewmh_fullscreen): Use wm_supports to check for _NET_WM_STATE.
(x_term_init): Initialize net_supported_atoms, nr_net_supported_atoms
and net_supported_window.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xterm.c | 173 |
1 files changed, 135 insertions, 38 deletions
diff --git a/src/xterm.c b/src/xterm.c index 0becc704a13..3b48caf0d36 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -277,6 +277,10 @@ static Lisp_Object last_mouse_scroll_bar; | |||
| 277 | 277 | ||
| 278 | static Time last_mouse_movement_time; | 278 | static Time last_mouse_movement_time; |
| 279 | 279 | ||
| 280 | /* Time for last user interaction as returned in X events. */ | ||
| 281 | |||
| 282 | static Time last_user_time; | ||
| 283 | |||
| 280 | /* Incremented by XTread_socket whenever it really tries to read | 284 | /* Incremented by XTread_socket whenever it really tries to read |
| 281 | events. */ | 285 | events. */ |
| 282 | 286 | ||
| @@ -5869,6 +5873,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 5869 | break; | 5873 | break; |
| 5870 | 5874 | ||
| 5871 | case SelectionNotify: | 5875 | case SelectionNotify: |
| 5876 | last_user_time = event.xselection.time; | ||
| 5872 | #ifdef USE_X_TOOLKIT | 5877 | #ifdef USE_X_TOOLKIT |
| 5873 | if (! x_window_to_frame (dpyinfo, event.xselection.requestor)) | 5878 | if (! x_window_to_frame (dpyinfo, event.xselection.requestor)) |
| 5874 | goto OTHER; | 5879 | goto OTHER; |
| @@ -5877,6 +5882,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 5877 | break; | 5882 | break; |
| 5878 | 5883 | ||
| 5879 | case SelectionClear: /* Someone has grabbed ownership. */ | 5884 | case SelectionClear: /* Someone has grabbed ownership. */ |
| 5885 | last_user_time = event.xselectionclear.time; | ||
| 5880 | #ifdef USE_X_TOOLKIT | 5886 | #ifdef USE_X_TOOLKIT |
| 5881 | if (! x_window_to_frame (dpyinfo, event.xselectionclear.window)) | 5887 | if (! x_window_to_frame (dpyinfo, event.xselectionclear.window)) |
| 5882 | goto OTHER; | 5888 | goto OTHER; |
| @@ -5893,6 +5899,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 5893 | break; | 5899 | break; |
| 5894 | 5900 | ||
| 5895 | case SelectionRequest: /* Someone wants our selection. */ | 5901 | case SelectionRequest: /* Someone wants our selection. */ |
| 5902 | last_user_time = event.xselectionrequest.time; | ||
| 5896 | #ifdef USE_X_TOOLKIT | 5903 | #ifdef USE_X_TOOLKIT |
| 5897 | if (!x_window_to_frame (dpyinfo, event.xselectionrequest.owner)) | 5904 | if (!x_window_to_frame (dpyinfo, event.xselectionrequest.owner)) |
| 5898 | goto OTHER; | 5905 | goto OTHER; |
| @@ -5913,6 +5920,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 5913 | break; | 5920 | break; |
| 5914 | 5921 | ||
| 5915 | case PropertyNotify: | 5922 | case PropertyNotify: |
| 5923 | last_user_time = event.xproperty.time; | ||
| 5916 | #if 0 /* This is plain wrong. In the case that we are waiting for a | 5924 | #if 0 /* This is plain wrong. In the case that we are waiting for a |
| 5917 | PropertyNotify used as an ACK in incremental selection | 5925 | PropertyNotify used as an ACK in incremental selection |
| 5918 | transfer, the property will be on the receiver's window. */ | 5926 | transfer, the property will be on the receiver's window. */ |
| @@ -5936,6 +5944,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 5936 | 5944 | ||
| 5937 | /* Perhaps reparented due to a WM restart. Reset this. */ | 5945 | /* Perhaps reparented due to a WM restart. Reset this. */ |
| 5938 | FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_UNKNOWN; | 5946 | FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_UNKNOWN; |
| 5947 | FRAME_X_DISPLAY_INFO (f)->net_supported_window = 0; | ||
| 5939 | } | 5948 | } |
| 5940 | goto OTHER; | 5949 | goto OTHER; |
| 5941 | 5950 | ||
| @@ -6094,6 +6103,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 6094 | 6103 | ||
| 6095 | case KeyPress: | 6104 | case KeyPress: |
| 6096 | 6105 | ||
| 6106 | last_user_time = event.xkey.time; | ||
| 6097 | ignore_next_mouse_click_timeout = 0; | 6107 | ignore_next_mouse_click_timeout = 0; |
| 6098 | 6108 | ||
| 6099 | #if defined (USE_X_TOOLKIT) || defined (USE_GTK) | 6109 | #if defined (USE_X_TOOLKIT) || defined (USE_GTK) |
| @@ -6484,6 +6494,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 6484 | #endif | 6494 | #endif |
| 6485 | 6495 | ||
| 6486 | case KeyRelease: | 6496 | case KeyRelease: |
| 6497 | last_user_time = event.xkey.time; | ||
| 6487 | #ifdef HAVE_X_I18N | 6498 | #ifdef HAVE_X_I18N |
| 6488 | /* Don't dispatch this event since XtDispatchEvent calls | 6499 | /* Don't dispatch this event since XtDispatchEvent calls |
| 6489 | XFilterEvent, and two calls in a row may freeze the | 6500 | XFilterEvent, and two calls in a row may freeze the |
| @@ -6494,6 +6505,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 6494 | #endif | 6505 | #endif |
| 6495 | 6506 | ||
| 6496 | case EnterNotify: | 6507 | case EnterNotify: |
| 6508 | last_user_time = event.xcrossing.time; | ||
| 6497 | x_detect_focus_change (dpyinfo, &event, &inev.ie); | 6509 | x_detect_focus_change (dpyinfo, &event, &inev.ie); |
| 6498 | 6510 | ||
| 6499 | f = x_any_window_to_frame (dpyinfo, event.xcrossing.window); | 6511 | f = x_any_window_to_frame (dpyinfo, event.xcrossing.window); |
| @@ -6534,6 +6546,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 6534 | goto OTHER; | 6546 | goto OTHER; |
| 6535 | 6547 | ||
| 6536 | case LeaveNotify: | 6548 | case LeaveNotify: |
| 6549 | last_user_time = event.xcrossing.time; | ||
| 6537 | x_detect_focus_change (dpyinfo, &event, &inev.ie); | 6550 | x_detect_focus_change (dpyinfo, &event, &inev.ie); |
| 6538 | 6551 | ||
| 6539 | f = x_top_window_to_frame (dpyinfo, event.xcrossing.window); | 6552 | f = x_top_window_to_frame (dpyinfo, event.xcrossing.window); |
| @@ -6567,6 +6580,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 6567 | 6580 | ||
| 6568 | case MotionNotify: | 6581 | case MotionNotify: |
| 6569 | { | 6582 | { |
| 6583 | last_user_time = event.xmotion.time; | ||
| 6570 | previous_help_echo_string = help_echo_string; | 6584 | previous_help_echo_string = help_echo_string; |
| 6571 | help_echo_string = Qnil; | 6585 | help_echo_string = Qnil; |
| 6572 | 6586 | ||
| @@ -6715,6 +6729,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit) | |||
| 6715 | 6729 | ||
| 6716 | bzero (&compose_status, sizeof (compose_status)); | 6730 | bzero (&compose_status, sizeof (compose_status)); |
| 6717 | last_mouse_glyph_frame = 0; | 6731 | last_mouse_glyph_frame = 0; |
| 6732 | last_user_time = event.xbutton.time; | ||
| 6718 | 6733 | ||
| 6719 | if (dpyinfo->grabbed | 6734 | if (dpyinfo->grabbed |
| 6720 | && last_mouse_frame | 6735 | && last_mouse_frame |
| @@ -8296,40 +8311,111 @@ x_set_offset (f, xoff, yoff, change_gravity) | |||
| 8296 | UNBLOCK_INPUT; | 8311 | UNBLOCK_INPUT; |
| 8297 | } | 8312 | } |
| 8298 | 8313 | ||
| 8299 | /* Do fullscreen as specified in extended window manager hints */ | 8314 | /* Return non-zero if _NET_SUPPORTING_WM_CHECK window exists and _NET_SUPPORTED |
| 8315 | on the root window for frame F contains ATOMNAME. | ||
| 8316 | This is how a WM check shall be done according to the Window Manager | ||
| 8317 | Specification/Extended Window Manager Hints at | ||
| 8318 | http://freedesktop.org/wiki/Standards_2fwm_2dspec. */ | ||
| 8319 | |||
| 8300 | static int | 8320 | static int |
| 8301 | do_ewmh_fullscreen (f) | 8321 | wm_supports (f, atomname) |
| 8302 | struct frame *f; | 8322 | struct frame *f; |
| 8323 | const char *atomname; | ||
| 8303 | { | 8324 | { |
| 8304 | int have_net_atom = FRAME_X_DISPLAY_INFO (f)->have_net_atoms; | 8325 | Atom actual_type; |
| 8326 | unsigned long actual_size, bytes_remaining; | ||
| 8327 | int i, rc, actual_format; | ||
| 8328 | Atom prop_atom; | ||
| 8329 | Window wmcheck_window; | ||
| 8330 | struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); | ||
| 8331 | Window target_window = dpyinfo->root_window; | ||
| 8332 | long max_len = 65536; | ||
| 8333 | Display *dpy = FRAME_X_DISPLAY (f); | ||
| 8334 | unsigned char *tmp_data = NULL; | ||
| 8335 | Atom target_type = XA_WINDOW; | ||
| 8336 | Atom want_atom; | ||
| 8305 | 8337 | ||
| 8306 | if (!have_net_atom) | 8338 | BLOCK_INPUT; |
| 8339 | |||
| 8340 | prop_atom = XInternAtom (dpy, "_NET_SUPPORTING_WM_CHECK", False); | ||
| 8341 | |||
| 8342 | x_catch_errors (dpy); | ||
| 8343 | rc = XGetWindowProperty (dpy, target_window, | ||
| 8344 | prop_atom, 0, max_len, False, target_type, | ||
| 8345 | &actual_type, &actual_format, &actual_size, | ||
| 8346 | &bytes_remaining, &tmp_data); | ||
| 8347 | |||
| 8348 | if (rc != Success || actual_type != XA_WINDOW || x_had_errors_p (dpy)) | ||
| 8349 | { | ||
| 8350 | if (tmp_data) XFree (tmp_data); | ||
| 8351 | x_uncatch_errors (); | ||
| 8352 | UNBLOCK_INPUT; | ||
| 8353 | return 0; | ||
| 8354 | } | ||
| 8355 | |||
| 8356 | wmcheck_window = *(Window *) tmp_data; | ||
| 8357 | XFree (tmp_data); | ||
| 8358 | |||
| 8359 | /* Check if window exists. */ | ||
| 8360 | XSelectInput (dpy, wmcheck_window, StructureNotifyMask); | ||
| 8361 | x_sync (f); | ||
| 8362 | if (x_had_errors_p (dpy)) | ||
| 8363 | { | ||
| 8364 | x_uncatch_errors (); | ||
| 8365 | UNBLOCK_INPUT; | ||
| 8366 | return 0; | ||
| 8367 | } | ||
| 8368 | |||
| 8369 | if (dpyinfo->net_supported_window != wmcheck_window) | ||
| 8307 | { | 8370 | { |
| 8308 | int num; | 8371 | /* Window changed, reload atoms */ |
| 8309 | Atom *atoms = XListProperties (FRAME_X_DISPLAY (f), | 8372 | if (dpyinfo->net_supported_atoms != NULL) |
| 8310 | FRAME_X_DISPLAY_INFO (f)->root_window, | 8373 | XFree (dpyinfo->net_supported_atoms); |
| 8311 | &num); | 8374 | dpyinfo->net_supported_atoms = NULL; |
| 8312 | if (atoms && num > 0) | 8375 | dpyinfo->nr_net_supported_atoms = 0; |
| 8376 | dpyinfo->net_supported_window = 0; | ||
| 8377 | |||
| 8378 | target_type = XA_ATOM; | ||
| 8379 | prop_atom = XInternAtom (dpy, "_NET_SUPPORTED", False); | ||
| 8380 | tmp_data = NULL; | ||
| 8381 | rc = XGetWindowProperty (dpy, target_window, | ||
| 8382 | prop_atom, 0, max_len, False, target_type, | ||
| 8383 | &actual_type, &actual_format, &actual_size, | ||
| 8384 | &bytes_remaining, &tmp_data); | ||
| 8385 | |||
| 8386 | if (rc != Success || actual_type != XA_ATOM || x_had_errors_p (dpy)) | ||
| 8313 | { | 8387 | { |
| 8314 | char **names = (char **) xmalloc (num * sizeof(*names)); | 8388 | if (tmp_data) XFree (tmp_data); |
| 8315 | if (XGetAtomNames (FRAME_X_DISPLAY (f), atoms, num, names)) | 8389 | x_uncatch_errors (); |
| 8316 | { | 8390 | UNBLOCK_INPUT; |
| 8317 | int i; | 8391 | return 0; |
| 8318 | for (i = 0; i < num; ++i) | ||
| 8319 | { | ||
| 8320 | if (!have_net_atom) | ||
| 8321 | have_net_atom = strncmp (names[i], "_NET_", 5) == 0; | ||
| 8322 | XFree (names[i]); | ||
| 8323 | } | ||
| 8324 | } | ||
| 8325 | xfree (names); | ||
| 8326 | } | 8392 | } |
| 8327 | if (atoms) | ||
| 8328 | XFree (atoms); | ||
| 8329 | 8393 | ||
| 8330 | FRAME_X_DISPLAY_INFO (f)->have_net_atoms = have_net_atom; | 8394 | dpyinfo->net_supported_atoms = (Atom *)tmp_data; |
| 8395 | dpyinfo->nr_net_supported_atoms = actual_size; | ||
| 8396 | dpyinfo->net_supported_window = wmcheck_window; | ||
| 8331 | } | 8397 | } |
| 8332 | 8398 | ||
| 8399 | rc = 0; | ||
| 8400 | want_atom = XInternAtom (dpy, atomname, False); | ||
| 8401 | |||
| 8402 | for (i = 0; rc == 0 && i < dpyinfo->nr_net_supported_atoms; ++i) | ||
| 8403 | rc = dpyinfo->net_supported_atoms[i] == want_atom; | ||
| 8404 | |||
| 8405 | x_uncatch_errors (); | ||
| 8406 | UNBLOCK_INPUT; | ||
| 8407 | |||
| 8408 | return rc; | ||
| 8409 | } | ||
| 8410 | |||
| 8411 | /* Do fullscreen as specified in extended window manager hints */ | ||
| 8412 | |||
| 8413 | static int | ||
| 8414 | do_ewmh_fullscreen (f) | ||
| 8415 | struct frame *f; | ||
| 8416 | { | ||
| 8417 | int have_net_atom = wm_supports (f, "_NET_WM_STATE"); | ||
| 8418 | |||
| 8333 | if (have_net_atom) | 8419 | if (have_net_atom) |
| 8334 | { | 8420 | { |
| 8335 | Lisp_Object frame; | 8421 | Lisp_Object frame; |
| @@ -8356,6 +8442,9 @@ do_ewmh_fullscreen (f) | |||
| 8356 | break; | 8442 | break; |
| 8357 | } | 8443 | } |
| 8358 | 8444 | ||
| 8445 | if (!wm_supports (f, what)) return 0; | ||
| 8446 | |||
| 8447 | |||
| 8359 | Fx_send_client_event (frame, make_number (0), frame, | 8448 | Fx_send_client_event (frame, make_number (0), frame, |
| 8360 | make_unibyte_string (atom, strlen (atom)), | 8449 | make_unibyte_string (atom, strlen (atom)), |
| 8361 | make_number (32), | 8450 | make_number (32), |
| @@ -8756,23 +8845,27 @@ XTframe_raise_lower (f, raise_flag) | |||
| 8756 | /* The following code is needed for `raise-frame' to work on | 8845 | /* The following code is needed for `raise-frame' to work on |
| 8757 | some versions of metacity; see Window Manager | 8846 | some versions of metacity; see Window Manager |
| 8758 | Specification/Extended Window Manager Hints at | 8847 | Specification/Extended Window Manager Hints at |
| 8759 | http://freedesktop.org/wiki/Standards_2fwm_2dspec | 8848 | http://freedesktop.org/wiki/Standards_2fwm_2dspec */ |
| 8760 | 8849 | ||
| 8761 | However, on other versions (metacity 2.17.2-1.fc7), it | 8850 | #if 0 |
| 8851 | /* However, on other versions (metacity 2.17.2-1.fc7), it | ||
| 8762 | reportedly causes hangs when resizing frames. */ | 8852 | reportedly causes hangs when resizing frames. */ |
| 8763 | 8853 | ||
| 8764 | /* Lisp_Object frame; | 8854 | const char *atom = "_NET_ACTIVE_WINDOW"; |
| 8765 | const char *atom = "_NET_ACTIVE_WINDOW"; */ | 8855 | if (f->async_visible && wm_supports (f, atom)) |
| 8766 | 8856 | { | |
| 8767 | x_raise_frame (f); | 8857 | Lisp_Object frame; |
| 8768 | 8858 | XSETFRAME (frame, f); | |
| 8769 | /* XSETFRAME (frame, f); | 8859 | Fx_send_client_event (frame, make_number (0), frame, |
| 8770 | Fx_send_client_event (frame, make_number (0), frame, | 8860 | make_unibyte_string (atom, strlen (atom)), |
| 8771 | make_unibyte_string (atom, strlen (atom)), | 8861 | make_number (32), |
| 8772 | make_number (32), | 8862 | Fcons (make_number (1), |
| 8773 | Fcons (make_number (1), | 8863 | Fcons (make_number (last_user_time), |
| 8774 | Fcons (make_number (time (NULL) * 1000), | 8864 | Qnil))); |
| 8775 | Qnil))); */ | 8865 | } |
| 8866 | else | ||
| 8867 | #endif | ||
| 8868 | x_raise_frame (f); | ||
| 8776 | } | 8869 | } |
| 8777 | else | 8870 | else |
| 8778 | x_lower_frame (f); | 8871 | x_lower_frame (f); |
| @@ -10747,6 +10840,10 @@ x_term_init (display_name, xrm_option, resource_name) | |||
| 10747 | dpyinfo->x_dnd_atoms = xmalloc (sizeof (*dpyinfo->x_dnd_atoms) | 10840 | dpyinfo->x_dnd_atoms = xmalloc (sizeof (*dpyinfo->x_dnd_atoms) |
| 10748 | * dpyinfo->x_dnd_atoms_size); | 10841 | * dpyinfo->x_dnd_atoms_size); |
| 10749 | 10842 | ||
| 10843 | dpyinfo->net_supported_atoms = NULL; | ||
| 10844 | dpyinfo->nr_net_supported_atoms = 0; | ||
| 10845 | dpyinfo->net_supported_window = 0; | ||
| 10846 | |||
| 10750 | connection = ConnectionNumber (dpyinfo->display); | 10847 | connection = ConnectionNumber (dpyinfo->display); |
| 10751 | dpyinfo->connection = connection; | 10848 | dpyinfo->connection = connection; |
| 10752 | 10849 | ||