mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-12 16:50:39 +00:00
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:
parent
01190aaf7a
commit
8fa0d2ccb3
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -216,7 +216,7 @@ void QuitLyX(bool noask)
|
||||
Alert::warning(_("Unable to remove temporary directory"), msg);
|
||||
}
|
||||
|
||||
lyx_gui::exit();
|
||||
lyx_gui::exit(0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user