aboutsummaryrefslogtreecommitdiffstats
path: root/src/haiku_support.cc
diff options
context:
space:
mode:
authorPo Lu2022-05-19 03:43:39 +0000
committerPo Lu2022-05-19 03:43:39 +0000
commit4dfaefcffc987400a317b5ccf0c9bf00f7c84134 (patch)
tree590fe0f71a6fae3fdec4d64fa80e20875f136be9 /src/haiku_support.cc
parentbc604417f87f9fce865e70b3bc88b6bf2a8fd415 (diff)
downloademacs-4dfaefcffc987400a317b5ccf0c9bf00f7c84134.tar.gz
emacs-4dfaefcffc987400a317b5ccf0c9bf00f7c84134.zip
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'.
Diffstat (limited to 'src/haiku_support.cc')
-rw-r--r--src/haiku_support.cc242
1 files changed, 123 insertions, 119 deletions
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index 0c126dab3d6..0b3ab4cf4ae 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
17along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ 17along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
18 18
19#include <config.h> 19#include <config.h>
20#include <attribute.h>
20 21
21#include <app/Application.h> 22#include <app/Application.h>
22#include <app/Cursor.h> 23#include <app/Cursor.h>
@@ -518,33 +519,42 @@ public:
518 struct child_frame *next; 519 struct child_frame *next;
519 int xoff, yoff; 520 int xoff, yoff;
520 EmacsWindow *window; 521 EmacsWindow *window;
521 } *subset_windows = NULL; 522 } *subset_windows;
522 523
523 EmacsWindow *parent = NULL; 524 EmacsWindow *parent;
524 BRect pre_fullscreen_rect; 525 BRect pre_fullscreen_rect;
525 BRect pre_zoom_rect; 526 BRect pre_zoom_rect;
526 int x_before_zoom = INT_MIN; 527 int x_before_zoom;
527 int y_before_zoom = INT_MIN; 528 int y_before_zoom;
528 bool fullscreen_p = false; 529 bool shown_flag;
529 bool zoomed_p = false; 530 volatile bool was_shown_p;
530 bool shown_flag = false; 531 bool menu_bar_active_p;
531 volatile int was_shown_p = 0; 532 bool override_redirect_p;
532 bool menu_bar_active_p = false;
533 bool override_redirect_p = false;
534 window_look pre_override_redirect_look; 533 window_look pre_override_redirect_look;
535 window_feel pre_override_redirect_feel; 534 window_feel pre_override_redirect_feel;
536 uint32 pre_override_redirect_workspaces; 535 uint32 pre_override_redirect_workspaces;
537 int window_id; 536 int window_id;
538 bool *menus_begun = NULL; 537 bool *menus_begun;
539 enum haiku_z_group z_group; 538 enum haiku_z_group z_group;
540 bool tooltip_p = false; 539 bool tooltip_p;
540 enum haiku_fullscreen_mode fullscreen_mode;
541 541
542 EmacsWindow () : BWindow (BRect (0, 0, 0, 0), "", B_TITLED_WINDOW_LOOK, 542 EmacsWindow () : BWindow (BRect (0, 0, 0, 0), "", B_TITLED_WINDOW_LOOK,
543 B_NORMAL_WINDOW_FEEL, B_NO_SERVER_SIDE_WINDOW_MODIFIERS) 543 B_NORMAL_WINDOW_FEEL, B_NO_SERVER_SIDE_WINDOW_MODIFIERS),
544 subset_windows (NULL),
545 parent (NULL),
546 x_before_zoom (INT_MIN),
547 y_before_zoom (INT_MIN),
548 shown_flag (false),
549 was_shown_p (false),
550 menu_bar_active_p (false),
551 override_redirect_p (false),
552 window_id (current_window_id),
553 menus_begun (NULL),
554 z_group (Z_GROUP_NONE),
555 tooltip_p (false),
556 fullscreen_mode (FULLSCREEN_MODE_NONE)
544 { 557 {
545 window_id = current_window_id++;
546 z_group = Z_GROUP_NONE;
547
548 /* This pulse rate is used by scroll bars for repeating a button 558 /* This pulse rate is used by scroll bars for repeating a button
549 action while a button is held down. */ 559 action while a button is held down. */
550 SetPulseRate (30000); 560 SetPulseRate (30000);
@@ -711,12 +721,6 @@ public:
711 RecomputeFeel (); 721 RecomputeFeel ();
712 UpwardsUnSubsetChildren (parent); 722 UpwardsUnSubsetChildren (parent);
713 this->RemoveFromSubset (this); 723 this->RemoveFromSubset (this);
714
715 if (fullscreen_p)
716 {
717 fullscreen_p = 0;
718 MakeFullscreen (1);
719 }
720 child_frame_lock.Unlock (); 724 child_frame_lock.Unlock ();
721 } 725 }
722 726
@@ -766,11 +770,6 @@ public:
766 this->AddToSubset (this); 770 this->AddToSubset (this);
767 if (!IsHidden () && this->parent) 771 if (!IsHidden () && this->parent)
768 UpwardsSubsetChildren (parent); 772 UpwardsSubsetChildren (parent);
769 if (fullscreen_p)
770 {
771 fullscreen_p = 0;
772 MakeFullscreen (1);
773 }
774 window->LinkChild (this); 773 window->LinkChild (this);
775 774
776 child_frame_lock.Unlock (); 775 child_frame_lock.Unlock ();
@@ -1161,41 +1160,103 @@ public:
1161 } 1160 }
1162 1161
1163 void 1162 void
1164 Zoom (BPoint o, float w, float h) 1163 ClearFullscreen (void)
1165 { 1164 {
1166 struct haiku_zoom_event rq; 1165 switch (fullscreen_mode)
1167 BRect rect; 1166 {
1168 rq.window = this; 1167 case FULLSCREEN_MODE_MAXIMIZED:
1168 BWindow::Zoom (pre_zoom_rect.LeftTop (),
1169 BE_RECT_WIDTH (pre_zoom_rect) - 1,
1170 BE_RECT_HEIGHT (pre_zoom_rect) - 1);
1171 break;
1169 1172
1170 if (fullscreen_p) 1173 case FULLSCREEN_MODE_BOTH:
1171 MakeFullscreen (0); 1174 case FULLSCREEN_MODE_HEIGHT:
1175 case FULLSCREEN_MODE_WIDTH:
1176 MoveTo (pre_fullscreen_rect.LeftTop ());
1177 ResizeTo (BE_RECT_WIDTH (pre_fullscreen_rect) - 1,
1178 BE_RECT_HEIGHT (pre_fullscreen_rect) - 1);
1172 1179
1173 if (!zoomed_p) 1180 SetFlags (Flags () & ~(B_NOT_MOVABLE
1174 { 1181 | B_NOT_ZOOMABLE
1175 pre_zoom_rect = Frame (); 1182 | B_NOT_RESIZABLE));
1176 zoomed_p = true; 1183 break;
1177 rect = CalculateZoomRect (); 1184
1178 } 1185 case FULLSCREEN_MODE_NONE:
1179 else 1186 break;
1180 {
1181 zoomed_p = false;
1182 rect = pre_zoom_rect;
1183 } 1187 }
1184 1188
1185 rq.zoomed = zoomed_p; 1189 fullscreen_mode = FULLSCREEN_MODE_NONE;
1186 haiku_write (ZOOM_EVENT, &rq); 1190 }
1187 1191
1188 BWindow::Zoom (rect.LeftTop (), BE_RECT_WIDTH (rect) - 1, 1192 BRect
1189 BE_RECT_HEIGHT (rect) - 1); 1193 FullscreenRectForMode (enum haiku_fullscreen_mode mode)
1194 {
1195 BScreen screen (this);
1196 BRect frame;
1197
1198 if (!screen.IsValid ())
1199 return BRect (0, 0, 0, 0);
1200
1201 frame = screen.Frame ();
1202
1203 if (mode == FULLSCREEN_MODE_HEIGHT)
1204 frame.right -= BE_RECT_WIDTH (frame) / 2;
1205 else if (mode == FULLSCREEN_MODE_WIDTH)
1206 frame.bottom -= BE_RECT_HEIGHT (frame) / 2;
1207
1208 return frame;
1190 } 1209 }
1191 1210
1192 void 1211 void
1193 UnZoom (void) 1212 SetFullscreen (enum haiku_fullscreen_mode mode)
1194 { 1213 {
1195 if (!zoomed_p) 1214 BRect zoom_rect;
1215
1216 if (fullscreen_mode == mode)
1196 return; 1217 return;
1197 1218
1198 BWindow::Zoom (); 1219 ClearFullscreen ();
1220
1221 switch (mode)
1222 {
1223 case FULLSCREEN_MODE_MAXIMIZED:
1224 pre_zoom_rect = Frame ();
1225 zoom_rect = CalculateZoomRect ();
1226 BWindow::Zoom (zoom_rect.LeftTop (),
1227 BE_RECT_WIDTH (zoom_rect) - 1,
1228 BE_RECT_HEIGHT (zoom_rect) - 1);
1229 break;
1230
1231 case FULLSCREEN_MODE_BOTH:
1232 SetFlags (Flags () | B_NOT_MOVABLE);
1233 FALLTHROUGH;
1234
1235 case FULLSCREEN_MODE_HEIGHT:
1236 case FULLSCREEN_MODE_WIDTH:
1237 SetFlags (Flags () | B_NOT_ZOOMABLE | B_NOT_RESIZABLE);
1238 pre_fullscreen_rect = Frame ();
1239 zoom_rect = FullscreenRectForMode (mode);
1240 ResizeTo (BE_RECT_WIDTH (zoom_rect) - 1,
1241 BE_RECT_HEIGHT (zoom_rect) - 1);
1242 MoveTo (zoom_rect.left, zoom_rect.top);
1243
1244 break;
1245
1246 case FULLSCREEN_MODE_NONE:
1247 break;
1248 }
1249
1250 fullscreen_mode = mode;
1251 }
1252
1253 void
1254 Zoom (BPoint o, float w, float h)
1255 {
1256 struct haiku_zoom_event rq;
1257
1258 rq.window = this;
1259 haiku_write (ZOOM_EVENT, &rq);
1199 } 1260 }
1200 1261
1201 void 1262 void
@@ -1218,51 +1279,6 @@ public:
1218 child_frame_lock.Lock (); 1279 child_frame_lock.Lock ();
1219 gui_abort ("Trying to calculate offsets for a child frame that doesn't exist"); 1280 gui_abort ("Trying to calculate offsets for a child frame that doesn't exist");
1220 } 1281 }
1221
1222 void
1223 MakeFullscreen (int make_fullscreen_p)
1224 {
1225 BScreen screen (this);
1226 uint32 flags;
1227 BRect screen_frame;
1228
1229 if (!screen.IsValid ())
1230 gui_abort ("Trying to make a window fullscreen without a screen");
1231
1232 screen_frame = screen.Frame ();
1233 UnZoom ();
1234
1235 if (make_fullscreen_p == fullscreen_p)
1236 return;
1237
1238 fullscreen_p = make_fullscreen_p;
1239 flags = Flags ();
1240
1241 if (fullscreen_p)
1242 {
1243 if (zoomed_p)
1244 UnZoom ();
1245
1246 flags |= B_NOT_MOVABLE | B_NOT_ZOOMABLE;
1247 pre_fullscreen_rect = Frame ();
1248
1249 MoveTo (0, 0);
1250 ResizeTo (BE_RECT_WIDTH (screen_frame) - 1,
1251 BE_RECT_HEIGHT (screen_frame) - 1);
1252 }
1253 else
1254 {
1255 flags &= ~(B_NOT_MOVABLE | B_NOT_ZOOMABLE);
1256
1257 /* Use MoveTo directly since pre_fullscreen_rect isn't
1258 adjusted for decorator sizes. */
1259 MoveTo (pre_fullscreen_rect.left,
1260 pre_fullscreen_rect.top);
1261 ResizeTo (BE_RECT_WIDTH (pre_fullscreen_rect) - 1,
1262 BE_RECT_HEIGHT (pre_fullscreen_rect) - 1);
1263 }
1264 SetFlags (flags);
1265 }
1266}; 1282};
1267 1283
1268class EmacsMenuBar : public BMenuBar 1284class EmacsMenuBar : public BMenuBar
@@ -4486,30 +4502,6 @@ be_popup_file_dialog (int open_p, const char *default_dir, int must_match_p,
4486 return file_name; 4502 return file_name;
4487} 4503}
4488 4504
4489/* Zoom WINDOW. */
4490void
4491BWindow_zoom (void *window)
4492{
4493 BWindow *w = (BWindow *) window;
4494 w->Zoom ();
4495}
4496
4497/* Make WINDOW fullscreen if FULLSCREEN_P. */
4498void
4499EmacsWindow_make_fullscreen (void *window, int fullscreen_p)
4500{
4501 EmacsWindow *w = (EmacsWindow *) window;
4502 w->MakeFullscreen (fullscreen_p);
4503}
4504
4505/* Unzoom (maximize) WINDOW. */
4506void
4507EmacsWindow_unzoom (void *window)
4508{
4509 EmacsWindow *w = (EmacsWindow *) window;
4510 w->UnZoom ();
4511}
4512
4513/* Move the pointer into MBAR and start tracking. Return whether the 4505/* Move the pointer into MBAR and start tracking. Return whether the
4514 menu bar was opened correctly. */ 4506 menu bar was opened correctly. */
4515bool 4507bool
@@ -5180,3 +5172,15 @@ be_unlock_window (void *window)
5180 5172
5181 wnd->UnlockLooper (); 5173 wnd->UnlockLooper ();
5182} 5174}
5175
5176void
5177be_set_window_fullscreen_mode (void *window, enum haiku_fullscreen_mode mode)
5178{
5179 EmacsWindow *w = (EmacsWindow *) window;
5180
5181 if (!w->LockLooper ())
5182 gui_abort ("Failed to lock window to set fullscreen mode");
5183
5184 w->SetFullscreen (mode);
5185 w->UnlockLooper ();
5186}