[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 4dfaefcffc: Fix race conditions processing frame fullscreen state
From: |
Po Lu |
Subject: |
master 4dfaefcffc: Fix race conditions processing frame fullscreen state on Haiku |
Date: |
Wed, 18 May 2022 23:44:03 -0400 (EDT) |
branch: master
commit 4dfaefcffc987400a317b5ccf0c9bf00f7c84134
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
Fix race conditions processing frame fullscreen state on Haiku
* doc/lispref/frames.texi (Size Parameters): Remove note saying
Haiku doesn't support `fullwidth' and `fullboth'.
* src/haiku_support.cc (subset_windows, class EmacsWindow)
(Unparent, ParentTo): Stop calling old fullscreen functions.
(ClearFullscreen, FullscreenRectForMode, SetFullscreen): New
functions. Completely rewrite old zoom and fullscreen handling
code.
(Zoom): Send a ZOOM_EVENT and don't actually zoom.
(BWindow_zoom, EmacsWindow_make_fullscreen, EmacsWindow_unzoom):
Delete functions.
(be_set_window_fullscreen_mode): New function.
* src/haiku_support.h (struct haiku_zoom_event): Remove
`zoomed_p' parameter.
(enum haiku_fullscreen_mode): New enum. Update prototypes.
* src/haikufns.c (Fx_display_pixel_height): Return height
instead of width.
* src/haikuterm.c (haiku_make_fullscreen_consistent)
(haiku_read_socket, haiku_fullscreen): Adjust to always set zoom
and fullscreen in the main thread instead of the UI threads.
* src/haikuterm.h (struct haiku_output): Remove flag `zoomed_p'
and add field `fullscreen_mode'.
---
doc/lispref/frames.texi | 14 ++-
src/haiku_support.cc | 242 ++++++++++++++++++++++++------------------------
src/haiku_support.h | 14 ++-
src/haikufns.c | 2 +-
src/haikuterm.c | 47 +++++++---
src/haikuterm.h | 11 ++-
6 files changed, 183 insertions(+), 147 deletions(-)
diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index 5853c45b79..5ea060871f 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -1734,16 +1734,14 @@ fit will be clipped by the window manager.
@item fullscreen
This parameter specifies whether to maximize the frame's width, height
or both. Its value can be @code{fullwidth}, @code{fullheight},
-@code{fullboth}, or @code{maximized}.@footnote{On Haiku, setting
-@code{fullscreen} to @code{fullwidth} or @code{fullheight} has no
-effect.} A @dfn{fullwidth} frame is as
+@code{fullboth}, or @code{maximized}. A @dfn{fullwidth} frame is as
wide as possible, a @dfn{fullheight} frame is as tall as possible, and
a @dfn{fullboth} frame is both as wide and as tall as possible. A
-@dfn{maximized} frame is like a ``fullboth'' frame, except that it usually
-keeps its title bar and the buttons for resizing
-and closing the frame. Also, maximized frames typically avoid hiding
-any task bar or panels displayed on the desktop. A ``fullboth'' frame,
-on the other hand, usually omits the title bar and occupies the entire
+@dfn{maximized} frame is like a ``fullboth'' frame, except that it
+usually keeps its title bar and the buttons for resizing and closing
+the frame. Also, maximized frames typically avoid hiding any task bar
+or panels displayed on the desktop. A ``fullboth'' frame, on the
+other hand, usually omits the title bar and occupies the entire
available screen space.
Full-height and full-width frames are more similar to maximized
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index 0c126dab3d..0b3ab4cf4a 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public
License
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <config.h>
+#include <attribute.h>
#include <app/Application.h>
#include <app/Cursor.h>
@@ -518,33 +519,42 @@ public:
struct child_frame *next;
int xoff, yoff;
EmacsWindow *window;
- } *subset_windows = NULL;
+ } *subset_windows;
- EmacsWindow *parent = NULL;
+ EmacsWindow *parent;
BRect pre_fullscreen_rect;
BRect pre_zoom_rect;
- int x_before_zoom = INT_MIN;
- int y_before_zoom = INT_MIN;
- bool fullscreen_p = false;
- bool zoomed_p = false;
- bool shown_flag = false;
- volatile int was_shown_p = 0;
- bool menu_bar_active_p = false;
- bool override_redirect_p = false;
+ int x_before_zoom;
+ int y_before_zoom;
+ bool shown_flag;
+ volatile bool was_shown_p;
+ bool menu_bar_active_p;
+ bool override_redirect_p;
window_look pre_override_redirect_look;
window_feel pre_override_redirect_feel;
uint32 pre_override_redirect_workspaces;
int window_id;
- bool *menus_begun = NULL;
+ bool *menus_begun;
enum haiku_z_group z_group;
- bool tooltip_p = false;
+ bool tooltip_p;
+ enum haiku_fullscreen_mode fullscreen_mode;
EmacsWindow () : BWindow (BRect (0, 0, 0, 0), "", B_TITLED_WINDOW_LOOK,
- B_NORMAL_WINDOW_FEEL,
B_NO_SERVER_SIDE_WINDOW_MODIFIERS)
+ B_NORMAL_WINDOW_FEEL,
B_NO_SERVER_SIDE_WINDOW_MODIFIERS),
+ subset_windows (NULL),
+ parent (NULL),
+ x_before_zoom (INT_MIN),
+ y_before_zoom (INT_MIN),
+ shown_flag (false),
+ was_shown_p (false),
+ menu_bar_active_p (false),
+ override_redirect_p (false),
+ window_id (current_window_id),
+ menus_begun (NULL),
+ z_group (Z_GROUP_NONE),
+ tooltip_p (false),
+ fullscreen_mode (FULLSCREEN_MODE_NONE)
{
- window_id = current_window_id++;
- z_group = Z_GROUP_NONE;
-
/* This pulse rate is used by scroll bars for repeating a button
action while a button is held down. */
SetPulseRate (30000);
@@ -711,12 +721,6 @@ public:
RecomputeFeel ();
UpwardsUnSubsetChildren (parent);
this->RemoveFromSubset (this);
-
- if (fullscreen_p)
- {
- fullscreen_p = 0;
- MakeFullscreen (1);
- }
child_frame_lock.Unlock ();
}
@@ -766,11 +770,6 @@ public:
this->AddToSubset (this);
if (!IsHidden () && this->parent)
UpwardsSubsetChildren (parent);
- if (fullscreen_p)
- {
- fullscreen_p = 0;
- MakeFullscreen (1);
- }
window->LinkChild (this);
child_frame_lock.Unlock ();
@@ -1161,41 +1160,103 @@ public:
}
void
- Zoom (BPoint o, float w, float h)
+ ClearFullscreen (void)
{
- struct haiku_zoom_event rq;
- BRect rect;
- rq.window = this;
+ switch (fullscreen_mode)
+ {
+ case FULLSCREEN_MODE_MAXIMIZED:
+ BWindow::Zoom (pre_zoom_rect.LeftTop (),
+ BE_RECT_WIDTH (pre_zoom_rect) - 1,
+ BE_RECT_HEIGHT (pre_zoom_rect) - 1);
+ break;
- if (fullscreen_p)
- MakeFullscreen (0);
+ case FULLSCREEN_MODE_BOTH:
+ case FULLSCREEN_MODE_HEIGHT:
+ case FULLSCREEN_MODE_WIDTH:
+ MoveTo (pre_fullscreen_rect.LeftTop ());
+ ResizeTo (BE_RECT_WIDTH (pre_fullscreen_rect) - 1,
+ BE_RECT_HEIGHT (pre_fullscreen_rect) - 1);
- if (!zoomed_p)
- {
- pre_zoom_rect = Frame ();
- zoomed_p = true;
- rect = CalculateZoomRect ();
- }
- else
- {
- zoomed_p = false;
- rect = pre_zoom_rect;
+ SetFlags (Flags () & ~(B_NOT_MOVABLE
+ | B_NOT_ZOOMABLE
+ | B_NOT_RESIZABLE));
+ break;
+
+ case FULLSCREEN_MODE_NONE:
+ break;
}
- rq.zoomed = zoomed_p;
- haiku_write (ZOOM_EVENT, &rq);
+ fullscreen_mode = FULLSCREEN_MODE_NONE;
+ }
- BWindow::Zoom (rect.LeftTop (), BE_RECT_WIDTH (rect) - 1,
- BE_RECT_HEIGHT (rect) - 1);
+ BRect
+ FullscreenRectForMode (enum haiku_fullscreen_mode mode)
+ {
+ BScreen screen (this);
+ BRect frame;
+
+ if (!screen.IsValid ())
+ return BRect (0, 0, 0, 0);
+
+ frame = screen.Frame ();
+
+ if (mode == FULLSCREEN_MODE_HEIGHT)
+ frame.right -= BE_RECT_WIDTH (frame) / 2;
+ else if (mode == FULLSCREEN_MODE_WIDTH)
+ frame.bottom -= BE_RECT_HEIGHT (frame) / 2;
+
+ return frame;
}
void
- UnZoom (void)
+ SetFullscreen (enum haiku_fullscreen_mode mode)
{
- if (!zoomed_p)
+ BRect zoom_rect;
+
+ if (fullscreen_mode == mode)
return;
- BWindow::Zoom ();
+ ClearFullscreen ();
+
+ switch (mode)
+ {
+ case FULLSCREEN_MODE_MAXIMIZED:
+ pre_zoom_rect = Frame ();
+ zoom_rect = CalculateZoomRect ();
+ BWindow::Zoom (zoom_rect.LeftTop (),
+ BE_RECT_WIDTH (zoom_rect) - 1,
+ BE_RECT_HEIGHT (zoom_rect) - 1);
+ break;
+
+ case FULLSCREEN_MODE_BOTH:
+ SetFlags (Flags () | B_NOT_MOVABLE);
+ FALLTHROUGH;
+
+ case FULLSCREEN_MODE_HEIGHT:
+ case FULLSCREEN_MODE_WIDTH:
+ SetFlags (Flags () | B_NOT_ZOOMABLE | B_NOT_RESIZABLE);
+ pre_fullscreen_rect = Frame ();
+ zoom_rect = FullscreenRectForMode (mode);
+ ResizeTo (BE_RECT_WIDTH (zoom_rect) - 1,
+ BE_RECT_HEIGHT (zoom_rect) - 1);
+ MoveTo (zoom_rect.left, zoom_rect.top);
+
+ break;
+
+ case FULLSCREEN_MODE_NONE:
+ break;
+ }
+
+ fullscreen_mode = mode;
+ }
+
+ void
+ Zoom (BPoint o, float w, float h)
+ {
+ struct haiku_zoom_event rq;
+
+ rq.window = this;
+ haiku_write (ZOOM_EVENT, &rq);
}
void
@@ -1218,51 +1279,6 @@ public:
child_frame_lock.Lock ();
gui_abort ("Trying to calculate offsets for a child frame that doesn't
exist");
}
-
- void
- 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;
- flags = Flags ();
-
- if (fullscreen_p)
- {
- if (zoomed_p)
- UnZoom ();
-
- flags |= B_NOT_MOVABLE | B_NOT_ZOOMABLE;
- pre_fullscreen_rect = Frame ();
-
- MoveTo (0, 0);
- ResizeTo (BE_RECT_WIDTH (screen_frame) - 1,
- BE_RECT_HEIGHT (screen_frame) - 1);
- }
- else
- {
- flags &= ~(B_NOT_MOVABLE | B_NOT_ZOOMABLE);
-
- /* 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);
- }
- SetFlags (flags);
- }
};
class EmacsMenuBar : public BMenuBar
@@ -4486,30 +4502,6 @@ be_popup_file_dialog (int open_p, const char
*default_dir, int must_match_p,
return file_name;
}
-/* Zoom WINDOW. */
-void
-BWindow_zoom (void *window)
-{
- BWindow *w = (BWindow *) window;
- w->Zoom ();
-}
-
-/* Make WINDOW fullscreen if FULLSCREEN_P. */
-void
-EmacsWindow_make_fullscreen (void *window, int fullscreen_p)
-{
- EmacsWindow *w = (EmacsWindow *) window;
- w->MakeFullscreen (fullscreen_p);
-}
-
-/* Unzoom (maximize) WINDOW. */
-void
-EmacsWindow_unzoom (void *window)
-{
- EmacsWindow *w = (EmacsWindow *) window;
- w->UnZoom ();
-}
-
/* Move the pointer into MBAR and start tracking. Return whether the
menu bar was opened correctly. */
bool
@@ -5180,3 +5172,15 @@ be_unlock_window (void *window)
wnd->UnlockLooper ();
}
+
+void
+be_set_window_fullscreen_mode (void *window, enum haiku_fullscreen_mode mode)
+{
+ EmacsWindow *w = (EmacsWindow *) window;
+
+ if (!w->LockLooper ())
+ gui_abort ("Failed to lock window to set fullscreen mode");
+
+ w->SetFullscreen (mode);
+ w->UnlockLooper ();
+}
diff --git a/src/haiku_support.h b/src/haiku_support.h
index 14dd36e275..0bfd027c0d 100644
--- a/src/haiku_support.h
+++ b/src/haiku_support.h
@@ -249,7 +249,6 @@ struct haiku_menu_bar_help_event
struct haiku_zoom_event
{
void *window;
- bool zoomed;
};
enum haiku_font_specification
@@ -316,6 +315,15 @@ enum haiku_font_weight
HAIKU_MEDIUM = 2000,
};
+enum haiku_fullscreen_mode
+ {
+ FULLSCREEN_MODE_NONE,
+ FULLSCREEN_MODE_WIDTH,
+ FULLSCREEN_MODE_HEIGHT,
+ FULLSCREEN_MODE_BOTH,
+ FULLSCREEN_MODE_MAXIMIZED,
+ };
+
struct haiku_font_pattern
{
/* Bitmask indicating which fields are set. */
@@ -495,7 +503,6 @@ extern void BWindow_center_on_screen (void *);
extern void BWindow_change_decoration (void *, int);
extern void BWindow_set_tooltip_decoration (void *);
extern void BWindow_set_avoid_focus (void *, int);
-extern void BWindow_zoom (void *);
extern void BWindow_set_size_alignment (void *, int, int);
extern void BWindow_sync (void *);
extern void BWindow_send_behind (void *, void *);
@@ -623,8 +630,6 @@ extern void BAlert_delete (void *);
extern void EmacsWindow_parent_to (void *, void *);
extern void EmacsWindow_unparent (void *);
extern void EmacsWindow_move_weak_child (void *, void *, int, int);
-extern void EmacsWindow_make_fullscreen (void *, int);
-extern void EmacsWindow_unzoom (void *);
extern void be_get_version_string (char *, int);
extern int be_get_display_planes (void);
@@ -690,6 +695,7 @@ extern status_t be_roster_launch (const char *, const char
*, char **,
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 *);
+extern void be_set_window_fullscreen_mode (void *, enum haiku_fullscreen_mode);
extern void be_lock_window (void *);
extern void be_unlock_window (void *);
diff --git a/src/haikufns.c b/src/haikufns.c
index 76a8569970..314152008b 100644
--- a/src/haikufns.c
+++ b/src/haikufns.c
@@ -2281,7 +2281,7 @@ DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
Sx_display_pixel_heigh
check_haiku_display_info (terminal);
be_get_screen_dimensions (&width, &height);
- return make_fixnum (width);
+ return make_fixnum (height);
}
DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0,
1, 0,
diff --git a/src/haikuterm.c b/src/haikuterm.c
index 2db1e352ff..731afd9d39 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -3018,11 +3018,20 @@ static struct redisplay_interface
haiku_redisplay_interface =
static void
haiku_make_fullscreen_consistent (struct frame *f)
{
- Lisp_Object lval = get_frame_param (f, Qfullscreen);
-
- if (!EQ (lval, Qmaximized) && FRAME_OUTPUT_DATA (f)->zoomed_p)
+ Lisp_Object lval;
+ struct haiku_output *output;
+
+ output = FRAME_OUTPUT_DATA (f);
+
+ if (output->fullscreen_mode == FULLSCREEN_MODE_BOTH)
+ lval = Qfullboth;
+ else if (output->fullscreen_mode == FULLSCREEN_MODE_WIDTH)
+ lval = Qfullwidth;
+ else if (output->fullscreen_mode == FULLSCREEN_MODE_HEIGHT)
+ lval = Qfullheight;
+ else if (output->fullscreen_mode == FULLSCREEN_MODE_MAXIMIZED)
lval = Qmaximized;
- else if (EQ (lval, Qmaximized) && !FRAME_OUTPUT_DATA (f)->zoomed_p)
+ else
lval = Qnil;
store_frame_param (f, Qfullscreen, lval);
@@ -3857,14 +3866,20 @@ haiku_read_socket (struct terminal *terminal, struct
input_event *hold_quit)
case ZOOM_EVENT:
{
struct haiku_zoom_event *b = buf;
-
struct frame *f = haiku_window_to_frame (b->window);
+ struct haiku_output *output;
if (!f)
continue;
- FRAME_OUTPUT_DATA (f)->zoomed_p = b->zoomed;
- haiku_make_fullscreen_consistent (f);
+ output = FRAME_OUTPUT_DATA (f);
+
+ if (output->fullscreen_mode == FULLSCREEN_MAXIMIZED)
+ f->want_fullscreen = FULLSCREEN_NONE;
+ else
+ f->want_fullscreen = FULLSCREEN_MAXIMIZED;
+
+ FRAME_TERMINAL (f)->fullscreen_hook (f);
break;
}
case DRAG_AND_DROP_EVENT:
@@ -4096,6 +4111,8 @@ haiku_toggle_invisible_pointer (struct frame *f, bool
invisible_p)
static void
haiku_fullscreen (struct frame *f)
{
+ enum haiku_fullscreen_mode mode;
+
/* When FRAME_OUTPUT_DATA (f)->configury_done is false, the frame is
being created, and its regular width and height have not yet been
set. This function will be called again by haiku_create_frame,
@@ -4104,18 +4121,22 @@ haiku_fullscreen (struct frame *f)
return;
if (f->want_fullscreen == FULLSCREEN_MAXIMIZED)
- BWindow_zoom (FRAME_HAIKU_WINDOW (f));
+ mode = FULLSCREEN_MODE_MAXIMIZED;
else if (f->want_fullscreen == FULLSCREEN_BOTH)
- EmacsWindow_make_fullscreen (FRAME_HAIKU_WINDOW (f), 1);
+ mode = FULLSCREEN_MODE_BOTH;
+ else if (f->want_fullscreen == FULLSCREEN_WIDTH)
+ mode = FULLSCREEN_MODE_WIDTH;
+ else if (f->want_fullscreen == FULLSCREEN_HEIGHT)
+ mode = FULLSCREEN_MODE_HEIGHT;
else
- {
- EmacsWindow_make_fullscreen (FRAME_HAIKU_WINDOW (f), 0);
- EmacsWindow_unzoom (FRAME_HAIKU_WINDOW (f));
- }
+ mode = FULLSCREEN_MODE_NONE;
f->want_fullscreen = FULLSCREEN_NONE;
+ be_set_window_fullscreen_mode (FRAME_HAIKU_WINDOW (f), mode);
+ FRAME_OUTPUT_DATA (f)->fullscreen_mode = mode;
haiku_update_size_hints (f);
+ haiku_make_fullscreen_consistent (f);
}
static struct terminal *
diff --git a/src/haikuterm.h b/src/haikuterm.h
index 068be82687..41b1a85b00 100644
--- a/src/haikuterm.h
+++ b/src/haikuterm.h
@@ -160,13 +160,16 @@ struct haiku_output
int fontset;
int baseline_offset;
- bool_bf zoomed_p : 1;
+ /* Whether or not the hourglass cursor is currently being
+ displayed. */
bool_bf hourglass_p : 1;
+
+ /* Whether or not the menu bar is open. */
bool_bf menu_bar_open_p : 1;
/* Whether or not there is data in a back buffer that hasn't been
displayed yet. */
- bool dirty_p;
+ bool_bf dirty_p : 1;
struct font *font;
@@ -201,6 +204,10 @@ struct haiku_output
and top_pos in that the decorator and parent frames are not taken
into account. */
int frame_x, frame_y;
+
+ /* The current fullscreen mode of this frame. This should be `enum
+ haiku_fullscreen_mode', but that isn't available here. */
+ int fullscreen_mode;
};
struct x_output
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 4dfaefcffc: Fix race conditions processing frame fullscreen state on Haiku,
Po Lu <=