Add support for detection and processing of clean program termination request.
The default handling of cmd-Q/Quit program under MacOS was to terminate the program if all its windows are closed without returning from FLTK's event loop. This was running against a strong design feature of FLTK that programs should always complete their event loop and return from main() when cleanly terminating. In the new code for the MacOS platform, cmd-Q/Quit program no longer terminates the program. Instead, the event loop is interrupted and a call to Fl::program_should_quit() allows to detect that program termination has been requested, if necessary. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12647 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
4ebaee0f40
commit
425ab2e8bc
6
CHANGES
6
CHANGES
@ -18,6 +18,12 @@ Changes in FLTK 1.4.0 Released: ??? ?? 2017
|
|||||||
New Features and Extensions
|
New Features and Extensions
|
||||||
|
|
||||||
- (add new items here)
|
- (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
|
- MacOS platform: Added support for rescaling the GUI of any app at run-time
|
||||||
using the command/+/-/0/ keystrokes.
|
using the command/+/-/0/ keystrokes.
|
||||||
- MSWindows platform: Added optional support for rescaling the GUI of any app
|
- MSWindows platform: Added optional support for rescaling the GUI of any app
|
||||||
|
14
FL/Fl.H
14
FL/Fl.H
@ -259,6 +259,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
static unsigned char options_[OPTION_LAST];
|
static unsigned char options_[OPTION_LAST];
|
||||||
static unsigned char options_read_;
|
static unsigned char options_read_;
|
||||||
|
static int program_should_quit_; // non-zero means the program was asked to cleanly terminate
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*
|
/*
|
||||||
@ -412,6 +413,19 @@ public:
|
|||||||
static int check();
|
static int check();
|
||||||
static int ready();
|
static int ready();
|
||||||
static int run();
|
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();
|
static Fl_Widget* readqueue();
|
||||||
/**
|
/**
|
||||||
Adds a one-shot timeout callback. The function will be called by
|
Adds a one-shot timeout callback. The function will be called by
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
// A base class for platform specific system calls
|
// A base class for platform specific system calls
|
||||||
// for the Fast Light Tool Kit (FLTK).
|
// 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
|
// 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
|
// 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 *meta_name() { return "Meta"; }
|
||||||
virtual const char *alt_name() { return "Alt"; }
|
virtual const char *alt_name() { return "Alt"; }
|
||||||
virtual const char *control_name() { return "Ctrl"; }
|
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
|
#endif // FL_SYSTEM_DRIVER_H
|
||||||
|
16
src/Fl.cxx
16
src/Fl.cxx
@ -589,6 +589,22 @@ int Fl::ready()
|
|||||||
return screen_driver()->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:
|
// Window list management:
|
||||||
|
|
||||||
|
@ -445,6 +445,15 @@ void Fl_System_Driver::gettime(time_t *sec, int *usec) {
|
|||||||
*usec = 0;
|
*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$".
|
// End of "$Id$".
|
||||||
//
|
//
|
||||||
|
@ -1507,6 +1507,7 @@ static FLWindowDelegate *flwindowdelegate_instance = nil;
|
|||||||
- (void)applicationWillUnhide:(NSNotification *)notify;
|
- (void)applicationWillUnhide:(NSNotification *)notify;
|
||||||
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename;
|
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation FLAppDelegate
|
@implementation FLAppDelegate
|
||||||
- (void)applicationDidFinishLaunching:(NSNotification *)notification
|
- (void)applicationDidFinishLaunching:(NSNotification *)notification
|
||||||
{
|
{
|
||||||
@ -1515,19 +1516,21 @@ static FLWindowDelegate *flwindowdelegate_instance = nil;
|
|||||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender
|
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender
|
||||||
{
|
{
|
||||||
fl_lock_function();
|
fl_lock_function();
|
||||||
NSApplicationTerminateReply reply = NSTerminateNow;
|
|
||||||
while ( Fl_X::first ) {
|
while ( Fl_X::first ) {
|
||||||
Fl_Window *win = Fl::first_window();
|
Fl_Window *win = Fl::first_window();
|
||||||
if (win->parent()) win = win->top_window();
|
if (win->parent()) win = win->top_window();
|
||||||
Fl_Widget_Tracker wt(win); // track the window object
|
Fl_Widget_Tracker wt(win); // track the window object
|
||||||
Fl::handle(FL_CLOSE, win);
|
Fl::handle(FL_CLOSE, win);
|
||||||
if (wt.exists() && win->shown()) { // the user didn't close win
|
if (wt.exists() && win->shown()) { // the user didn't close win
|
||||||
reply = NSTerminateCancel; // so we return to the main program now
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fl_unlock_function();
|
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
|
- (void)applicationDidBecomeActive:(NSNotification *)notify
|
||||||
{
|
{
|
||||||
@ -1716,6 +1719,18 @@ static void drain_dropped_files_list() {
|
|||||||
free(fname);
|
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...
|
* Install an open documents event handler...
|
||||||
*/
|
*/
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
// Definition of Apple Darwin system driver
|
// Definition of Apple Darwin system driver
|
||||||
// for the Fast Light Tool Kit (FLTK).
|
// 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
|
// 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
|
// 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 *meta_name();
|
||||||
virtual const char *alt_name();
|
virtual const char *alt_name();
|
||||||
virtual const char *control_name();
|
virtual const char *control_name();
|
||||||
|
virtual int run_also_windowless();
|
||||||
|
virtual int wait_also_windowless(double delay);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FL_DARWIN_SYSTEM_DRIVER_H
|
#endif // FL_DARWIN_SYSTEM_DRIVER_H
|
||||||
|
Loading…
Reference in New Issue
Block a user