diff options
| author | Po Lu | 2022-05-19 03:43:39 +0000 |
|---|---|---|
| committer | Po Lu | 2022-05-19 03:43:39 +0000 |
| commit | 4dfaefcffc987400a317b5ccf0c9bf00f7c84134 (patch) | |
| tree | 590fe0f71a6fae3fdec4d64fa80e20875f136be9 /src/haiku_support.cc | |
| parent | bc604417f87f9fce865e70b3bc88b6bf2a8fd415 (diff) | |
| download | emacs-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.cc | 242 |
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 | |||
| 17 | along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | 17 | along 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 | ||
| 1268 | class EmacsMenuBar : public BMenuBar | 1284 | class 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. */ | ||
| 4490 | void | ||
| 4491 | BWindow_zoom (void *window) | ||
| 4492 | { | ||
| 4493 | BWindow *w = (BWindow *) window; | ||
| 4494 | w->Zoom (); | ||
| 4495 | } | ||
| 4496 | |||
| 4497 | /* Make WINDOW fullscreen if FULLSCREEN_P. */ | ||
| 4498 | void | ||
| 4499 | EmacsWindow_make_fullscreen (void *window, int fullscreen_p) | ||
| 4500 | { | ||
| 4501 | EmacsWindow *w = (EmacsWindow *) window; | ||
| 4502 | w->MakeFullscreen (fullscreen_p); | ||
| 4503 | } | ||
| 4504 | |||
| 4505 | /* Unzoom (maximize) WINDOW. */ | ||
| 4506 | void | ||
| 4507 | EmacsWindow_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. */ |
| 4515 | bool | 4507 | bool |
| @@ -5180,3 +5172,15 @@ be_unlock_window (void *window) | |||
| 5180 | 5172 | ||
| 5181 | wnd->UnlockLooper (); | 5173 | wnd->UnlockLooper (); |
| 5182 | } | 5174 | } |
| 5175 | |||
| 5176 | void | ||
| 5177 | be_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 | } | ||