From 675b0d44df8a7f3604caf5819fcb4fa9e769d21f Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <fourdan.olivier@wanadoo.fr>
Date: Thu, 22 Apr 2004 20:34:43 +0000
Subject: [PATCH] Add a technique (from Metacity) to limit the number of resize
 operations per second to prevent the app from lagging when using opaque
 resize.

(Old svn revision: 11719)
---
 po/xfwm4.pot |  6 ++---
 src/client.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++-----
 src/client.h |  1 +
 3 files changed, 65 insertions(+), 9 deletions(-)

diff --git a/po/xfwm4.pot b/po/xfwm4.pot
index f4f9815d5..beb3aa939 100644
--- a/po/xfwm4.pot
+++ b/po/xfwm4.pot
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2004-04-21 23:52+0200\n"
+"POT-Creation-Date: 2004-04-22 21:27+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -299,12 +299,12 @@ msgstr ""
 msgid "Advanced"
 msgstr ""
 
-#: src/client.c:527
+#: src/client.c:528
 #, c-format
 msgid "%s: Unmanaged net_wm_state (window 0x%lx)"
 msgstr ""
 
-#: src/events.c:1502
+#: src/events.c:1507
 #, c-format
 msgid "%s: Operation not supported (yet)\n"
 msgstr ""
diff --git a/src/client.c b/src/client.c
index a1dcef09e..a603a6de6 100644
--- a/src/client.c
+++ b/src/client.c
@@ -100,6 +100,14 @@
 #define XWINDOW_TO_GPOINTER(w)  ((gpointer) (Window) (w))
 #define GPOINTER_TO_XWINDOW(p)  ((Window) (p))
 
+#ifndef EPSILON
+#define EPSILON                 (1e-6)  
+#endif
+
+#ifndef MAX_RESIZES_PER_SECOND
+#define MAX_RESIZES_PER_SECOND  20.0
+#endif
+
 typedef struct _MoveResizeData MoveResizeData;
 struct _MoveResizeData
 {
@@ -349,6 +357,47 @@ clientIsTransientOrModalForGroup (Client * c)
     return (clientIsTransientForGroup(c) || clientIsModalForGroup(c));
 }
 
+/* 
+ * The following two functions are to limit the number of updates 
+ * during resize operations.
+ * It's taken from Metacity
+ */
+void
+clientClearLastOpTime (Client * c)
+{
+    g_return_if_fail (c != NULL);
+    
+    TRACE ("entering clientClearLastOpTime");
+    c->lastoptime.tv_sec = 0;
+    c->lastoptime.tv_usec = 0;
+}
+
+static gboolean
+clientCheckLastOpTime (Client * c)
+{
+    GTimeVal current_time;
+    double elapsed;
+  
+    g_return_val_if_fail (c != NULL, FALSE);
+
+    g_get_current_time (&current_time);
+    /* use milliseconds, 1000 milliseconds/second */
+    elapsed = (((double)current_time.tv_sec - c->lastoptime.tv_sec) * G_USEC_PER_SEC +
+                  (current_time.tv_usec - c->lastoptime.tv_usec)) / 1000.0;
+    if (elapsed >= 0.0 && elapsed < (1000.0 / MAX_RESIZES_PER_SECOND))
+    {
+        return FALSE;
+    }
+    else if (elapsed < (0.0 - EPSILON))
+    {
+        /* clock screw */
+        clientClearLastOpTime (c);
+    }
+    c->lastoptime = current_time;
+  
+    return TRUE;
+}
+
 void
 clientSetNetState (Client * c)
 {
@@ -3234,6 +3283,9 @@ clientFrame (Window w, gboolean recapture)
     c->border_width = attr.border_width;
     c->cmap = attr.colormap;
 
+    /* Clear time counter */
+    clientClearLastOpTime (c);
+
     if (clientCheckShape(c))
     {
         FLAG_UNSET (c->flags, CLIENT_FLAG_HAS_BORDER);
@@ -5505,7 +5557,6 @@ clientResize_event_filter (XEvent * xevent, gpointer data)
     int frame_top, frame_left, frame_right, frame_bottom;
 
     TRACE ("entering clientResize_event_filter");
-
     frame_x = frameX (c);
     frame_y = frameY (c);
     frame_height = frameHeight (c);
@@ -5639,6 +5690,7 @@ clientResize_event_filter (XEvent * xevent, gpointer data)
         if (xevent->type == ButtonRelease)
         {
             resizing = FALSE;
+            clientClearLastOpTime (c);
         }
 
         if (!passdata->grab && params.box_resize)
@@ -5751,11 +5803,14 @@ clientResize_event_filter (XEvent * xevent, gpointer data)
         }
         else
         {
-            wc.x = c->x;
-            wc.y = c->y;
-            wc.width = c->width;
-            wc.height = c->height;
-            clientConfigure (c, &wc, CWX | CWY | CWWidth | CWHeight, NO_CFG_FLAG);
+            if (clientCheckLastOpTime (c))
+            {
+                wc.x = c->x;
+                wc.y = c->y;
+                wc.width = c->width;
+                wc.height = c->height;
+                clientConfigure (c, &wc, CWX | CWY | CWWidth | CWHeight, NO_CFG_FLAG);
+            }
         }
         
     }
diff --git a/src/client.h b/src/client.h
index 11ae45faf..269177474 100644
--- a/src/client.h
+++ b/src/client.h
@@ -222,6 +222,7 @@ struct _Client
     int button_pressed[BUTTON_COUNT];
     int struts[12];
     char *name;
+    GTimeVal lastoptime;
 #ifdef HAVE_LIBSTARTUP_NOTIFICATION
 
     char *startup_id;
-- 
GitLab