aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJan Djärv2007-01-08 17:56:31 +0000
committerJan Djärv2007-01-08 17:56:31 +0000
commit1c8591d04ca0c88d816e1498f058db7fe948fb63 (patch)
treea3cfed52e85cf41ca326b172117723eaa5d31337 /src
parentaf5debda9205ed0fe0c0d7cf523b503675afa261 (diff)
downloademacs-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.c173
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
278static Time last_mouse_movement_time; 278static Time last_mouse_movement_time;
279 279
280/* Time for last user interaction as returned in X events. */
281
282static 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
8300static int 8320static int
8301do_ewmh_fullscreen (f) 8321wm_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
8413static int
8414do_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