X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt%2FGuiApplication.cpp;h=ff33065fe34fe313fd051ef1d21227d614f02ec2;hb=b41293352ea8d52890b7668f059fd07f09bd6bb6;hp=a5cb3c8db80080eed1fac0cc3554ad4fee328477;hpb=635a7d77ddc94c63d52494dc4d68a930faccf45f;p=features.git diff --git a/src/frontends/qt/GuiApplication.cpp b/src/frontends/qt/GuiApplication.cpp index a5cb3c8db8..ff33065fe3 100644 --- a/src/frontends/qt/GuiApplication.cpp +++ b/src/frontends/qt/GuiApplication.cpp @@ -137,14 +137,22 @@ #if (QT_VERSION < 0x050000) || (QT_VERSION >= 0x050400) #if defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN) -#if (QT_VERSION < 0x060000) #if (QT_VERSION < 0x050000) #include #define QWINDOWSMIME QWindowsMime +#define QVARIANTTYPE QVariant::Type +#elif (QT_VERSION >= 0x060000) +#include +#include +#include +#define QWINDOWSMIME QWindowsMime +#define QVARIANTTYPE QMetaType +using QWindowsMime = QNativeInterface::Private::QWindowsMime; +using QWindowsApplication = QNativeInterface::Private::QWindowsApplication; #else #include #define QWINDOWSMIME QWinMime -#endif +#define QVARIANTTYPE QVariant::Type #endif #ifdef Q_CC_GNU #include @@ -153,7 +161,7 @@ #endif #endif -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && (QT_VERSION < 0x060000) #include #endif // Q_OS_MAC @@ -189,6 +197,20 @@ frontend::Application * createApplication(int & argc, char * argv[]) #endif +#if defined(Q_OS_MAC) + int const cursor_time_on = NSTextInsertionPointBlinkPeriodOn(); + int const cursor_time_off = NSTextInsertionPointBlinkPeriodOff(); + if (cursor_time_on > 0 && cursor_time_off > 0) { + QApplication::setCursorFlashTime(cursor_time_on + cursor_time_off); + } else if (cursor_time_on <= 0 && cursor_time_off > 0) { + // Off is set and On is undefined of zero + QApplication::setCursorFlashTime(0); + } else if (cursor_time_off <= 0 && cursor_time_on > 0) { + // On is set and Off is undefined of zero + QApplication::setCursorFlashTime(0); + } +#endif + // Setup high DPI handling. This is a bit complicated, but will be default in Qt6. // macOS does it by itself. #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) && !defined(Q_OS_MAC) @@ -503,6 +525,47 @@ QString themeIconName(QString const & action) } +namespace { + +/* Get aliases for icon name. This allows to avoid duplication of + * icons when new versions of functions are introduced for the + * toolbar. A good example is the introduction of layout-toggle in + * #9864. + * The file is parsed by Lexer. Each line is of the form + * + * + * The return value is another icon file name that can be queried. + */ +// FIXME: consider using regular expressions. +QString getAlias(QString name) { + static bool has_aliases = false; + static vector > aliases; + // Initialize aliases list (once). + if (!has_aliases) { + FileName alfile = libFileSearch("images", "icon.aliases"); + if (alfile.exists()) { + Lexer lex; + lex.setFile(alfile); + while(lex.isOK()) { + string from, to; + lex >> from >> to; + if (!from.empty()) + aliases.push_back({toqstr(from), toqstr(to)}); + } + } + has_aliases = true; + } + // check for the following aliases + for (auto const & alias : aliases) { + if (name.contains(alias.first)) + name.replace(alias.first, alias.second); + } + return name; +} + +} // namespace + + IconInfo iconInfo(FuncRequest const & f, bool unknown, bool rtl) { IconInfo res; @@ -516,9 +579,10 @@ IconInfo iconInfo(FuncRequest const & f, bool unknown, bool rtl) name.replace(' ', '_'); name.replace(';', '_'); name.replace('\\', "backslash"); - // avoid duplication for these - name.replace("dialog-toggle", "dialog-show"); names << name; + QString alias = getAlias(name); + if (alias != name) + names << alias; // then special default icon for some lfuns switch (f.action()) { @@ -550,16 +614,19 @@ IconInfo iconInfo(FuncRequest const & f, bool unknown, bool rtl) // next thing to try is function name alone names << lfunname; + QString alias = getAlias(lfunname); + if (alias != lfunname) + names << alias; // and finally maybe the unknown icon if (unknown) names << "unknown"; - search_mode const mode = theGuiApp()->imageSearchMode(); + search_mode const mode = theGuiApp() ? theGuiApp()->imageSearchMode() : support::must_exist; // The folders where icons are searched for QStringList imagedirs; imagedirs << "images/ipa/" << "images/"; - // This is used to search for rtl version of icons which have the +rrtl suffix. + // This is used to search for rtl version of icons which have the +rtl suffix. QStringList suffixes; if (rtl) suffixes << "+rtl"; @@ -752,7 +819,7 @@ public: // //////////////////////////////////////////////////////////////////////// -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && (QT_VERSION < 0x060000) // QMacPasteboardMimeGraphics can only be compiled on Mac. class QMacPasteboardMimeGraphics : public QMacPasteboardMime @@ -812,7 +879,7 @@ public: //////////////////////////////////////////////////////////////////////// // Windows specific stuff goes here... -#if (QT_VERSION < 0x050000) || (QT_VERSION >= 0x050400 && QT_VERSION < 0x060000) +#if (QT_VERSION < 0x050000) || (QT_VERSION >= 0x050400) #if defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN) // QWindowsMimeMetafile can only be compiled on Windows. @@ -859,7 +926,7 @@ public: } QVariant convertToMime(QString const & mimetype, IDataObject * pDataObj, - QVariant::Type /*preferredType*/) const override + QVARIANTTYPE /*preferredType*/) const override { QByteArray data; if (!canConvertToMime(mimetype, pDataObj)) @@ -978,15 +1045,29 @@ struct GuiApplication::Private , last_state_(Qt::ApplicationInactive) #endif { - #if (QT_VERSION < 0x050000) || (QT_VERSION >= 0x050400 && QT_VERSION < 0x060000) + #if (QT_VERSION < 0x050000) || (QT_VERSION >= 0x050400) #if defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN) /// WMF Mime handler for Windows clipboard. wmf_mime_ = new QWindowsMimeMetafile; + #if (QT_VERSION >= 0x060000) + win_app_ = dynamic_cast + (QGuiApplicationPrivate::platformIntegration()); + win_app_->registerMime(wmf_mime_); + #endif #endif #endif initKeySequences(&theTopLevelKeymap()); } + #if (QT_VERSION >= 0x060000) + #if defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN) + ~Private() + { + win_app_->unregisterMime(wmf_mime_); + } + #endif + #endif + void initKeySequences(KeyMap * kb) { keyseq = KeySequence(kb, kb); @@ -1048,15 +1129,18 @@ struct GuiApplication::Private Qt::ApplicationState last_state_; #endif -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && (QT_VERSION < 0x060000) /// Linkback mime handler for MacOSX. QMacPasteboardMimeGraphics mac_pasteboard_mime_; #endif -#if (QT_VERSION < 0x050000) || (QT_VERSION >= 0x050400 && QT_VERSION < 0x060000) +#if (QT_VERSION < 0x050000) || (QT_VERSION >= 0x050400) #if defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN) /// WMF Mime handler for Windows clipboard. QWindowsMimeMetafile * wmf_mime_; +#if (QT_VERSION >= 0x060000) + QWindowsApplication * win_app_; +#endif #endif #endif @@ -1084,7 +1168,7 @@ GuiApplication::GuiApplication(int & argc, char ** argv) QCoreApplication::setOrganizationName(app_name); QCoreApplication::setOrganizationDomain("lyx.org"); QCoreApplication::setApplicationName(lyx_package); -#if QT_VERSION >= 0x050000 && QT_VERSION < 0x060000 +#if QT_VERSION >= 0x050100 && QT_VERSION < 0x060000 QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); #endif @@ -1141,7 +1225,7 @@ GuiApplication::GuiApplication(int & argc, char ** argv) // needs to be done before reading lyxrc QWidget w; - lyxrc.dpi = (w.physicalDpiX() + w.physicalDpiY()) / 2; + lyxrc.dpi = (w.logicalDpiX() + w.logicalDpiY()) / 2; guiApp = this; @@ -1399,10 +1483,17 @@ bool GuiApplication::getStatus(FuncRequest const & cmd, FuncStatus & flag) const case LFUN_REPEAT: case LFUN_PREFERENCES_SAVE: case LFUN_BUFFER_SAVE_AS_DEFAULT: - case LFUN_DEBUG_LEVEL_SET: // these are handled in our dispatch() break; + case LFUN_DEBUG_LEVEL_SET: { + string bad = Debug::badValue(to_utf8(cmd.argument())); + enable = bad.empty(); + if (!bad.empty()) + flag.message(bformat(_("Bad debug value `%1$s'."), from_utf8(bad))); + break; + } + case LFUN_WINDOW_CLOSE: enable = !d->views_.empty(); break; @@ -1548,7 +1639,7 @@ void GuiApplication::updateCurrentView(FuncRequest const & cmd, DispatchResult & BufferView * bv = current_view_->currentBufferView(); if (bv) { - if (dr.needBufferUpdate()) { + if (dr.needBufferUpdate() || bv->buffer().needUpdate()) { bv->cursor().clearBufferUpdate(); bv->buffer().updateBuffer(); } @@ -1645,8 +1736,10 @@ void GuiApplication::gotoBookmark(unsigned int idx, bool openFile, void GuiApplication::reconfigure(string const & option) { // emit message signal. - if (current_view_) + if (current_view_) { current_view_->message(_("Running configure...")); + current_view_->setCursor(Qt::WaitCursor); + } // Run configure in user lyx directory string const lock_file = package().getConfigureLockName(); @@ -1660,6 +1753,9 @@ void GuiApplication::reconfigure(string const & option) LaTeXPackages::getAvailable(); fileUnlock(fd, lock_file.c_str()); + if (current_view_) + current_view_->unsetCursor(); + if (ret) Alert::information(_("System reconfiguration failed"), _("The system reconfiguration has failed.\n" @@ -2285,6 +2381,12 @@ void GuiApplication::onLocaleChanged() } +void GuiApplication::onPaletteChanged() +{ + colorCache().setPalette(palette()); +} + + void GuiApplication::handleKeyFunc(FuncCode action) { char_type c = 0; @@ -2673,6 +2775,18 @@ Menus & GuiApplication::menus() } +bool GuiApplication::needsBackingStore() const +{ + /* Qt on macOS and Wayland does not respect the + * Qt::WA_OpaquePaintEvent attribute and resets the widget backing + * store at each update. Therefore, we use our own backing store + * in these two cases. It is also possible to force the use of the + * backing store for cases like x11 with transparent WM themes. + */ + return platformName() == "cocoa" || platformName().contains("wayland"); +} + + QList GuiApplication::viewIds() const { return d->views_.keys(); @@ -2713,7 +2827,11 @@ void GuiApplication::setGuiLanguage() // opposite. Therefore, long name should be used without truncation. // c.f. http://doc.trolltech.com/4.1/qtranslator.html#load if (!d->qt_trans_.load(language_name, +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + QLibraryInfo::path(QLibraryInfo::TranslationsPath))) { +#else QLibraryInfo::location(QLibraryInfo::TranslationsPath))) { +#endif LYXERR(Debug::LOCALE, "Could not find Qt translations for locale " << language_name); } else { @@ -2747,7 +2865,7 @@ void GuiApplication::execBatchCommands() #if QT_VERSION > 0x040600 setAttribute(Qt::AA_MacDontSwapCtrlAndMeta,lyxrc.mac_dontswap_ctrl_meta); #endif -#if QT_VERSION > 0x050100 +#if QT_VERSION >= 0x050000 && QT_VERSION < 0x060000 setAttribute(Qt::AA_UseHighDpiPixmaps,true); #endif // Create the global default menubar which is shown for the dialogs @@ -2924,6 +3042,11 @@ bool GuiApplication::event(QEvent * e) e->accept(); return true; #endif + case QEvent::ApplicationPaletteChange: { + // runtime switch from/to dark mode + onPaletteChanged(); + return QApplication::event(e); + } default: return QApplication::event(e); }