From 3e3fe06307de183a4a4f9c7ead6a0d5c5adedfa9 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sat, 21 May 2022 06:28:06 +0000 Subject: [PATCH] Compute frame workareas on Haiku * lisp/frame.el (display-monitor-attributes-list): Implement specially on Haiku as well. * src/haiku_support.cc (get_zoom_rect): New function. Extract CalculateZoomRect here. (class EmacsWindow, SetFullscreen): Use that instead of CalculateZoomRect. (be_get_explicit_workarea): New function. * src/haiku_support.h: Update prototypes. * src/haikufns.c (Fhaiku_display_monitor_attributes_list): New function. (syms_of_haikufns): Register new subr. --- lisp/frame.el | 4 + src/haiku_support.cc | 170 +++++++++++++++++++++++++------------------ src/haiku_support.h | 1 + src/haikufns.c | 52 +++++++++++++ 4 files changed, 155 insertions(+), 72 deletions(-) diff --git a/lisp/frame.el b/lisp/frame.el index 094d67688c2..27f99fb7d21 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -2376,6 +2376,8 @@ If DISPLAY is omitted or nil, it defaults to the selected frame's display." (&optional terminal)) (declare-function pgtk-display-monitor-attributes-list "pgtkfns.c" (&optional terminal)) +(declare-function haiku-display-monitor-attributes-list "haikufns.c" + (&optional terminal)) (defun display-monitor-attributes-list (&optional display) "Return a list of physical monitor attributes on DISPLAY. @@ -2427,6 +2429,8 @@ monitors." (ns-display-monitor-attributes-list display)) ((eq frame-type 'pgtk) (pgtk-display-monitor-attributes-list display)) + ((eq frame-type 'haiku) + (haiku-display-monitor-attributes-list display)) (t (let ((geometry (list 0 0 (display-pixel-width display) (display-pixel-height display)))) diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 33c68cbd465..0c8e87154b2 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -449,6 +449,80 @@ map_normal (uint32_t kc, uint32_t *ch) key_map_lock.Unlock (); } +static BRect +get_zoom_rect (BWindow *window) +{ + BScreen screen; + BDeskbar deskbar; + BRect screen_frame; + BRect frame; + BRect deskbar_frame; + BRect window_frame; + BRect decorator_frame; + + if (!screen.IsValid ()) + gui_abort ("Failed to calculate screen rect"); + + screen_frame = frame = screen.Frame (); + deskbar_frame = deskbar.Frame (); + + if (!(modifiers () & B_SHIFT_KEY) && !deskbar.IsAutoHide ()) + { + switch (deskbar.Location ()) + { + case B_DESKBAR_TOP: + frame.top = deskbar_frame.bottom + 2; + break; + + case B_DESKBAR_BOTTOM: + case B_DESKBAR_LEFT_BOTTOM: + case B_DESKBAR_RIGHT_BOTTOM: + frame.bottom = deskbar_frame.top - 2; + break; + + case B_DESKBAR_LEFT_TOP: + if (!deskbar.IsExpanded ()) + frame.top = deskbar_frame.bottom + 2; + else if (!deskbar.IsAlwaysOnTop () + && !deskbar.IsAutoRaise ()) + frame.left = deskbar_frame.right + 2; + break; + + default: + if (deskbar.IsExpanded () + && !deskbar.IsAlwaysOnTop () + && !deskbar.IsAutoRaise ()) + frame.right = deskbar_frame.left - 2; + } + } + + if (window) + { + window_frame = window->Frame (); + decorator_frame = window->DecoratorFrame (); + + frame.top += (window_frame.top + - decorator_frame.top); + frame.bottom -= (decorator_frame.bottom + - window_frame.bottom); + frame.left += (window_frame.left + - decorator_frame.left); + frame.right -= (decorator_frame.right + - window_frame.right); + + if (frame.top > deskbar_frame.bottom + || frame.bottom < deskbar_frame.top) + { + frame.left = screen_frame.left + (window_frame.left + - decorator_frame.left); + frame.right = screen_frame.right - (decorator_frame.right + - window_frame.right); + } + } + + return frame; +} + class Emacs : public BApplication { public: @@ -593,77 +667,6 @@ public: SetFeel (B_NORMAL_WINDOW_FEEL); } - BRect - CalculateZoomRect (void) - { - BScreen screen (this); - BDeskbar deskbar; - BRect screen_frame; - BRect frame; - BRect deskbar_frame; - BRect window_frame; - BRect decorator_frame; - - if (!screen.IsValid ()) - gui_abort ("Failed to calculate screen rect"); - - screen_frame = frame = screen.Frame (); - deskbar_frame = deskbar.Frame (); - - if (!(modifiers () & B_SHIFT_KEY) && !deskbar.IsAutoHide ()) - { - switch (deskbar.Location ()) - { - case B_DESKBAR_TOP: - frame.top = deskbar_frame.bottom + 2; - break; - - case B_DESKBAR_BOTTOM: - case B_DESKBAR_LEFT_BOTTOM: - case B_DESKBAR_RIGHT_BOTTOM: - frame.bottom = deskbar_frame.top - 2; - break; - - case B_DESKBAR_LEFT_TOP: - if (!deskbar.IsExpanded ()) - frame.top = deskbar_frame.bottom + 2; - else if (!deskbar.IsAlwaysOnTop () - && !deskbar.IsAutoRaise ()) - frame.left = deskbar_frame.right + 2; - break; - - default: - if (deskbar.IsExpanded () - && !deskbar.IsAlwaysOnTop () - && !deskbar.IsAutoRaise ()) - frame.right = deskbar_frame.left - 2; - } - } - - window_frame = Frame (); - decorator_frame = DecoratorFrame (); - - frame.top += (window_frame.top - - decorator_frame.top); - frame.bottom -= (decorator_frame.bottom - - window_frame.bottom); - frame.left += (window_frame.left - - decorator_frame.left); - frame.right -= (decorator_frame.right - - window_frame.right); - - if (frame.top > deskbar_frame.bottom - || frame.bottom < deskbar_frame.top) - { - frame.left = screen_frame.left + (window_frame.left - - decorator_frame.left); - frame.right = screen_frame.right - (decorator_frame.right - - window_frame.right); - } - - return frame; - } - void UpwardsSubset (EmacsWindow *w) { @@ -1248,7 +1251,7 @@ public: { case FULLSCREEN_MODE_MAXIMIZED: pre_zoom_rect = frame; - zoom_rect = CalculateZoomRect (); + zoom_rect = get_zoom_rect (this); BWindow::Zoom (zoom_rect.LeftTop (), BE_RECT_WIDTH (zoom_rect) - 1, BE_RECT_HEIGHT (zoom_rect) - 1); @@ -5210,3 +5213,26 @@ be_set_window_fullscreen_mode (void *window, enum haiku_fullscreen_mode mode) w->SetFullscreen (mode); w->UnlockLooper (); } + +bool +be_get_explicit_workarea (int *x, int *y, int *width, int *height) +{ + BDeskbar deskbar; + BRect zoom; + deskbar_location location; + + location = deskbar.Location (); + + if (location != B_DESKBAR_TOP + && location != B_DESKBAR_BOTTOM) + return false; + + zoom = get_zoom_rect (NULL); + + *x = zoom.left; + *y = zoom.top; + *width = BE_RECT_WIDTH (zoom); + *height = BE_RECT_HEIGHT (zoom); + + return true; +} diff --git a/src/haiku_support.h b/src/haiku_support.h index 163685572f6..dbb12c24aa2 100644 --- a/src/haiku_support.h +++ b/src/haiku_support.h @@ -702,6 +702,7 @@ extern void be_set_window_fullscreen_mode (void *, enum haiku_fullscreen_mode); extern void be_lock_window (void *); extern void be_unlock_window (void *); +extern bool be_get_explicit_workarea (int *, int *, int *, int *); #ifdef __cplusplus } diff --git a/src/haikufns.c b/src/haikufns.c index 427ca7762da..7b1abb5cdc7 100644 --- a/src/haikufns.c +++ b/src/haikufns.c @@ -3021,6 +3021,57 @@ call this function yourself. */) return Qnil; } +DEFUN ("haiku-display-monitor-attributes-list", + Fhaiku_display_monitor_attributes_list, + Shaiku_display_monitor_attributes_list, + 0, 1, 0, + doc: /* Return a list of physical monitor attributes on the display TERMINAL. + +The optional argument TERMINAL specifies which display to ask about. +TERMINAL should be a terminal object, a frame or a display name (a string). +If omitted or nil, that stands for the selected frame's display. + +Internal use only, use `display-monitor-attributes-list' instead. */) + (Lisp_Object terminal) +{ + struct MonitorInfo monitor; + struct haiku_display_info *dpyinfo; + Lisp_Object frames, tail, tem; + + dpyinfo = check_haiku_display_info (terminal); + frames = Qnil; + + FOR_EACH_FRAME (tail, tem) + { + maybe_quit (); + + if (FRAME_HAIKU_P (XFRAME (tem)) + && !FRAME_TOOLTIP_P (XFRAME (tem))) + frames = Fcons (tem, frames); + } + + monitor.geom.x = 0; + monitor.geom.y = 0; + be_get_screen_dimensions ((int *) &monitor.geom.width, + (int *) &monitor.geom.height); + + monitor.mm_width = (monitor.geom.width + / (dpyinfo->resx / 25.4)); + monitor.mm_height = (monitor.geom.height + / (dpyinfo->resy / 25.4)); + monitor.name = (char *) "BeOS monitor"; + + if (!be_get_explicit_workarea ((int *) &monitor.work.x, + (int *) &monitor.work.y, + (int *) &monitor.work.width, + (int *) &monitor.work.height)) + monitor.work = monitor.geom; + + return make_monitor_attribute_list (&monitor, 1, 0, + make_vector (1, frames), + "fallback"); +} + frame_parm_handler haiku_frame_parm_handlers[] = { gui_set_autoraise, @@ -3126,6 +3177,7 @@ syms_of_haikufns (void) defsubr (&Sx_display_save_under); defsubr (&Shaiku_frame_restack); defsubr (&Shaiku_save_session_reply); + defsubr (&Shaiku_display_monitor_attributes_list); tip_timer = Qnil; staticpro (&tip_timer); -- 2.39.2