emacs-diffs
[Top][All Lists]
Advanced

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

master 5c656182ce: Avoid race conditions when computing real frame posit


From: Po Lu
Subject: master 5c656182ce: Avoid race conditions when computing real frame positions on Haiku
Date: Tue, 17 May 2022 09:13:58 -0400 (EDT)

branch: master
commit 5c656182ce30372873ea2e3f1ffb555f52df9d95
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Avoid race conditions when computing real frame positions on Haiku
    
    * src/haiku_support.cc (DispatchMessage): Accept
    SEND_MOVE_FRAME_EVENT.
    (class EmacsWindow, FrameMoved): Include decorator frame in
    MOVE_EVENT events.
    (be_send_move_frame_event): New function.
    * src/haiku_support.h (struct haiku_move_event): Include
    decorator dimensions.  Update prototypes.
    
    * src/haikufns.c (haiku_update_after_decoration_change): Ask for
    a move frame event and don't do anything if configury is not yet
    complete.
    
    * src/haikuterm.c (haiku_read_socket): Adjust accordingly.
---
 src/haiku_support.cc | 44 ++++++++++++++++++++++++++++++++++++--------
 src/haiku_support.h  |  6 ++++--
 src/haikufns.c       | 21 +++++++--------------
 src/haikuterm.c      | 10 +++-------
 4 files changed, 50 insertions(+), 31 deletions(-)

diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index 299b37c1cc..28c8608584 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -106,6 +106,7 @@ enum
     SET_FONT_INDICES     = 3012,
     SET_PREVIEW_DIALOG   = 3013,
     UPDATE_PREVIEW_DIALOG = 3014,
+    SEND_MOVE_FRAME_EVENT = 3015,
   };
 
 /* X11 keysyms that we use.  */
@@ -993,6 +994,8 @@ public:
            haiku_write (WHEEL_MOVE_EVENT, &rq);
          };
       }
+    else if (msg->what == SEND_MOVE_FRAME_EVENT)
+      FrameMoved (Frame ().LeftTop ());
     else
       BWindow::DispatchMessage (msg, handler);
   }
@@ -1034,33 +1037,44 @@ public:
   }
 
   void
