mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-01-06 11:55:48 +00:00
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.
This commit is contained in:
parent
2414fa3603
commit
5c656182ce
@ -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 @@ class EmacsWindow : public BWindow
|
||||
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 @@ class EmacsWindow : public BWindow
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
if (!FRAME_OUTPUT_DATA (f)->configury_done)
|
||||
return;
|
||||
|
||||
parent = FRAME_PARENT_FRAME (f);
|
||||
|
||||
if (parent)
|
||||
{
|
||||
x = x - FRAME_OUTPUT_DATA (f)->frame_x;
|
||||
y = y - FRAME_OUTPUT_DATA (f)->frame_x;
|
||||
}
|
||||
|
||||
f->left_pos = x;
|
||||
f->top_pos = y;
|
||||
be_send_move_frame_event (FRAME_HAIKU_WINDOW (f));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user