emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 7f9335f91d: Implement _NET_WM_USER_TIME protocol


From: Po Lu
Subject: master 7f9335f91d: Implement _NET_WM_USER_TIME protocol
Date: Wed, 9 Feb 2022 03:14:53 -0500 (EST)

branch: master
commit 7f9335f91d3e0ecdff9c3adb93aad08454002035
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Implement _NET_WM_USER_TIME protocol
    
    * src/xterm.c (x_display_set_last_user_time): Set user time on
    the active window.
    (handle_one_xevent): Only set user time when the user actually
    interacted with Emacs.
    (x_make_frame_visible): Set user time if non-zero.
    (x_term_init): Intern `_NET_WM_USER_TIME'.
    * src/xterm.h (struct x_display_info): New field
    `Xatom_net_wm_user_time'.
    (x_display_set_last_user_time): Implement in xterm.c instead.
---
 src/xterm.c | 101 ++++++++++++++++++++++++++++++++++++++----------------------
 src/xterm.h |  14 +++------
 2 files changed, 69 insertions(+), 46 deletions(-)

diff --git a/src/xterm.c b/src/xterm.c
index aed97fb37e..38b50bcd3b 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -2217,6 +2217,29 @@ static void x_scroll_bar_clear (struct frame *);
 static void x_check_font (struct frame *, struct font *);
 #endif
 
+void
+x_display_set_last_user_time (struct x_display_info *dpyinfo, Time time)
+{
+  struct frame *focus_frame = dpyinfo->x_focus_frame;
+
+#ifdef ENABLE_CHECKING
+  eassert (t <= X_ULONG_MAX);
+#endif
+  dpyinfo->last_user_time = time;
+
+  if (focus_frame)
+    {
+      while (FRAME_PARENT_FRAME (focus_frame))
+       focus_frame = FRAME_PARENT_FRAME (focus_frame);
+
+      XChangeProperty (dpyinfo->display,
+                      FRAME_OUTER_WINDOW (dpyinfo->x_focus_frame),
+                      dpyinfo->Xatom_net_wm_user_time,
+                      XA_CARDINAL, 32, PropModeReplace,
+                      (unsigned char *) &time, 1);
+    }
+}
+
 
 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
    face.  */
@@ -9307,7 +9330,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       break;
 
     case SelectionNotify:
-      x_display_set_last_user_time (dpyinfo, event->xselection.time);
 #ifdef USE_X_TOOLKIT
       if (! x_window_to_frame (dpyinfo, event->xselection.requestor))
         goto OTHER;
@@ -9316,7 +9338,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       break;
 
     case SelectionClear:       /* Someone has grabbed ownership.  */
-      x_display_set_last_user_time (dpyinfo, event->xselectionclear.time);
 #ifdef USE_X_TOOLKIT
       if (! x_window_to_frame (dpyinfo, event->xselectionclear.window))
         goto OTHER;
@@ -9332,7 +9353,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       break;
 
     case SelectionRequest:     /* Someone wants our selection.  */
-      x_display_set_last_user_time (dpyinfo, event->xselectionrequest.time);
 #ifdef USE_X_TOOLKIT
       if (!x_window_to_frame (dpyinfo, event->xselectionrequest.owner))
         goto OTHER;
@@ -9351,7 +9371,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       break;
 
     case PropertyNotify:
