diff options
| -rw-r--r-- | CHANGES | 6 | ||||
| -rw-r--r-- | FL/Fl.H | 16 | ||||
| -rw-r--r-- | FL/Fl_System_Driver.H | 5 | ||||
| -rw-r--r-- | src/Fl.cxx | 16 | ||||
| -rw-r--r-- | src/Fl_System_Driver.cxx | 9 | ||||
| -rw-r--r-- | src/Fl_cocoa.mm | 27 | ||||
| -rw-r--r-- | src/drivers/Darwin/Fl_Darwin_System_Driver.H | 4 |
7 files changed, 74 insertions, 9 deletions
@@ -18,6 +18,12 @@ Changes in FLTK 1.4.0 Released: ??? ?? 2017 New Features and Extensions - (add new items here) + - New member functions FL::run_also_windowless(), + and FL::wait_also_windowless(double secnds) to run the event + loop even without any mapped window if the platform supports it. + - New member functions Fl::program_should_quit(void), + and Fl::program_should_quit(int) to support detection by the library + of a request to terminate cleanly the program. - MacOS platform: Added support for rescaling the GUI of any app at run-time using the command/+/-/0/ keystrokes. - MSWindows platform: Added optional support for rescaling the GUI of any app @@ -259,7 +259,8 @@ public: private: static unsigned char options_[OPTION_LAST]; static unsigned char options_read_; - + static int program_should_quit_; // non-zero means the program was asked to cleanly terminate + public: /* Return a global setting for all FLTK applications, possibly overridden @@ -412,6 +413,19 @@ public: static int check(); static int ready(); static int run(); + static int run_also_windowless(); + static int wait_also_windowless(double delay = 1e20); + /** Returns non-zero when a request for program termination was received and accepted. + On the MacOS platform, the "Quit xxx" item of the application menu is such a request, + that is considered accepted when all windows are closed. On other platforms, this function + returns 0 until \p Fl::program_should_quit(1) is called. + */ + static int program_should_quit() {return program_should_quit_;} + /** Indicate to the FLTK library whether a program termination request was received and accepted. + A program may set this to 1, for example, while performing a platform-independent command asking the program to cleanly + terminate, similarly to the "Quit xxx" item of the application menu under MacOS. */ + static void program_should_quit(int should_i) { program_should_quit_ = should_i; } + static Fl_Widget* readqueue(); /** Adds a one-shot timeout callback. The function will be called by diff --git a/FL/Fl_System_Driver.H b/FL/Fl_System_Driver.H index 5bcd8e994..a543906fd 100644 --- a/FL/Fl_System_Driver.H +++ b/FL/Fl_System_Driver.H @@ -4,7 +4,7 @@ // A base class for platform specific system calls // for the Fast Light Tool Kit (FLTK). // -// Copyright 2010-2017 by Bill Spitzak and others. +// Copyright 2010-2018 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 @@ -225,6 +225,9 @@ public: virtual const char *meta_name() { return "Meta"; } virtual const char *alt_name() { return "Alt"; } virtual const char *control_name() { return "Ctrl"; } + // The default implementation of the next 2 functions may be enough. + virtual int run_also_windowless(); + virtual int wait_also_windowless(double delay); }; #endif // FL_SYSTEM_DRIVER_H diff --git a/src/Fl.cxx b/src/Fl.cxx index ca629ab94..e6af1297b 100644 --- a/src/Fl.cxx +++ b/src/Fl.cxx @@ -589,6 +589,22 @@ int Fl::ready() return screen_driver()->ready(); } +/** Run the event loop even without any mapped window if the platform supports it. + \return zero indicates the event loop has been terminated. + */ +int Fl::run_also_windowless() { + return Fl::system_driver()->run_also_windowless(); +} + +/** Wait for \p delay seconds or until an event occurs, even without any mapped window if the platform supports it. + \return non zero indicates the event loop should be terminated + */ +int Fl::wait_also_windowless(double delay) { + return Fl::system_driver()->wait_also_windowless(delay); +} + +int Fl::program_should_quit_ = 0; + //////////////////////////////////////////////////////////////// // Window list management: diff --git a/src/Fl_System_Driver.cxx b/src/Fl_System_Driver.cxx index c396c9e2f..62c5a765b 100644 --- a/src/Fl_System_Driver.cxx +++ b/src/Fl_System_Driver.cxx @@ -445,6 +445,15 @@ void Fl_System_Driver::gettime(time_t *sec, int *usec) { *usec = 0; } +int Fl_System_Driver::run_also_windowless() { + return Fl::run(); +} + +int Fl_System_Driver::wait_also_windowless(double delay) { + Fl::wait(delay); + return Fl::first_window() != NULL; +} + // // End of "$Id$". // diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm index f738c3221..5fbd2cbf2 100644 --- a/src/Fl_cocoa.mm +++ b/src/Fl_cocoa.mm @@ -832,9 +832,9 @@ static int do_queued_events( double time = 0.0 ) } fl_unlock_function(); - NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask - untilDate:[NSDate dateWithTimeIntervalSinceNow:time] - inMode:NSDefaultRunLoopMode dequeue:YES]; + NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask + untilDate:[NSDate dateWithTimeIntervalSinceNow:time] + inMode:NSDefaultRunLoopMode dequeue:YES]; if (event != nil) { got_events = 1; [FLApplication sendEvent:event]; // will then call [NSApplication sendevent:] @@ -1507,6 +1507,7 @@ static FLWindowDelegate *flwindowdelegate_instance = nil; - (void)applicationWillUnhide:(NSNotification *)notify; - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename; @end + @implementation FLAppDelegate - (void)applicationDidFinishLaunching:(NSNotification *)notification { @@ -1515,19 +1516,21 @@ static FLWindowDelegate *flwindowdelegate_instance = nil; - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender { fl_lock_function(); - NSApplicationTerminateReply reply = NSTerminateNow; while ( Fl_X::first ) { Fl_Window *win = Fl::first_window(); if (win->parent()) win = win->top_window(); Fl_Widget_Tracker wt(win); // track the window object Fl::handle(FL_CLOSE, win); if (wt.exists() && win->shown()) { // the user didn't close win - reply = NSTerminateCancel; // so we return to the main program now break; } } fl_unlock_function(); - return reply; + if ( ! Fl::first_window() ) { + Fl::program_should_quit(1); + breakMacEventLoop(); // necessary when called through menu and in Fl::wait() + } + return NSTerminateCancel; } - (void)applicationDidBecomeActive:(NSNotification *)notify { @@ -1716,6 +1719,18 @@ static void drain_dropped_files_list() { free(fname); } +int Fl_Darwin_System_Driver::run_also_windowless() { + while (!Fl::program_should_quit()) { + Fl::wait(1e20); + } + return 0; +} + +int Fl_Darwin_System_Driver::wait_also_windowless(double delay) { + if (!Fl::program_should_quit()) Fl::wait(delay); + return !Fl::program_should_quit(); +} + /* * Install an open documents event handler... */ diff --git a/src/drivers/Darwin/Fl_Darwin_System_Driver.H b/src/drivers/Darwin/Fl_Darwin_System_Driver.H index cec33d2a9..77f38efc0 100644 --- a/src/drivers/Darwin/Fl_Darwin_System_Driver.H +++ b/src/drivers/Darwin/Fl_Darwin_System_Driver.H @@ -4,7 +4,7 @@ // Definition of Apple Darwin system driver // for the Fast Light Tool Kit (FLTK). // -// Copyright 2010-2016 by Bill Spitzak and others. +// Copyright 2010-2018 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 @@ -81,6 +81,8 @@ public: virtual const char *meta_name(); virtual const char *alt_name(); virtual const char *control_name(); + virtual int run_also_windowless(); + virtual int wait_also_windowless(double delay); }; #endif // FL_DARWIN_SYSTEM_DRIVER_H |
