Rewrite Haiku frame geometry code to handle decorator frames
* doc/lispref/frames.texi (Frame Layout): Document changes to Haiku frame layout. * src/haiku_support.cc (class EmacsWindow, MoveToIncludingFrame) (EmacsMoveTo, MakeFullscreen): Move to an offset including the decorator frames. (be_get_window_decorator_dimensions): (be_get_window_decorator_frame): New functions. * src/haiku_support.h: Update prototypes. * src/haikufns.c (haiku_update_after_decoration_change): New function. (haiku_create_frame, haiku_set_undecorated) (haiku_set_override_redirect): Call that function. (frame_geometry): Actually calculate frame geometry based on decorator and frame sizes. * src/haikuterm.c (haiku_coords_from_parent): Use frame width instead. (haiku_read_socket): Set left and top positions based on decorator width and height. * src/haikuterm.h (struct haiku_output): New field `frame_x' and `frame_y'.
This commit is contained in:
parent
dc239872cc
commit
e9ad64ef92
6 changed files with 205 additions and 103 deletions
|
@ -683,9 +683,9 @@ The position of the top left corner of the native frame specifies the
|
|||
indicate that position for the various builds:
|
||||
|
||||
@itemize @w{}
|
||||
@item (1) non-toolkit and terminal frames
|
||||
@item (1) non-toolkit, Haiku, and terminal frames
|
||||
|
||||
@item (2) Lucid, Motif, MS-Windows, and Haiku frames
|
||||
@item (2) Lucid, Motif, and MS-Windows frames
|
||||
|
||||
@item (3) GTK+ and NS frames
|
||||
@end itemize
|
||||
|
|
|
@ -795,12 +795,24 @@ class EmacsWindow : public BWindow
|
|||
subset_windows = f;
|
||||
}
|
||||
|
||||
void
|
||||
MoveToIncludingFrame (int x, int y)
|
||||
{
|
||||
BRect decorator, frame;
|
||||
|
||||
decorator = DecoratorFrame ();
|
||||
frame = Frame ();
|
||||
|
||||
MoveTo (x + frame.left - decorator.left,
|
||||
y + frame.top - decorator.top);
|
||||
}
|
||||
|
||||
void
|
||||
DoMove (struct child_frame *f)
|
||||
{
|
||||
BRect frame = this->Frame ();
|
||||
f->window->MoveTo (frame.left + f->xoff,
|
||||
frame.top + f->yoff);
|
||||
f->window->MoveToIncludingFrame (frame.left + f->xoff,
|
||||
frame.top + f->yoff);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1062,7 +1074,7 @@ class EmacsWindow : public BWindow
|
|||
gui_abort ("Failed to lock child frame state lock");
|
||||
|
||||
if (!this->parent)
|
||||
this->MoveTo (x, y);
|
||||
this->MoveToIncludingFrame (x, y);
|
||||
else
|
||||
this->parent->MoveChild (this, x, y, 0);
|
||||
child_frame_lock.Unlock ();
|
||||
|
@ -1172,30 +1184,6 @@ class EmacsWindow : public BWindow
|
|||
BWindow::Zoom ();
|
||||
}
|
||||
|
||||
void
|
||||
GetParentWidthHeight (int *width, int *height)
|
||||
{
|
||||
if (!child_frame_lock.Lock ())
|
||||
gui_abort ("Failed to lock child frame state lock");
|
||||
|
||||
if (parent)
|
||||
{
|
||||
BRect frame = parent->Frame ();
|
||||
*width = BE_RECT_WIDTH (frame);
|
||||
*height = BE_RECT_HEIGHT (frame);
|
||||
}
|
||||
else
|
||||
{
|
||||
BScreen s (this);
|
||||
BRect frame = s.Frame ();
|
||||
|
||||
*width = BE_RECT_WIDTH (frame);
|
||||
*height = BE_RECT_HEIGHT (frame);
|
||||
}
|
||||
|
||||
child_frame_lock.Unlock ();
|
||||
}
|
||||
|
||||
void
|
||||
OffsetChildRect (BRect *r, EmacsWindow *c)
|
||||
{
|
||||
|
@ -1221,17 +1209,21 @@ class EmacsWindow : public BWindow
|
|||
MakeFullscreen (int make_fullscreen_p)
|
||||
{
|
||||
BScreen screen (this);
|
||||
uint32 flags;
|
||||
BRect screen_frame;
|
||||
|
||||
if (!screen.IsValid ())
|
||||
gui_abort ("Trying to make a window fullscreen without a screen");
|
||||
|
||||
screen_frame = screen.Frame ();
|
||||
UnZoom ();
|
||||
|
||||
if (make_fullscreen_p == fullscreen_p)
|
||||
return;
|
||||
|
||||
fullscreen_p = make_fullscreen_p;
|
||||
uint32 flags = Flags ();
|
||||
flags = Flags ();
|
||||
|
||||
if (fullscreen_p)
|
||||
{
|
||||
if (zoomed_p)
|
||||
|
@ -1240,24 +1232,18 @@ class EmacsWindow : public BWindow
|
|||
flags |= B_NOT_MOVABLE | B_NOT_ZOOMABLE;
|
||||
pre_fullscreen_rect = Frame ();
|
||||
|
||||
if (!child_frame_lock.Lock ())
|
||||
gui_abort ("Failed to lock child frame state lock");
|
||||
|
||||
if (parent)
|
||||
parent->OffsetChildRect (&pre_fullscreen_rect, this);
|
||||
|
||||
child_frame_lock.Unlock ();
|
||||
|
||||
int w, h;
|
||||
EmacsMoveTo (0, 0);
|
||||
GetParentWidthHeight (&w, &h);
|
||||
ResizeTo (w - 1, h - 1);
|
||||
MoveTo (0, 0);
|
||||
ResizeTo (BE_RECT_WIDTH (screen_frame) - 1,
|
||||
BE_RECT_HEIGHT (screen_frame) - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
flags &= ~(B_NOT_MOVABLE | B_NOT_ZOOMABLE);
|
||||
EmacsMoveTo (pre_fullscreen_rect.left,
|
||||
pre_fullscreen_rect.top);
|
||||
|
||||
/* Use MoveTo directly since pre_fullscreen_rect isn't
|
||||
adjusted for decorator sizes. */
|
||||
MoveTo (pre_fullscreen_rect.left,
|
||||
pre_fullscreen_rect.top);
|
||||
ResizeTo (BE_RECT_WIDTH (pre_fullscreen_rect) - 1,
|
||||
BE_RECT_HEIGHT (pre_fullscreen_rect) - 1);
|
||||
}
|
||||
|
@ -5097,3 +5083,55 @@ be_create_pixmap_cursor (void *bitmap, int x, int y)
|
|||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
void
|
||||
be_get_window_decorator_dimensions (void *window, int *left, int *top,
|
||||
int *right, int *bottom)
|
||||
{
|
||||
BWindow *wnd;
|
||||
BRect frame, window_frame;
|
||||
|
||||
wnd = (BWindow *) window;
|
||||
|
||||
if (!wnd->LockLooper ())
|
||||
gui_abort ("Failed to lock window looper frame");
|
||||
|
||||
frame = wnd->DecoratorFrame ();
|
||||
window_frame = wnd->Frame ();
|
||||
|
||||
if (left)
|
||||
*left = window_frame.left - frame.left;
|
||||
|
||||
if (top)
|
||||
*top = window_frame.top - frame.top;
|
||||
|
||||
if (right)
|
||||
*right = frame.right - window_frame.right;
|
||||
|
||||
if (bottom)
|
||||
*bottom = frame.bottom - window_frame.bottom;
|
||||
|
||||
wnd->UnlockLooper ();
|
||||
}
|
||||
|
||||
void
|
||||
be_get_window_decorator_frame (void *window, int *left, int *top,
|
||||
int *width, int *height)
|
||||
{
|
||||
BWindow *wnd;
|
||||
BRect frame;
|
||||
|
||||
wnd = (BWindow *) window;
|
||||
|
||||
if (!wnd->LockLooper ())
|
||||
gui_abort ("Failed to lock window looper frame");
|
||||
|
||||
frame = wnd->DecoratorFrame ();
|
||||
|
||||
*left = frame.left;
|
||||
*top = frame.top;
|
||||
*width = BE_RECT_WIDTH (frame);
|
||||
*height = BE_RECT_HEIGHT (frame);
|
||||
|
||||
wnd->UnlockLooper ();
|
||||
}
|
||||
|
|
|
@ -686,6 +686,9 @@ extern bool be_select_font (void (*) (void), bool (*) (void),
|
|||
extern int be_find_font_indices (struct haiku_font_pattern *, int *, int *);
|
||||
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 *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
|
|
132
src/haikufns.c
132
src/haikufns.c
|
@ -104,6 +104,29 @@ get_geometry_from_preferences (struct haiku_display_info *dpyinfo,
|
|||
return parms;
|
||||
}
|
||||
|
||||
/* Update the left and top offsets of F after its decorators
|
||||
change. */
|
||||
static void
|
||||
haiku_update_after_decoration_change (struct frame *f)
|
||||
{
|
||||
int x, y, width, height;
|
||||
struct frame *parent;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
f->left_pos = x;
|
||||
f->top_pos = y;
|
||||
}
|
||||
|
||||
void
|
||||
haiku_change_tool_bar_height (struct frame *f, int height)
|
||||
{
|
||||
|
@ -827,10 +850,7 @@ haiku_create_frame (Lisp_Object parms)
|
|||
|
||||
f->terminal->reference_count++;
|
||||
|
||||
block_input ();
|
||||
FRAME_OUTPUT_DATA (f)->window
|
||||
= BWindow_new (&FRAME_OUTPUT_DATA (f)->view);
|
||||
unblock_input ();
|
||||
FRAME_OUTPUT_DATA (f)->window = BWindow_new (&FRAME_OUTPUT_DATA (f)->view);
|
||||
|
||||
if (!FRAME_OUTPUT_DATA (f)->window)
|
||||
xsignal1 (Qerror, build_unibyte_string ("Could not create window"));
|
||||
|
@ -842,7 +862,8 @@ haiku_create_frame (Lisp_Object parms)
|
|||
|
||||
Vframe_list = Fcons (frame, Vframe_list);
|
||||
|
||||
Lisp_Object parent_frame = gui_display_get_arg (dpyinfo, parms, Qparent_frame, NULL, NULL,
|
||||
Lisp_Object parent_frame = gui_display_get_arg (dpyinfo, parms,
|
||||
Qparent_frame, NULL, NULL,
|
||||
RES_TYPE_SYMBOL);
|
||||
|
||||
if (EQ (parent_frame, Qunbound)
|
||||
|
@ -1315,6 +1336,8 @@ haiku_set_undecorated (struct frame *f, Lisp_Object new_value,
|
|||
FRAME_UNDECORATED (f) = !NILP (new_value);
|
||||
BWindow_change_decoration (FRAME_HAIKU_WINDOW (f), NILP (new_value));
|
||||
unblock_input ();
|
||||
|
||||
haiku_update_after_decoration_change (f);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1329,6 +1352,8 @@ haiku_set_override_redirect (struct frame *f, Lisp_Object new_value,
|
|||
!NILP (new_value));
|
||||
FRAME_OVERRIDE_REDIRECT (f) = !NILP (new_value);
|
||||
unblock_input ();
|
||||
|
||||
haiku_update_after_decoration_change (f);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1375,47 +1400,74 @@ haiku_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval
|
|||
static Lisp_Object
|
||||
frame_geometry (Lisp_Object frame, Lisp_Object attribute)
|
||||
{
|
||||
struct frame *f = decode_live_frame (frame);
|
||||
check_window_system (f);
|
||||
struct frame *f, *parent;
|
||||
int outer_x, outer_y, outer_width, outer_height;
|
||||
int right_off, bottom_off, top_off;
|
||||
int native_x, native_y;
|
||||
|
||||
f = decode_window_system_frame (frame);
|
||||
parent = FRAME_PARENT_FRAME (f);
|
||||
|
||||
be_get_window_decorator_frame (FRAME_HAIKU_WINDOW (f), &outer_x,
|
||||
&outer_y, &outer_width, &outer_height);
|
||||
be_get_window_decorator_dimensions (FRAME_HAIKU_WINDOW (f), NULL,
|
||||
&top_off, &right_off, &bottom_off);
|
||||
native_x = FRAME_OUTPUT_DATA (f)->frame_x;
|
||||
native_y = FRAME_OUTPUT_DATA (f)->frame_y;
|
||||
|
||||
if (parent)
|
||||
{
|
||||
/* Adjust all the coordinates by the coordinates of the parent
|
||||
frame. */
|
||||
outer_x -= FRAME_OUTPUT_DATA (parent)->frame_x;
|
||||
outer_y -= FRAME_OUTPUT_DATA (parent)->frame_y;
|
||||
native_x -= FRAME_OUTPUT_DATA (parent)->frame_x;
|
||||
native_y -= FRAME_OUTPUT_DATA (parent)->frame_y;
|
||||
}
|
||||
|
||||
if (EQ (attribute, Qouter_edges))
|
||||
return list4i (f->left_pos, f->top_pos,
|
||||
f->left_pos, f->top_pos);
|
||||
return list4i (outer_x, outer_y,
|
||||
outer_x + outer_width,
|
||||
outer_y + outer_height);
|
||||
else if (EQ (attribute, Qnative_edges))
|
||||
return list4i (f->left_pos, f->top_pos,
|
||||
f->left_pos + FRAME_PIXEL_WIDTH (f),
|
||||
f->top_pos + FRAME_PIXEL_HEIGHT (f));
|
||||
return list4i (native_x, native_y,
|
||||
native_x + FRAME_PIXEL_WIDTH (f),
|
||||
native_y + FRAME_PIXEL_HEIGHT (f));
|
||||
else if (EQ (attribute, Qinner_edges))
|
||||
return list4i (f->left_pos + FRAME_INTERNAL_BORDER_WIDTH (f),
|
||||
f->top_pos + FRAME_INTERNAL_BORDER_WIDTH (f) +
|
||||
FRAME_MENU_BAR_HEIGHT (f) + FRAME_TOOL_BAR_HEIGHT (f),
|
||||
f->left_pos - FRAME_INTERNAL_BORDER_WIDTH (f) +
|
||||
FRAME_PIXEL_WIDTH (f),
|
||||
f->top_pos + FRAME_PIXEL_HEIGHT (f) -
|
||||
FRAME_INTERNAL_BORDER_WIDTH (f));
|
||||
return list4i (native_x + FRAME_INTERNAL_BORDER_WIDTH (f),
|
||||
native_y + FRAME_INTERNAL_BORDER_WIDTH (f)
|
||||
+ FRAME_MENU_BAR_HEIGHT (f) + FRAME_TOOL_BAR_HEIGHT (f),
|
||||
native_x - FRAME_INTERNAL_BORDER_WIDTH (f)
|
||||
+ FRAME_PIXEL_WIDTH (f),
|
||||
native_y + FRAME_PIXEL_HEIGHT (f)
|
||||
- FRAME_INTERNAL_BORDER_WIDTH (f));
|
||||
|
||||
else
|
||||
return
|
||||
list (Fcons (Qouter_position,
|
||||
Fcons (make_fixnum (f->left_pos),
|
||||
make_fixnum (f->top_pos))),
|
||||
Fcons (Qouter_size,
|
||||
Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f)),
|
||||
make_fixnum (FRAME_PIXEL_HEIGHT (f)))),
|
||||
Fcons (Qexternal_border_size,
|
||||
Fcons (make_fixnum (0), make_fixnum (0))),
|
||||
Fcons (Qtitle_bar_size,
|
||||
Fcons (make_fixnum (0), make_fixnum (0))),
|
||||
Fcons (Qmenu_bar_external, Qnil),
|
||||
Fcons (Qmenu_bar_size, Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f) -
|
||||
(FRAME_INTERNAL_BORDER_WIDTH (f) * 2)),
|
||||
make_fixnum (FRAME_MENU_BAR_HEIGHT (f)))),
|
||||
Fcons (Qtool_bar_external, Qnil),
|
||||
Fcons (Qtool_bar_position, Qtop),
|
||||
Fcons (Qtool_bar_size, Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f) -
|
||||
(FRAME_INTERNAL_BORDER_WIDTH (f) * 2)),
|
||||
make_fixnum (FRAME_TOOL_BAR_HEIGHT (f)))),
|
||||
Fcons (Qinternal_border_width, make_fixnum (FRAME_INTERNAL_BORDER_WIDTH (f))));
|
||||
return list (Fcons (Qouter_position,
|
||||
Fcons (make_fixnum (outer_x),
|
||||
make_fixnum (outer_y))),
|
||||
Fcons (Qouter_size,
|
||||
Fcons (make_fixnum (outer_width),
|
||||
make_fixnum (outer_height))),
|
||||
Fcons (Qexternal_border_size,
|
||||
Fcons (make_fixnum (right_off),
|
||||
make_fixnum (bottom_off))),
|
||||
Fcons (Qtitle_bar_size,
|
||||
Fcons (make_fixnum (outer_width),
|
||||
make_fixnum (top_off))),
|
||||
Fcons (Qmenu_bar_external, Qnil),
|
||||
Fcons (Qmenu_bar_size,
|
||||
Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f)
|
||||
- (FRAME_INTERNAL_BORDER_WIDTH (f) * 2)),
|
||||
make_fixnum (FRAME_MENU_BAR_HEIGHT (f)))),
|
||||
Fcons (Qtool_bar_external, Qnil),
|
||||
Fcons (Qtool_bar_position, Qtop),
|
||||
Fcons (Qtool_bar_size,
|
||||
Fcons (make_fixnum (FRAME_PIXEL_WIDTH (f)
|
||||
- (FRAME_INTERNAL_BORDER_WIDTH (f) * 2)),
|
||||
make_fixnum (FRAME_TOOL_BAR_HEIGHT (f)))),
|
||||
Fcons (Qinternal_border_width,
|
||||
make_fixnum (FRAME_INTERNAL_BORDER_WIDTH (f))));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -96,14 +96,9 @@ static void
|
|||
haiku_coords_from_parent (struct frame *f, int *x, int *y)
|
||||
{
|
||||
struct frame *p = FRAME_PARENT_FRAME (f);
|
||||
eassert (p);
|
||||
|
||||
for (struct frame *parent = p; parent;
|
||||
parent = FRAME_PARENT_FRAME (parent))
|
||||
{
|
||||
*x -= parent->left_pos;
|
||||
*y -= parent->top_pos;
|
||||
}
|
||||
*x -= FRAME_OUTPUT_DATA (p)->frame_x;
|
||||
*y -= FRAME_OUTPUT_DATA (p)->frame_y;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -3535,7 +3530,6 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
|
|||
SET_FRAME_ICONIFIED (f, 0);
|
||||
inev.kind = DEICONIFY_EVENT;
|
||||
|
||||
|
||||
/* Haiku doesn't expose frames on deiconification, but
|
||||
if we are double-buffered, the previous screen
|
||||
contents should have been preserved. */
|
||||
|
@ -3559,30 +3553,40 @@ 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;
|
||||
struct frame *p;
|
||||
|
||||
if (!f)
|
||||
continue;
|
||||
|
||||
FRAME_OUTPUT_DATA (f)->frame_x = b->x;
|
||||
FRAME_OUTPUT_DATA (f)->frame_y = b->y;
|
||||
|
||||
if (FRAME_PARENT_FRAME (f))
|
||||
haiku_coords_from_parent (f, &b->x, &b->y);
|
||||
|
||||
if (b->x != f->left_pos || b->y != f->top_pos)
|
||||
be_get_window_decorator_dimensions (b->window, &decorator_width,
|
||||
&decorator_height, NULL,
|
||||
NULL);
|
||||
|
||||
left = b->x - decorator_width;
|
||||
top = b->y - decorator_height;
|
||||
|
||||
if (left != f->left_pos || top != f->top_pos)
|
||||
{
|
||||
inev.kind = MOVE_FRAME_EVENT;
|
||||
|
||||
XSETINT (inev.x, b->x);
|
||||
XSETINT (inev.y, b->y);
|
||||
XSETINT (inev.x, left);
|
||||
XSETINT (inev.y, top);
|
||||
|
||||
f->left_pos = b->x;
|
||||
f->top_pos = b->y;
|
||||
f->left_pos = left;
|
||||
f->top_pos = top;
|
||||
|
||||
struct frame *p;
|
||||
p = FRAME_PARENT_FRAME (f);
|
||||
|
||||
if ((p = FRAME_PARENT_FRAME (f)))
|
||||
{
|
||||
void *window = FRAME_HAIKU_WINDOW (p);
|
||||
EmacsWindow_move_weak_child (window, b->window, b->x, b->y);
|
||||
}
|
||||
if (p)
|
||||
EmacsWindow_move_weak_child (FRAME_HAIKU_WINDOW (p),
|
||||
b->window, left, top);
|
||||
|
||||
XSETFRAME (inev.frame_or_window, f);
|
||||
}
|
||||
|
|
|
@ -196,6 +196,11 @@ struct haiku_output
|
|||
They are changed only when a different background is involved.
|
||||
-1 means no color has been computed. */
|
||||
long relief_background;
|
||||
|
||||
/* The absolute position of this frame. This differs from left_pos
|
||||
and top_pos in that the decorator and parent frames are not taken
|
||||
into account. */
|
||||
int frame_x, frame_y;
|
||||
};
|
||||
|
||||
struct x_output
|
||||
|
|
Loading…
Add table
Reference in a new issue