-  FrameMoved (BPoint newPosition)
+  FrameMoved (BPoint new_position)
   {
     struct haiku_move_event rq;
+    BRect frame, decorator_frame;
+    struct child_frame *f;
+
     rq.window = this;
-    rq.x = std::lrint (newPosition.x);
-    rq.y = std::lrint (newPosition.y);
+    rq.x = std::lrint (new_position.x);
+    rq.y = std::lrint (new_position.y);
+
+    frame = Frame ();
+    decorator_frame = DecoratorFrame ();
+
+    rq.decorator_width
+      = std::lrint (frame.left - decorator_frame.left);
+    rq.decorator_height
+      = std::lrint (frame.top - decorator_frame.top);
 
     haiku_write (MOVE_EVENT, &rq);
 
     CHILD_FRAME_LOCK_INSIDE_LOOPER_CALLBACK
       {
-       for (struct child_frame *f = subset_windows;
-            f; f = f->next)
+       for (f = subset_windows; f; f = f->next)
          DoMove (f);
        child_frame_lock.Unlock ();
 
-       BWindow::FrameMoved (newPosition);
+       BWindow::FrameMoved (new_position);
       }
   }
 
   void
   WorkspacesChanged (uint32_t old, uint32_t n)
   {
+    struct child_frame *f;
+
     CHILD_FRAME_LOCK_INSIDE_LOOPER_CALLBACK
       {
-       for (struct child_frame *f = subset_windows;
-            f; f = f->next)
+       for (f = subset_windows; f; f = f->next)
          DoUpdateWorkspace (f);
 
        child_frame_lock.Unlock ();
@@ -5135,3 +5149,17 @@ be_get_window_decorator_frame (void *window, int *left, 
int *top,
 
   wnd->UnlockLooper ();
 }
+
+/* Request that a MOVE_EVENT be sent for WINDOW.  This is so that
+   frame offsets can be updated after a frame parameter affecting
+   decorators changes.  Sending an event instead of updating the
+   offsets directly avoids race conditions where events with older
+   information are received after the update happens.  */
+void
+be_send_move_frame_event (void *window)
+{
+  BWindow *wnd = (BWindow *) window;
+  BMessenger msg (wnd);
+
+  msg.SendMessage (SEND_MOVE_FRAME_EVENT);
+}
diff --git a/src/haiku_support.h b/src/haiku_support.h
index cdeb40f67c..22f13c1ee6 100644
--- a/src/haiku_support.h
+++ b/src/haiku_support.h
@@ -219,8 +219,9 @@ struct haiku_iconification_event
 struct haiku_move_event
 {
   void *window;
-  int x;
-  int y;
+  int x, y;
+  int decorator_width;
+  int decorator_height;
 };
 
 struct haiku_wheel_move_event
@@ -688,6 +689,7 @@ extern status_t be_roster_launch (const char *, const char 
*, char **,
                                  ptrdiff_t, void *, team_id *);
 extern void be_get_window_decorator_dimensions (void *, int *, int *, int *, 
int *);
 extern void be_get_window_decorator_frame (void *, int *, int *, int *, int *);
+extern void be_send_move_frame_event (void *);
 
 #ifdef __cplusplus
 }
diff --git a/src/haikufns.c b/src/haikufns.c
index e8e303fd27..fa47da73d2 100644
--- a/src/haikufns.c
+++ b/src/haikufns.c
@@ -109,22 +109,15 @@ get_geometry_from_preferences (struct haiku_display_info 
*dpyinfo,
 static void
 haiku_update_after_decoration_change (struct frame *f)
 {
-  int x, y, width, height;
-  struct frame *parent;
+  /* Don't reset offsets during initial frame creation, since the
+     contents of f->left_pos and f->top_pos won't be applied to the
+     window until `x-create-frame' finishes, so setting them here will
+     overwrite the offsets that the window should be moved to.  */
 
-  be_get_window_decorator_frame (FRAME_HAIKU_WINDOW (f),
-                                &x, &y, &width, &height);
-
-  parent = FRAME_PARENT_FRAME (f);
-
-  if (parent)
-    {
-      x = x - FRAME_OUTPUT_DATA (f)->frame_x;
-      y = y - FRAME_OUTPUT_DATA (f)->frame_x;
-    }
+  if (!FRAME_OUTPUT_DATA (f)->configury_done)
+    return;
 
-  f->left_pos = x;
-  f->top_pos = y;
+  be_send_move_frame_event (FRAME_HAIKU_WINDOW (f));
 }
 
 void
diff --git a/src/haikuterm.c b/src/haikuterm.c
index d46228d02e..0952392210 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -3553,7 +3553,7 @@ haiku_read_socket (struct terminal *terminal, struct 
input_event *hold_quit)
          {
            struct haiku_move_event *b = buf;
            struct frame *f = haiku_window_to_frame (b->window);
-           int decorator_width, decorator_height, top, left;
+           int top, left;
            struct frame *p;
 
            if (!f)
@@ -3565,12 +3565,8 @@ haiku_read_socket (struct terminal *terminal, struct 
input_event *hold_quit)
            if (FRAME_PARENT_FRAME (f))
              haiku_coords_from_parent (f, &b->x, &b->y);
 
-           be_get_window_decorator_dimensions (b->window, &decorator_width,
-                                               &decorator_height, NULL,
-                                               NULL);
-
-           left = b->x - decorator_width;
-           top = b->y - decorator_height;
+           left = b->x - b->decorator_width;
+           top = b->y - b->decorator_height;
 
            if (left != f->left_pos || top != f->top_pos)
              {



reply via email to

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