SET_FONT_INDICES = 3012,
SET_PREVIEW_DIALOG = 3013,
UPDATE_PREVIEW_DIALOG = 3014,
+ SEND_MOVE_FRAME_EVENT = 3015,
};
/* X11 keysyms that we use. */
haiku_write (WHEEL_MOVE_EVENT, &rq);
};
}
+ else if (msg->what == SEND_MOVE_FRAME_EVENT)
+ FrameMoved (Frame ().LeftTop ());
else
BWindow::DispatchMessage (msg, handler);
}
}
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 ();
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);
+}
struct haiku_move_event
{
void *window;
- int x;
- int y;
+ int x, y;
+ int decorator_width;
+ int decorator_height;
};
struct haiku_wheel_move_event
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
}
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
{
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)
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)
{