Skip to content

Commit

Permalink
MacOS fullscreen fix
Browse files Browse the repository at this point in the history
* Disable tabs creation when opening a window from a fullscreened window
* Fix crash when disconnecting while having a fullscreened child window
  • Loading branch information
Namaneo committed Aug 24, 2023
1 parent 8244a3c commit c2da3d7
Showing 1 changed file with 27 additions and 32 deletions.
59 changes: 27 additions & 32 deletions src/unix/apple/macosx/app.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,18 @@

// App

struct window;
struct window {
NSWindow <NSWindowDelegate> *nsw;
NSTrackingArea *area;
MTY_App *app;
struct window_common cmn;
MTY_Window window;
NSRect normal_frame;
NSRect restore_frame;
bool was_maximized;
bool top;
bool open;
};

struct MTY_App {
NSObject <NSApplicationDelegate, NSUserNotificationCenterDelegate> *nsapp;
Expand Down Expand Up @@ -56,7 +67,7 @@
bool pen_left;
NSUInteger buttons;
uint32_t cb_seq;
struct window *windows[MTY_WINDOW_MAX];
struct window windows[MTY_WINDOW_MAX];
float timeout;
struct hid *hid;
};
Expand Down Expand Up @@ -385,48 +396,36 @@ static Class app_class(void)

// Window

struct window {
NSWindow <NSWindowDelegate> *nsw;
NSTrackingArea *area;
MTY_App *app;
struct window_common cmn;
MTY_Window window;
NSRect normal_frame;
NSRect restore_frame;
bool was_maximized;
bool top;
};

static struct window *app_get_window(MTY_App *ctx, MTY_Window window)
{
return window < 0 ? NULL : ctx->windows[window];
return window < 0 || !ctx->windows[window].open ? NULL : &ctx->windows[window];
}

static struct window *app_get_active_window(MTY_App *ctx)
{
for (MTY_Window x = 0; x < MTY_WINDOW_MAX; x++)
if (ctx->windows[x] && ctx->windows[x]->nsw.isKeyWindow)
return ctx->windows[x];
if (ctx->windows[x].open && ctx->windows[x].nsw.isKeyWindow)
return &ctx->windows[x];

return NULL;
}

static struct window *app_get_window_by_number(MTY_App *ctx, NSInteger number)
{
for (MTY_Window x = 0; x < MTY_WINDOW_MAX; x++)
if (ctx->windows[x] && ctx->windows[x]->nsw.windowNumber == number)
return ctx->windows[x];
if (ctx->windows[x].open && ctx->windows[x].nsw.windowNumber == number)
return &ctx->windows[x];

return NULL;
}

static MTY_Window app_find_open_window(MTY_App *ctx, MTY_Window req)
{
if (req >= 0 && req < MTY_WINDOW_MAX && !ctx->windows[req])
if (req >= 0 && req < MTY_WINDOW_MAX && !ctx->windows[req].open)
return req;

for (MTY_Window x = 0; x < MTY_WINDOW_MAX; x++)
if (!ctx->windows[x])
if (!ctx->windows[x].open)
return x;

return -1;
Expand Down Expand Up @@ -835,8 +834,7 @@ static NSRect window_windowWillUseStandardFrame_defaultFrame(NSWindow *self, SEL
{
struct window *ctx = OBJC_CTX();

if (!NSEqualRects(window.frame, newFrame))
ctx->normal_frame = window.frame;
ctx->normal_frame = newFrame;

return newFrame;
}
Expand Down Expand Up @@ -1716,7 +1714,8 @@ MTY_Window MTY_WindowCreate(MTY_App *app, const char *title, const MTY_Frame *fr
NSWindowStyleMaskResizable | NSWindowStyleMaskMiniaturizable;

// Window
struct window *ctx = MTY_Alloc(1, sizeof(struct window));
struct window *ctx = &app->windows[window];
ctx->open = true;
ctx->window = window;
ctx->app = app;

Expand All @@ -1727,6 +1726,7 @@ MTY_Window MTY_WindowCreate(MTY_App *app, const char *title, const MTY_Frame *fr
[ctx->nsw setDelegate:ctx->nsw];
[ctx->nsw setAcceptsMouseMovedEvents:YES];
[ctx->nsw setReleasedWhenClosed:NO];
[ctx->nsw setTabbingMode:NSWindowTabbingModeDisallowed];

NSUInteger cb = alt_fs ? NSWindowCollectionBehaviorFullScreenNone |
NSWindowCollectionBehaviorFullScreenDisallowsTiling : NSWindowCollectionBehaviorFullScreenPrimary;
Expand All @@ -1736,8 +1736,6 @@ MTY_Window MTY_WindowCreate(MTY_App *app, const char *title, const MTY_Frame *fr
content = [OBJC_NEW(view_class(), ctx) initWithFrame:[ctx->nsw contentRectForFrameRect:ctx->nsw.frame]];
[ctx->nsw setContentView:content];

ctx->app->windows[window] = ctx;

if (frame->type & MTY_WINDOW_MAXIMIZED)
[ctx->nsw zoom:ctx->nsw];

Expand All @@ -1763,18 +1761,15 @@ void MTY_WindowDestroy(MTY_App *app, MTY_Window window)
if (!ctx)
return;

ctx->app->windows[window] = NULL;

[ctx->nsw close];

// XXX Make sure this is freed after the window is closed, events
// can continue to fire until that point
mty_webview_destroy(&ctx->cmn.webview);

ctx->nsw = nil;
ctx->area = nil;

MTY_Free(ctx);
// The window is closed asynchronously, meaning events can still be fired after this function
// We keep the app inside the window in case that happens to prevent the app from crashing
*ctx = (struct window) { .app = ctx->app };
}

MTY_Size MTY_WindowGetSize(MTY_App *app, MTY_Window window)
Expand Down

0 comments on commit c2da3d7

Please sign in to comment.