diff --git a/src/Fl_Window_Driver.H b/src/Fl_Window_Driver.H index cec60a2daec09ce16f8a2bef505803d29b365a6d..865c57af956ffa9348cb1ce44ad5cc7549976b79 100644 --- a/src/Fl_Window_Driver.H +++ b/src/Fl_Window_Driver.H @@ -2,7 +2,7 @@ // A base class for platform specific window handling code // for the Fast Light Tool Kit (FLTK). // -// Copyright 2010-2024 by Bill Spitzak and others. +// Copyright 2010-2025 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -152,6 +152,7 @@ public: virtual void unmap() {} virtual void fullscreen_on() {} virtual void fullscreen_off(int /*X*/, int /*Y*/, int /*W*/, int /*H*/) {} + virtual void fullscreen_screens(bool /*on_off*/) {} virtual void maximize(); virtual void un_maximize(); virtual bool maximize_needs_hide() { return false; } diff --git a/src/Fl_Window_fullscreen.cxx b/src/Fl_Window_fullscreen.cxx index e464a9fba886febecb894f9f2a88200341aa858d..79e57a0c8f3de8a13f9ebfdff2f2526f129f505e 100644 --- a/src/Fl_Window_fullscreen.cxx +++ b/src/Fl_Window_fullscreen.cxx @@ -1,7 +1,7 @@ // // Fullscreen window support for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2015 by Bill Spitzak and others. +// Copyright 1998-2025 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -75,11 +75,13 @@ void Fl_Window::fullscreen_screens(int top, int bottom, int left, int right) { fullscreen_screen_bottom = -1; fullscreen_screen_left = -1; fullscreen_screen_right = -1; + pWindowDriver->fullscreen_screens(false); } else { fullscreen_screen_top = top; fullscreen_screen_bottom = bottom; fullscreen_screen_left = left; fullscreen_screen_right = right; + pWindowDriver->fullscreen_screens(true); } if (shown() && fullscreen_active()) diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index fcd691aa08e0a63c29b951006a78b3405942b612..8095447a84d67c933a7a10ee0e7d692795ab47de 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -1,7 +1,7 @@ // // macOS-Cocoa specific code for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2024 by Bill Spitzak and others. +// Copyright 1998-2025 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -557,6 +557,7 @@ void Fl_Cocoa_Screen_Driver::breakMacEventLoop() - (NSPoint)convertBaseToScreen:(NSPoint)aPoint; #endif - (NSBitmapImageRep*)rect_to_NSBitmapImageRep:(Fl_Rect*)r; +- (void)makeKeyWindow; @end @@ -795,6 +796,11 @@ void Fl_Cocoa_Screen_Driver::breakMacEventLoop() - (NSBitmapImageRep*)rect_to_NSBitmapImageRep:(Fl_Rect*)r { return rect_to_NSBitmapImageRep(w, r->x(), r->y(), r->w(), r->h()); } +- (void)makeKeyWindow { + // Necessary in this scenario at least: + // transition of a subwindow-containing window from multiscreen-fullscreen mode to normal mode. + if ([self canBecomeKeyWindow]) [super makeKeyWindow]; +} @end @interface FLApplication : NSObject @@ -1437,7 +1443,11 @@ static FLWindowDelegate *flwindowdelegate_instance = nil; FLWindow *nsw = (FLWindow*)[notif object]; Fl_Window *w = [nsw getFl_Window]; /* Restore previous fullscreen level */ - if (w->fullscreen_active() && fl_mac_os_version < 100700) { + if (w->fullscreen_active() && (fl_mac_os_version < 100700 +# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 + || !(nsw.styleMask & NSWindowStyleMaskFullScreen) +#endif + )) { [nsw setLevel:NSStatusWindowLevel]; fixup_window_levels(); } @@ -3278,10 +3288,23 @@ void Fl_Cocoa_Window_Driver::makeWindow() [pool release]; } + +static BOOL fullscreen_screen_border = NO; // YES means the multi-screened window had a border before + +static NSUInteger calc_win_style(Fl_Window *win); + + void Fl_Cocoa_Window_Driver::fullscreen_on() { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + bool has_border = pWindow->border(); + if (fl_mac_os_version >= 100700 && fullscreen_screen_top() >= 0 && has_border) { + fullscreen_screen_border = YES; + has_border = false; + } +#endif pWindow->_set_fullscreen(); #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 - if (fl_mac_os_version >= 100700 && pWindow->border()) { + if (fl_mac_os_version >= 100700 && has_border) { # if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 NSWindow *nswin = fl_xid(pWindow); # if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_13 @@ -3290,10 +3313,29 @@ void Fl_Cocoa_Window_Driver::fullscreen_on() { if (active_tab) nswin = active_tab; } # endif + if (fullscreen_screen_border) { // from "All Screens" fullscreen to single-screen fullscreen + pWindow->_clear_fullscreen(); + [nswin setLevel:NSNormalWindowLevel]; + [nswin setStyleMask:calc_win_style(pWindow)]; //10.6 + pWindow->_set_fullscreen(); + } [nswin toggleFullScreen:nil]; # endif } else if (fl_mac_os_version >= 100600) { FLWindow *nswin = fl_xid(pWindow); +# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 + if (fl_mac_os_version >= 100700 && (nswin.styleMask & NSWindowStyleMaskFullScreen)) { + // from single-screen fullscreen to "All Screens" fullscreen + [nswin toggleFullScreen:nil]; + if (*no_fullscreen_w() == 0) { + *no_fullscreen_x() = x(); + *no_fullscreen_y() = y(); + *no_fullscreen_w() = w(); + *no_fullscreen_h() = h(); + } + pWindow->_set_fullscreen(); + } +#endif [nswin setStyleMask:NSWindowStyleMaskBorderless]; // 10.6 if ([nswin isKeyWindow]) { if ([nswin level] != NSStatusWindowLevel) { @@ -3373,11 +3415,15 @@ static void restore_window_title_and_icon(Fl_Window *pWindow, NSImage *icon) { #endif void Fl_Cocoa_Window_Driver::fullscreen_off(int X, int Y, int W, int H) { + NSWindow *nswin = fl_xid(pWindow); pWindow->_clear_fullscreen(); #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 - if (fl_mac_os_version >= 100700 && pWindow->border()) { + if (fl_mac_os_version >= 100700 +# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 + && ([nswin styleMask] & NSWindowStyleMaskFullScreen) +# endif + ) { # if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 - NSWindow *nswin = fl_xid(pWindow); # if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_13 if (fl_mac_os_version >= 101300) { NSWindow *active_tab = [[nswin tabGroup] selectedWindow]; @@ -3385,9 +3431,10 @@ void Fl_Cocoa_Window_Driver::fullscreen_off(int X, int Y, int W, int H) { } # endif [nswin toggleFullScreen:nil]; + pWindow->resize(*no_fullscreen_x(), *no_fullscreen_y(), *no_fullscreen_w(), *no_fullscreen_h()); # endif } else if (fl_mac_os_version >= 100600) { - FLWindow *nswin = fl_xid(pWindow); + // Transition from multi-screen fullscreen mode to normal mode NSInteger level = NSNormalWindowLevel; if (pWindow->modal()) level = modal_window_level(); else if (pWindow->non_modal()) level = non_modal_window_level(); @@ -3413,8 +3460,21 @@ void Fl_Cocoa_Window_Driver::fullscreen_off(int X, int Y, int W, int H) { pWindow->show(); } Fl::handle(FL_FULLSCREEN, pWindow); + fullscreen_screen_border = NO; } + +void Fl_Cocoa_Window_Driver::fullscreen_screens(bool on_off) { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 + if (fl_mac_os_version >= 100700) { + FLWindow *xid = fl_mac_xid(pWindow); + if (on_off) xid.collectionBehavior |= NSWindowCollectionBehaviorFullScreenNone; + else xid.collectionBehavior &= ~NSWindowCollectionBehaviorFullScreenNone; + } +#endif +} + + void Fl_Cocoa_Window_Driver::use_border() { if (!shown() || pWindow->parent()) return; #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 diff --git a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H index ef57a4607c2cc6582d09badbee1d8fcca7c0b121..c4d4e31dac322b535a9ad5453f67ae6b6d0fb8d4 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H +++ b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H @@ -2,7 +2,7 @@ // Definition of Apple Cocoa window driver // for the Fast Light Tool Kit (FLTK). // -// Copyright 2010-2022 by Bill Spitzak and others. +// Copyright 2010-2025 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -133,6 +133,7 @@ public: void unmap() FL_OVERRIDE; void fullscreen_on() FL_OVERRIDE; void fullscreen_off(int X, int Y, int W, int H) FL_OVERRIDE; + void fullscreen_screens(bool on_off) FL_OVERRIDE; void maximize() FL_OVERRIDE; void un_maximize() FL_OVERRIDE; void use_border() FL_OVERRIDE;