Fix crash on exit (bug 2549) by correct usage of QApplication

* src/lyx_cb.C
        (quitLyX): lyx_gui::exit takes now an argument

        * src/frontends/{gtk,xforms}/lyx_gui.C
        (lyx_gui::parse_init): rename to lyx_gui::exec and call LyX::exec2
        (void lyx_gui::exit): add exit status argument

        * src/frontends/qt2/lyx_gui.C
        (cleanup): new function for pointer cleanup
        (lyx_gui::parse_init): rename to lyx_gui::exec and call LyX::exec2,
        turn static variables into automatic variables
        (void lyx_gui::exit): add exit status argument
        (start): Use cleanup()
        (exit): ditto

        * src/frontends/lyx_gui.h
        (parse_init): remove
        (exec): new
        (exit): Take exist status argument

        * src/lyx_main.[Ch]
        (LyX::priv_exec): split into LyX::priv_exec and LyX::exec2

        * src/lyx_main.C
        (lyx_exit): New, choose the right exit function
        (showFileError): call lyx_exit
        (LyX::queryUserLyXDir): ditto
        (LyX::init): ditto
        (LyX::priv_exec): ditto
        (LyX::priv_exec): Replace want_gui by lyx_gui::use_gui
        (LyX::priv_exec): replace lyx_gui::parse_init by lyx_gui::exec and
        exec2
        (LyX::init): Replace gui argument by lyx_gui::use_gui



git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/branches/BRANCH_1_4_X@14059 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Georg Baum 2006-06-09 13:07:04 +00:00
parent 01190aaf7a
commit 8fa0d2ccb3
8 changed files with 97 additions and 54 deletions

View File

@ -99,7 +99,7 @@ int getDPI()
} // namespace anon
void lyx_gui::parse_init(int & argc, char * argv[])
void lyx_gui::exec(int & argc, char * argv[])
{
new Gtk::Main(argc, argv);
@ -111,6 +111,8 @@ void lyx_gui::parse_init(int & argc, char * argv[])
// must do this /before/ lyxrc gets read
lyxrc.dpi = getDPI();
LyX::ref().exec2(argc, argv);
}
@ -150,8 +152,9 @@ void lyx_gui::start(string const & batch, std::vector<string> const & files)
}
void lyx_gui::exit()
void lyx_gui::exit(int /*status*/)
{
// FIXME: Don't ignore status
Gtk::Main::quit();
}

View File

