Am Montag, 5. Juni 2006 21:35 schrieb Bennett Helm: > That does it. With more testing on both Qt-3 and Qt-4 versions, I > still can't get a crash.
I hoped that. > (Does this patch work for LyX-1.4.x as well?) No, take the attached one. Georg
Index: src/lyx_cb.C =================================================================== --- src/lyx_cb.C (Revision 14013) +++ src/lyx_cb.C (Arbeitskopie) @@ -216,7 +216,7 @@ void QuitLyX(bool noask) Alert::warning(_("Unable to remove temporary directory"), msg); } - lyx_gui::exit(); + lyx_gui::exit(0); } Index: src/frontends/gtk/lyx_gui.C =================================================================== --- src/frontends/gtk/lyx_gui.C (Revision 14013) +++ src/frontends/gtk/lyx_gui.C (Arbeitskopie) @@ -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, cha // 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 } -void lyx_gui::exit() +void lyx_gui::exit(int /*status*/) { + // FIXME: Don't ignore status Gtk::Main::quit(); } Index: src/frontends/qt2/lyx_gui.C =================================================================== --- src/frontends/qt2/lyx_gui.C (Revision 14013) +++ src/frontends/qt2/lyx_gui.C (Arbeitskopie) @@ -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 * x #endif #ifdef Q_WS_MACX -extern bool macEventFilter(EventRef event); extern pascal OSErr handleOpenDocuments(const AppleEvent* inEvent, AppleEvent* /*reply*/, long /*refCon*/); @@ -157,22 +164,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 +194,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 +204,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 +216,8 @@ void parse_init(int & argc, char * argv[ lyxrc.dpi = getDPI(); LoaderQueue::setPriority(10,100); + + LyX::ref().exec2(argc, argv); } @@ -248,9 +258,7 @@ void start(string const & batch, vector< qApp->exec(); // FIXME - delete lyxsocket; - delete lyxserver; - lyxserver = 0; + cleanup(); } @@ -266,18 +274,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); } Index: src/frontends/xforms/lyx_gui.C =================================================================== --- src/frontends/xforms/lyx_gui.C (Revision 14013) +++ src/frontends/xforms/lyx_gui.C (Arbeitskopie) @@ -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< // FIXME: breaks emergencyCleanup delete lyxsocket; delete lyxserver; + ::exit(exit_status); } -void exit() +void exit(int status) { finished = true; + exit_status = status; } Index: src/frontends/lyx_gui.h =================================================================== --- src/frontends/lyx_gui.h (Revision 14013) +++ src/frontends/lyx_gui.h (Arbeitskopie) @@ -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. @@ -59,6 +56,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. */ void sync_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 Index: src/lyx_main.C =================================================================== --- src/lyx_main.C (Revision 14013) +++ src/lyx_main.C (Arbeitskopie) @@ -107,12 +107,20 @@ string cl_system_support; string cl_user_support; +void lyx_exit(int status) +{ + 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,30 +212,37 @@ void LyX::priv_exec(int & argc, char * a { // 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) { if (argv[argi][0] == '-') { lyxerr << bformat(_("Wrong command line option `%1$s'. Exiting."), argv[argi]) << endl; - exit(1); + lyx_exit(EXIT_FAILURE); } } // 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; @@ -276,12 +291,12 @@ void LyX::priv_exec(int & argc, char * a 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); } } @@ -379,7 +394,7 @@ static void error_handler(int err_sig) if (err_sig == SIGSEGV || !getEnv("LYXDEBUG").empty()) #endif lyx::support::abort(); - exit(0); + lyx_exit(EXIT_SUCCESS); } } @@ -393,7 +408,7 @@ void LyX::printError(ErrorItem const & e } -void LyX::init(bool gui) +void LyX::init() { #ifdef SIGHUP signal(SIGHUP, error_handler); @@ -404,9 +419,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 +457,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 +486,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 +519,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 +670,7 @@ bool LyX::queryUserLyXDir(bool explicit_ _("&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 +681,7 @@ bool LyX::queryUserLyXDir(bool explicit_ // Failed, so let's exit. lyxerr << _("Failed to create directory. Exiting.") << endl; - exit(1); + lyx_exit(EXIT_FAILURE); } return true; Index: src/lyx_main.h =================================================================== --- src/lyx_main.h (Revision 14013) +++ src/lyx_main.h (Arbeitskopie) @@ -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