summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJan Djärv <jan.h.d@swipnet.se>2007-01-08 17:56:31 +0000
committerJan Djärv <jan.h.d@swipnet.se>2007-01-08 17:56:31 +0000
commit1c8591d04ca0c88d816e1498f058db7fe948fb63 (patch)
treea3cfed52e85cf41ca326b172117723eaa5d31337 /src
parentaf5debda9205ed0fe0c0d7cf523b503675afa261 (diff)
downloademacs-1c8591d04ca0c88d816e1498f058db7fe948fb63.tar.gz
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;
static Time last_mouse_movement_time;
+/* Time for last user interaction as returned in X events. */
+
+static Time last_user_time;
+
/* Incremented by XTread_socket whenever it really tries to read
events. */
@@ -5869,6 +5873,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
break;
case SelectionNotify:
+ last_user_time = event.xselection.time;
#ifdef USE_X_TOOLKIT
if (! x_window_to_frame (dpyinfo, event.xselection.requestor))
goto OTHER;
@@ -5877,6 +5882,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
break;
case SelectionClear: /* Someone has grabbed ownership. */
+ last_user_time = event.xselectionclear.time;
#ifdef USE_X_TOOLKIT
if (! x_window_to_frame (dpyinfo, event.xselectionclear.window))
goto OTHER;
@@ -5893,6 +5899,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
break;
case SelectionRequest: /* Someone wants our selection. */
+ last_user_time = event.xselectionrequest.time;
#ifdef USE_X_TOOLKIT
if (!x_window_to_frame (dpyinfo, event.xselectionrequest.owner))
goto OTHER;
@@ -5913,6 +5920,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
break;
case PropertyNotify:
+ last_user_time = event.xproperty.time;
#if 0 /* This is plain wrong. In the case that we are waiting for a
PropertyNotify used as an ACK in incremental selection
transfer, the property will be on the receiver's window. */
@@ -5936,6 +5944,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
/* Perhaps reparented due to a WM restart. Reset this. */
FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_UNKNOWN;
+ FRAME_X_DISPLAY_INFO (f)->net_supported_window = 0;
}
goto OTHER;
@@ -6094,6 +6103,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
case KeyPress:
+ last_user_time = event.xkey.time;
ignore_next_mouse_click_timeout = 0;
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
@@ -6484,6 +6494,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
#endif
case KeyRelease:
+ last_user_time = event.xkey.time;
#ifdef HAVE_X_I18N
/* Don't dispatch this event since XtDispatchEvent calls
XFilterEvent, and two calls in a row may freeze the
@@ -6494,6 +6505,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
#endif
case EnterNotify:
+ last_user_time = event.xcrossing.time;
x_detect_focus_change (dpyinfo, &event, &inev.ie);
f = x_any_window_to_frame (dpyinfo, event.xcrossing.window);
@@ -6534,6 +6546,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
goto OTHER;
case LeaveNotify:
+ last_user_time = event.xcrossing.time;
x_detect_focus_change (dpyinfo, &event, &inev.ie);
f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
@@ -6567,6 +6580,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
case MotionNotify:
{
+ last_user_time = event.xmotion.time;
previous_help_echo_string = help_echo_string;
help_echo_string = Qnil;
@@ -6715,6 +6729,7 @@ handle_one_xevent (dpyinfo, eventp, finish, hold_quit)
bzero (&compose_status, sizeof (compose_status));
last_mouse_glyph_frame = 0;
+ last_user_time = event.xbutton.time;
if (dpyinfo->grabbed
&& last_mouse_frame
@@ -8296,40 +8311,111 @@ x_set_offset (f, xoff, yoff, change_gravity)
UNBLOCK_INPUT;
}
-/* Do fullscreen as specified in extended window manager hints */
+/* Return non-zero if _NET_SUPPORTING_WM_CHECK window exists and _NET_SUPPORTED
+ on the root window for frame F contains ATOMNAME.
+ This is how a WM check shall be done according to the Window Manager
+ Specification/Extended Window Manager Hints at
+ http://freedesktop.org/wiki/Standards_2fwm_2dspec. */
+
static int
-do_ewmh_fullscreen (f)
+wm_supports (f, atomname)
struct frame *f;
+ const char *atomname;
{
- int have_net_atom = FRAME_X_DISPLAY_INFO (f)->have_net_atoms;
+ Atom actual_type;
+ unsigned long actual_size, bytes_remaining;
+ int i, rc, actual_format;
+ Atom prop_atom;
+ Window wmcheck_window;
+ struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+ Window target_window = dpyinfo->root_window;
+ long max_len = 65536;
+ Display *dpy = FRAME_X_DISPLAY (f);
+ unsigned char *tmp_data = NULL;
+ Atom target_type = XA_WINDOW;
+ Atom want_atom;
- if (!have_net_atom)
+ BLOCK_INPUT;
+
+ prop_atom = XInternAtom (dpy, "_NET_SUPPORTING_WM_CHECK", False);
+
+ x_catch_errors (dpy);
+ rc = XGetWindowProperty (dpy, target_window,
+ prop_atom, 0, max_len, False, target_type,
+ &actual_type, &actual_format, &actual_size,
+ &bytes_remaining, &tmp_data);
+
+ if (rc != Success || actual_type != XA_WINDOW || x_had_errors_p (dpy))
+ {
+ if (tmp_data) XFree (tmp_data);
+ x_uncatch_errors ();
+ UNBLOCK_INPUT;
+ return 0;
+ }
+
+ wmcheck_window = *(Window *) tmp_data;
+ XFree (tmp_data);
+
+ /* Check if window exists. */
+ XSelectInput (dpy, wmcheck_window, StructureNotifyMask);
+ x_sync (f);
+ if (x_had_errors_p (dpy))
+ {
+ x_uncatch_errors ();
+ UNBLOCK_INPUT;
+ return 0;
+ }
+
+ if (dpyinfo->net_supported_window != wmcheck_window)
{
- int num;
- Atom *atoms = XListProperties (FRAME_X_DISPLAY (f),
- FRAME_X_DISPLAY_INFO (f)->root_window,
- &num);
- if (atoms && num > 0)
+ /* Window changed, reload atoms */
+ if (dpyinfo->net_supported_atoms != NULL)
+ XFree (dpyinfo->net_supported_atoms);
+ dpyinfo->net_supported_atoms = NULL;
+ dpyinfo->nr_net_supported_atoms = 0;
+ dpyinfo->net_supported_window = 0;
+
+ target_type = XA_ATOM;
+ prop_atom = XInternAtom (dpy, "_NET_SUPPORTED", False);
+ tmp_data = NULL;
+ rc = XGetWindowProperty (dpy, target_window,
+ prop_atom, 0, max_len, False, target_type,
+ &actual_type, &actual_format, &actual_size,
+ &bytes_remaining, &tmp_data);
+
+ if (rc != Success || actual_type != XA_ATOM || x_had_errors_p (dpy))
{
- char **names = (char **) xmalloc (num * sizeof(*names));
- if (XGetAtomNames (FRAME_X_DISPLAY (f), atoms, num, names))
- {
- int i;
- for (i = 0; i < num; ++i)
- {
- if (!have_net_atom)
- have_net_atom = strncmp (names[i], "_NET_", 5) == 0;
- XFree (names[i]);
- }
- }
- xfree (names);
+ if (tmp_data) XFree (tmp_data);
+ x_uncatch_errors ();
+ UNBLOCK_INPUT;
+ return 0;
}
- if (atoms)
- XFree (atoms);
- FRAME_X_DISPLAY_INFO (f)->have_net_atoms = have_net_atom;
+ dpyinfo->net_supported_atoms = (Atom *)tmp_data;
+ dpyinfo->nr_net_supported_atoms = actual_size;
+ dpyinfo->net_supported_window = wmcheck_window;
}
+ rc = 0;
+ want_atom = XInternAtom (dpy, atomname, False);
+
+ for (i = 0; rc == 0 && i < dpyinfo->nr_net_supported_atoms; ++i)
+ rc = dpyinfo->net_supported_atoms[i] == want_atom;
+
+ x_uncatch_errors ();
+ UNBLOCK_INPUT;
+
+ return rc;
+}
+
+/* Do fullscreen as specified in extended window manager hints */
+
+static int
+do_ewmh_fullscreen (f)
+ struct frame *f;
+{
+ int have_net_atom = wm_supports (f, "_NET_WM_STATE");
+
if (have_net_atom)
{
Lisp_Object frame;
@@ -8356,6 +8442,9 @@ do_ewmh_fullscreen (f)
break;
}
+ if (!wm_supports (f, what)) return 0;
+
+
Fx_send_client_event (frame, make_number (0), frame,
make_unibyte_string (atom, strlen (atom)),
make_number (32),
@@ -8756,23 +8845,27 @@ XTframe_raise_lower (f, raise_flag)
/* The following code is needed for `raise-frame' to work on
some versions of metacity; see Window Manager
Specification/Extended Window Manager Hints at
- http://freedesktop.org/wiki/Standards_2fwm_2dspec
+ http://freedesktop.org/wiki/Standards_2fwm_2dspec */
- However, on other versions (metacity 2.17.2-1.fc7), it
+#if 0
+ /* However, on other versions (metacity 2.17.2-1.fc7), it
reportedly causes hangs when resizing frames. */
- /* Lisp_Object frame;
- const char *atom = "_NET_ACTIVE_WINDOW"; */
-
- x_raise_frame (f);
-
- /* XSETFRAME (frame, f);
- Fx_send_client_event (frame, make_number (0), frame,
- make_unibyte_string (atom, strlen (atom)),
- make_number (32),
- Fcons (make_number (1),
- Fcons (make_number (time (NULL) * 1000),
- Qnil))); */
+ const char *atom = "_NET_ACTIVE_WINDOW";
+ if (f->async_visible && wm_supports (f, atom))
+ {
+ Lisp_Object frame;
+ XSETFRAME (frame, f);
+ Fx_send_client_event (frame, make_number (0), frame,
+ make_unibyte_string (atom, strlen (atom)),
+ make_number (32),
+ Fcons (make_number (1),
+ Fcons (make_number (last_user_time),
+ Qnil)));
+ }
+ else
+#endif
+ x_raise_frame (f);
}
else
x_lower_frame (f);
@@ -10747,6 +10840,10 @@ x_term_init (display_name, xrm_option, resource_name)
dpyinfo->x_dnd_atoms = xmalloc (sizeof (*dpyinfo->x_dnd_atoms)
* dpyinfo->x_dnd_atoms_size);
+ dpyinfo->net_supported_atoms = NULL;
+ dpyinfo->nr_net_supported_atoms = 0;
+ dpyinfo->net_supported_window = 0;
+
connection = ConnectionNumber (dpyinfo->display);
dpyinfo->connection = connection;