@ -43,9 +43,6 @@ std::string const sans_font_name();
/// return a suitable monospaced font name (called from non-gui context too !)
std::string const typewriter_font_name();
/// parse command line and do basic initialisation
void parse_init(int & argc, char * argv[]);
/**
* set up GUI parameters. At this point lyxrc may
* be used.
@ -58,6 +55,11 @@ void parse_lyxrc();
*/
void start(std::string const & batch, std::vector<std::string> const & files);
/**
* Enter the main event loop (\sa LyX::exec2)
*/
void exec(int & argc, char * argv[]);
/**
* Synchronise all pending events.
*/
@ -66,7 +68,7 @@ void sync_events();
/**
* quit running LyX
*/
void exit();
void exit(int);
/**
* return the status flag for a given action. This can be used to tell

View File

@ -78,6 +78,10 @@ using std::string;
extern BufferList bufferlist;
// FIXME: wrong place !
LyXServer * lyxserver;
LyXServerSocket * lyxsocket;
namespace {
int getDPI()
@ -89,11 +93,15 @@ int getDPI()
map<int, shared_ptr<socket_callback> > socket_callbacks;
} // namespace anon
void cleanup()
{
delete lyxsocket;
lyxsocket = 0;
delete lyxserver;
lyxserver = 0;
}
// FIXME: wrong place !
LyXServer * lyxserver;
LyXServerSocket * lyxsocket;
} // namespace anon
// in QLyXKeySym.C
extern void initEncodings();
@ -103,7 +111,6 @@ extern bool lyxX11EventFilter(XEvent * xev);
#endif
#ifdef Q_WS_MACX
extern bool macEventFilter(EventRef event);
extern pascal OSErr
handleOpenDocuments(const AppleEvent* inEvent, AppleEvent* /*reply*/,
long /*refCon*/);
@ -113,7 +120,6 @@ class LQApplication : public QApplication
{
public:
LQApplication(int & argc, char ** argv);
~LQApplication();
#ifdef Q_WS_X11
bool x11EventFilter (XEvent * ev) { return lyxX11EventFilter(ev); }
#endif
@ -134,10 +140,6 @@ LQApplication::LQApplication(int & argc, char ** argv)
}
LQApplication::~LQApplication()
{}
#ifdef Q_WS_MACX
bool LQApplication::macEventFilter(EventRef event)
{
@ -157,22 +159,23 @@ namespace lyx_gui {
bool use_gui = true;
void parse_init(int & argc, char * argv[])
void exec(int & argc, char * argv[])
{
// Force adding of font path _before_ QApplication is initialized
FontLoader::initFontPath();
static LQApplication app(argc, argv);
LQApplication app(argc, argv);
#if QT_VERSION >= 0x030200
// install translation file for Qt built-in dialogs
// These are only installed since Qt 3.2.x
static QTranslator qt_trans(0);
QTranslator qt_trans(0);
if (qt_trans.load(QString("qt_") + QTextCodec::locale(),
qInstallPathTranslations())) {
app.installTranslator(&qt_trans);
qApp->installTranslator(&qt_trans);
// even if the language calls for RtL, don't do that
app.setReverseLayout(false);
qApp->setReverseLayout(false);
lyxerr[Debug::GUI]
<< "Successfully installed Qt translations for locale "
<< QTextCodec::locale() << std::endl;
@ -186,7 +189,7 @@ void parse_init(int & argc, char * argv[])
// These translations are meant to break Qt/Mac menu merging
// algorithm on some entries. It lists the menu names that
// should not be moved to the LyX menu
static QTranslator aqua_trans(0);
QTranslator aqua_trans(0);
aqua_trans.insert(QTranslatorMessage("QMenuBar", "Setting", 0,
"do_not_merge_me"));
aqua_trans.insert(QTranslatorMessage("QMenuBar", "Config", 0,
@ -196,7 +199,7 @@ void parse_init(int & argc, char * argv[])
aqua_trans.insert(QTranslatorMessage("QMenuBar", "Setup", 0,
"do_not_merge_me"));
app.installTranslator(&aqua_trans);
qApp->installTranslator(&aqua_trans);
#endif
using namespace lyx::graphics;
@ -208,6 +211,8 @@ void parse_init(int & argc, char * argv[])
lyxrc.dpi = getDPI();
LoaderQueue::setPriority(10,100);
LyX::ref().exec2(argc, argv);
}
@ -248,9 +253,7 @@ void start(string const & batch, vector<string> const & files)
qApp->exec();
// FIXME
delete lyxsocket;
delete lyxserver;
lyxserver = 0;
cleanup();
}
@ -266,18 +269,16 @@ void sync_events()
}
void exit()
void exit(int status)
{
delete lyxsocket;
delete lyxserver;
lyxserver = 0;
cleanup();
// we cannot call qApp->exit(0) - that could return us
// we cannot call QApplication::exit(status) - that could return us
// into a static dialog return in the lyx code (for example,
// load autosave file QMessageBox. We have to just get the hell
// out.
::exit(0);
::exit(status);
}

View File

@ -84,6 +84,7 @@ namespace {
/// quit lyx
bool finished = false;
int exit_status = 0;
/// estimate DPI from X server
int getDPI()
@ -153,7 +154,7 @@ namespace lyx_gui {
bool use_gui = true;
void parse_init(int & argc, char * argv[])
void exec(int & argc, char * argv[])
{
setDefaults();
@ -198,6 +199,8 @@ void parse_init(int & argc, char * argv[])
lyxrc.dpi = getDPI();
LoaderQueue::setPriority(10,100);
LyX::ref().exec2(argc, argv);
}
@ -327,12 +330,14 @@ void start(string const & batch, vector<string> const & files)
// FIXME: breaks emergencyCleanup
delete lyxsocket;
delete lyxserver;
::exit(exit_status);
}
void exit()
void exit(int status)
{
finished = true;
exit_status = status;
}

View File

@ -216,7 +216,7 @@ void QuitLyX(bool noask)
Alert::warning(_("Unable to remove temporary directory"), msg);
}
lyx_gui::exit();
lyx_gui::exit(0);
}

View File

@ -107,12 +107,23 @@ string cl_system_support;
string cl_user_support;
void lyx_exit(int status)
{
// FIXME: We should not directly call exit(), since it only
// guarantees a return to the system, no application cleanup.
// This may cause troubles with not executed destructors.
if (lyx_gui::use_gui)
lyx_gui::exit(status);
exit(status);
}
void showFileError(string const & error)
{
Alert::warning(_("Could not read configuration file"),
bformat(_("Error while reading the configuration file\n%1$s.\n"
"Please check your installation."), error));
exit(EXIT_FAILURE);
lyx_exit(EXIT_FAILURE);
}
@ -204,14 +215,21 @@ void LyX::priv_exec(int & argc, char * argv[])
{
// Here we need to parse the command line. At least
// we need to parse for "-dbg" and "-help"
bool const want_gui = easyParse(argc, argv);
lyx_gui::use_gui = easyParse(argc, argv);
lyx::support::init_package(argv[0], cl_system_support, cl_user_support,
lyx::support::top_build_dir_is_one_level_up);
if (want_gui)
lyx_gui::parse_init(argc, argv);
// Start the real execution loop.
if (lyx_gui::use_gui)
lyx_gui::exec(argc, argv);
else
exec2(argc, argv);
}
void LyX::exec2(int & argc, char * argv[])
{
// check for any spurious extra arguments
// other than documents
for (int argi = 1; argi < argc ; ++argi) {
@ -224,10 +242,10 @@ void LyX::priv_exec(int & argc, char * argv[])
// Initialization of LyX (reads lyxrc and more)
lyxerr[Debug::INIT] << "Initializing LyX::init..." << endl;
init(want_gui);
init();
lyxerr[Debug::INIT] << "Initializing LyX::init...done" << endl;
if (want_gui)
if (lyx_gui::use_gui)
lyx_gui::parse_lyxrc();
vector<string> files;
@ -270,18 +288,18 @@ void LyX::priv_exec(int & argc, char * argv[])
bool success = false;
if (last_loaded->dispatch(batch_command, &success)) {
QuitLyX(false);
exit(!success);
lyx_exit(!success);
}
}
files.clear(); // the files are already loaded
}
if (want_gui)
if (lyx_gui::use_gui)
lyx_gui::start(batch_command, files);
else {
// Something went wrong above
QuitLyX(false);
exit(EXIT_FAILURE);
lyx_exit(EXIT_FAILURE);
}
}
@ -393,7 +411,7 @@ void LyX::printError(ErrorItem const & ei)
}
void LyX::init(bool gui)
void LyX::init()
{
#ifdef SIGHUP
signal(SIGHUP, error_handler);
@ -404,9 +422,6 @@ void LyX::init(bool gui)
signal(SIGTERM, error_handler);
// SIGPIPE can be safely ignored.
// Disable gui when easyparse says so
lyx_gui::use_gui = gui;
lyxrc.tempdir_path = package().temp_dir();
lyxrc.document_path = package().document_dir();
@ -445,7 +460,7 @@ void LyX::init(bool gui)
// Check that user LyX directory is ok. We don't do that if
// running in batch mode.
if (gui) {
if (lyx_gui::use_gui) {
if (queryUserLyXDir(package().explicit_user_support()))
reconfigureUserLyXDir();
} else {
@ -474,7 +489,7 @@ void LyX::init(bool gui)
lyxerr[Debug::INIT] << "Reading layouts..." << endl;
LyXSetStyle();
if (gui) {
if (lyx_gui::use_gui) {
// Set up bindings
toplevel_keymap.reset(new kb_keymap);
defaultKeyBindings(toplevel_keymap.get());
@ -507,7 +522,7 @@ void LyX::init(bool gui)
// close to zero. We therefore don't try to overcome this
// problem with e.g. asking the user for a new path and
// trying again but simply exit.
exit(EXIT_FAILURE);
lyx_exit(EXIT_FAILURE);
}
if (lyxerr.debugging(Debug::INIT)) {
@ -658,7 +673,7 @@ bool LyX::queryUserLyXDir(bool explicit_userdir)
_("&Create directory"),
_("&Exit LyX"))) {
lyxerr << _("No user LyX directory. Exiting.") << endl;
exit(1);
lyx_exit(EXIT_FAILURE);
}
lyxerr << bformat(_("LyX: Creating directory %1$s"),
@ -669,7 +684,7 @@ bool LyX::queryUserLyXDir(bool explicit_userdir)
// Failed, so let's exit.
lyxerr << _("Failed to create directory. Exiting.")
<< endl;
exit(1);
lyx_exit(EXIT_FAILURE);
}
return true;

View File

@ -32,7 +32,21 @@ class kb_keymap;
/// initial startup
class LyX : boost::noncopyable {
public:
/**
* Execute LyX. The startup sequence is as follows:
* -# LyX::exec()
* -# LyX::priv_exec()
* -# lyx_gui::exec()
* -# LyX::exec2()
* Step 3 is omitted if no gui is wanted. We need lyx_gui::exec()
* only to create the QApplication object in the qt frontend. All
* attempts with static and dynamically allocated QApplication
* objects lead either to harmless error messages on exit
* ("Mutex destroy failure") or crashes (OS X).
*/
static void exec(int & argc, char * argv[]);
/// Execute LyX (inner execution loop, \sa exec)
void exec2(int & argc, char * argv[]);
static LyX & ref();
static LyX const & cref();
@ -56,7 +70,7 @@ private:
void priv_exec(int & argc, char * argv[]);
/// initial LyX set up
void init(bool);
void init();
/// set up the default key bindings
void defaultKeyBindings(kb_keymap * kbmap);
/// set up the default dead key bindings if requested

View File

@ -127,6 +127,9 @@ What's new
- Fix crash when there is a syntax error in a keyboard map file (bug 2604).
- Fix crash on exit on MacOS X, and the well known "Mutex destroy failure"
error message on linux (qt frontend, bugs 2549 and 1029).
* Configuration/Installation:
- Replace the old sh version of lib/configure with the new python version