-      x_display_set_last_user_time (dpyinfo, event->xproperty.time);
       f = x_top_window_to_frame (dpyinfo, event->xproperty.window);
       if (f && event->xproperty.atom == dpyinfo->Xatom_net_wm_state)
        {
@@ -9682,7 +9701,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       goto OTHER;
 
     case KeyPress:
-
       x_display_set_last_user_time (dpyinfo, event->xkey.time);
       ignore_next_mouse_click_timeout = 0;
 
@@ -10018,7 +10036,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 #endif
 
     case KeyRelease:
-      x_display_set_last_user_time (dpyinfo, 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
@@ -10172,7 +10189,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 
     case MotionNotify:
       {
-        x_display_set_last_user_time (dpyinfo, event->xmotion.time);
         previous_help_echo_string = help_echo_string;
         help_echo_string = Qnil;
 
@@ -10482,7 +10498,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 
        memset (&compose_status, 0, sizeof (compose_status));
        dpyinfo->last_mouse_glyph_frame = NULL;
-       x_display_set_last_user_time (dpyinfo, event->xbutton.time);
+
+       if (event->xbutton.type == ButtonPress)
+         x_display_set_last_user_time (dpyinfo, event->xbutton.time);
 
        f = mouse_or_wdesc_frame (dpyinfo, event->xmotion.window);
        if (f && event->xbutton.type == ButtonPress
@@ -10901,8 +10919,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                goto XI_OTHER;
 #endif
 
-             x_display_set_last_user_time (dpyinfo, xi_event->time);
-
 #ifdef HAVE_XWIDGETS
              struct xwidget_view *xv = xwidget_view_from_window (xev->event);
              double xv_total_x = 0.0;
@@ -11224,7 +11240,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
              bv.time = xev->time;
 
              dpyinfo->last_mouse_glyph_frame = NULL;
-             x_display_set_last_user_time (dpyinfo, xev->time);
+
+             if (xev->evtype == XI_ButtonPress)
+               x_display_set_last_user_time (dpyinfo, xev->time);
 
              f = mouse_or_wdesc_frame (dpyinfo, xev->event);
 
@@ -11735,34 +11753,32 @@ handle_one_xevent (struct x_display_info *dpyinfo,
            }
 
          case XI_KeyRelease:
-           x_display_set_last_user_time (dpyinfo, xev->time);
-
 #if defined HAVE_X_I18N || defined USE_GTK
-             XKeyPressedEvent xkey;
-
-             memset (&xkey, 0, sizeof xkey);
-
-             xkey.type = KeyRelease;
-             xkey.serial = xev->serial;
-             xkey.send_event = xev->send_event;
-             xkey.display = dpyinfo->display;
-             xkey.window = xev->event;
-             xkey.root = xev->root;
-             xkey.subwindow = xev->child;
-             xkey.time = xev->time;
-             xkey.state = ((xev->mods.effective & ~(1 << 13 | 1 << 14))
-                           | (xev->group.effective << 13));
-             xkey.keycode = xev->detail;
-             xkey.same_screen = True;
+           XKeyPressedEvent xkey;
+
+           memset (&xkey, 0, sizeof xkey);
+
+           xkey.type = KeyRelease;
+           xkey.serial = xev->serial;
+           xkey.send_event = xev->send_event;
+           xkey.display = dpyinfo->display;
+           xkey.window = xev->event;
+           xkey.root = xev->root;
+           xkey.subwindow = xev->child;
+           xkey.time = xev->time;
+           xkey.state = ((xev->mods.effective & ~(1 << 13 | 1 << 14))
+                         | (xev->group.effective << 13));
+           xkey.keycode = xev->detail;
+           xkey.same_screen = True;
 
 #ifdef HAVE_X_I18N
-             if (x_filter_event (dpyinfo, (XEvent *) &xkey))
-               *finish = X_EVENT_DROP;
+           if (x_filter_event (dpyinfo, (XEvent *) &xkey))
+             *finish = X_EVENT_DROP;
 #else
-             f = x_any_window_to_frame (xkey->event);
+           f = x_any_window_to_frame (xkey->event);
 
-             if (f && xg_filter_key (f, event))
-               *finish = X_EVENT_DROP;
+           if (f && xg_filter_key (f, event))
+             *finish = X_EVENT_DROP;
 #endif
 #endif
 
@@ -11989,8 +12005,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 
          case XI_GesturePinchEnd:
            {
-             x_display_set_last_user_time (dpyinfo, xi_event->time);
-
 #if defined HAVE_XWIDGETS && HAVE_USABLE_XI_GESTURE_PINCH_EVENT
              XIGesturePinchEvent *pev = (XIGesturePinchEvent *) xi_event;
              struct xwidget_view *xvw = xwidget_view_from_window (pev->event);
@@ -14466,6 +14480,8 @@ xembed_send_message (struct frame *f, Time t, enum 
xembed_message msg,
 void
 x_make_frame_visible (struct frame *f)
 {
+  struct x_display_info *dpyinfo;
+
   if (FRAME_PARENT_FRAME (f))
     {
       if (!FRAME_VISIBLE_P (f))
@@ -14489,6 +14505,7 @@ x_make_frame_visible (struct frame *f)
   block_input ();
 
   gui_set_bitmap_icon (f);
+  dpyinfo = FRAME_DISPLAY_INFO (f);
 
   if (! FRAME_VISIBLE_P (f))
     {
@@ -14501,6 +14518,17 @@ x_make_frame_visible (struct frame *f)
          && ! f->output_data.x->asked_for_visible)
        x_set_offset (f, f->left_pos, f->top_pos, 0);
 
+      if (dpyinfo->last_user_time)
+       XChangeProperty (dpyinfo->display,
+                        FRAME_OUTER_WINDOW (f),
+                        dpyinfo->Xatom_net_wm_user_time,
+                        XA_CARDINAL, 32, PropModeReplace,
+                        (unsigned char *) &dpyinfo->last_user_time, 1);
+      else
+       XDeleteProperty (dpyinfo->display,
+                        FRAME_OUTER_WINDOW (f),
+                        dpyinfo->Xatom_net_wm_user_time);
+
       f->output_data.x->asked_for_visible = true;
 
       if (! EQ (Vx_no_window_manager, Qt))
@@ -16104,6 +16132,7 @@ x_term_init (Lisp_Object display_name, char 
*xrm_option, char *resource_name)
       ATOM_REFS_INIT ("_NET_WM_SYNC_REQUEST", Xatom_net_wm_sync_request)
       ATOM_REFS_INIT ("_NET_WM_SYNC_REQUEST_COUNTER", 
Xatom_net_wm_sync_request_counter)
       ATOM_REFS_INIT ("_NET_WM_FRAME_DRAWN", Xatom_net_wm_frame_drawn)
+      ATOM_REFS_INIT ("_NET_WM_USER_TIME", Xatom_net_wm_user_time)
       /* Session management */
       ATOM_REFS_INIT ("SM_CLIENT_ID", Xatom_SM_CLIENT_ID)
       ATOM_REFS_INIT ("_XSETTINGS_SETTINGS", Xatom_xsettings_prop)
diff --git a/src/xterm.h b/src/xterm.h
index 435569943c..9aa7021c4d 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -505,7 +505,8 @@ struct x_display_info
     Xatom_net_wm_state_hidden, Xatom_net_wm_state_skip_taskbar,
     Xatom_net_frame_extents, Xatom_net_current_desktop, Xatom_net_workarea,
     Xatom_net_wm_opaque_region, Xatom_net_wm_ping, Xatom_net_wm_sync_request,
-    Xatom_net_wm_sync_request_counter, Xatom_net_wm_frame_drawn;
+    Xatom_net_wm_sync_request_counter, Xatom_net_wm_frame_drawn,
+    Xatom_net_wm_user_time;
 
   /* XSettings atoms and windows.  */
   Atom Xatom_xsettings_sel, Xatom_xsettings_prop, Xatom_xsettings_mgr;
@@ -1283,6 +1284,8 @@ extern void x_xr_apply_ext_clip (struct frame *f, GC gc);
 extern void x_xr_reset_ext_clip (struct frame *f);
 #endif
 
+extern void x_display_set_last_user_time (struct x_display_info *, Time);
+
 INLINE int
 x_display_pixel_height (struct x_display_info *dpyinfo)
 {
@@ -1295,15 +1298,6 @@ x_display_pixel_width (struct x_display_info *dpyinfo)
   return WidthOfScreen (dpyinfo->screen);
 }
 
-INLINE void
-x_display_set_last_user_time (struct x_display_info *dpyinfo, Time t)
-{
-#ifdef ENABLE_CHECKING
-  eassert (t <= X_ULONG_MAX);
-#endif
-  dpyinfo->last_user_time = t;
-}
-
 INLINE unsigned long
 x_make_truecolor_pixel (struct x_display_info *dpyinfo, int r, int g, int b)
 {



reply via email to

[Prev in Thread] Current Thread [Next in Thread]