diff -urN libreoffice-6.3.5.2/vcl/inc/unx/desktops.hxx libreoffice-6.3.5.2-patched/vcl/inc/unx/desktops.hxx --- libreoffice-6.3.5.2/vcl/inc/unx/desktops.hxx 2020-02-11 22:14:56.000000000 +1000 +++ libreoffice-6.3.5.2-patched/vcl/inc/unx/desktops.hxx 2020-03-25 22:24:27.343432021 +1000 @@ -31,6 +31,7 @@ DESKTOP_UNITY, DESKTOP_XFCE, DESKTOP_MATE, + DESKTOP_KDE4, DESKTOP_KDE5, DESKTOP_LXQT }; // keep in sync with desktop_strings[] in salplug.cxx diff -urN libreoffice-6.3.5.2/vcl/source/app/IconThemeSelector.cxx libreoffice-6.3.5.2-patched/vcl/source/app/IconThemeSelector.cxx --- libreoffice-6.3.5.2/vcl/source/app/IconThemeSelector.cxx 2020-02-11 22:14:56.000000000 +1000 +++ libreoffice-6.3.5.2-patched/vcl/source/app/IconThemeSelector.cxx 2020-03-25 22:24:27.343432021 +1000 @@ -56,7 +56,8 @@ return OUString("colibre"); #else OUString r; - if ( desktopEnvironment.equalsIgnoreAsciiCase("kde5") || + if ( desktopEnvironment.equalsIgnoreAsciiCase("kde4") || + desktopEnvironment.equalsIgnoreAsciiCase("kde5") || desktopEnvironment.equalsIgnoreAsciiCase("lxqt") ) { r = "breeze"; } diff -urN libreoffice-6.3.5.2/vcl/source/app/salplug.cxx libreoffice-6.3.5.2-patched/vcl/source/app/salplug.cxx --- libreoffice-6.3.5.2/vcl/source/app/salplug.cxx 2020-02-11 22:14:56.000000000 +1000 +++ libreoffice-6.3.5.2-patched/vcl/source/app/salplug.cxx 2020-03-25 22:41:24.079451287 +1000 @@ -95,6 +95,8 @@ * not access the 'gnome_accessibility_module_shutdown' anymore. * So make sure libgtk+ & co are still mapped into memory when * atk-bridge's atexit handler gets called. + * #i109007# KDE3 seems to have the same problem. + * And same applies for KDE4. */ if( rModuleBase == "gtk" || rModuleBase == "gtk3" || rModuleBase == "gtk3_kde5" || rModuleBase == "win" ) { @@ -185,7 +187,8 @@ desktop == DESKTOP_XFCE || desktop == DESKTOP_MATE ) pList = pStandardFallbackList; - else if( desktop == DESKTOP_KDE5 || + else if( desktop == DESKTOP_KDE4 || + desktop == DESKTOP_KDE5 || desktop == DESKTOP_LXQT ) pList = pKDEFallbackList; @@ -318,7 +321,8 @@ // Order to match desktops.hxx' DesktopType static const char * const desktop_strings[] = { "none", "unknown", "GNOME", "UNITY", - "XFCE", "MATE", "KDE5", "LXQT" }; + "XFCE", "MATE", "KDE4", "KDE5", + "LXQT" }; static OUString aDesktopEnvironment; if( aDesktopEnvironment.isEmpty()) { diff -urN libreoffice-6.3.5.2/vcl/unx/generic/desktopdetect/desktopdetector.cxx libreoffice-6.3.5.2-patched/vcl/unx/generic/desktopdetect/desktopdetector.cxx --- libreoffice-6.3.5.2/vcl/unx/generic/desktopdetect/desktopdetector.cxx 2020-02-11 22:14:56.000000000 +1000 +++ libreoffice-6.3.5.2-patched/vcl/unx/generic/desktopdetect/desktopdetector.cxx 2020-03-25 22:28:24.099436507 +1000 @@ -116,6 +116,80 @@ } +static bool bWasXError = false; + +static bool WasXError() +{ + bool bRet = bWasXError; + bWasXError = false; + return bRet; +} + +extern "C" +{ + static int autodect_error_handler( Display*, XErrorEvent* ) + { + bWasXError = true; + return 0; + } + + typedef int(* XErrorHandler)(Display*,XErrorEvent*); +} + +static int KDEVersion( Display* pDisplay ) +{ + int nRet = 0; + + Atom nFullSession = XInternAtom( pDisplay, "KDE_FULL_SESSION", True ); + Atom nKDEVersion = XInternAtom( pDisplay, "KDE_SESSION_VERSION", True ); + + if( nFullSession ) + { + if( !nKDEVersion ) + return 3; + + Atom aRealType = None; + int nFormat = 8; + unsigned long nItems = 0; + unsigned long nBytesLeft = 0; + unsigned char* pProperty = nullptr; + XGetWindowProperty( pDisplay, + DefaultRootWindow( pDisplay ), + nKDEVersion, + 0, 1, + False, + AnyPropertyType, + &aRealType, + &nFormat, + &nItems, + &nBytesLeft, + &pProperty ); + if( !WasXError() && nItems != 0 && pProperty ) + { + nRet = *reinterpret_cast< sal_Int32* >( pProperty ); + } + if( pProperty ) + { + XFree( pProperty ); + pProperty = nullptr; + } + } + return nRet; +} + +static bool is_kde4_desktop( Display* pDisplay ) +{ + static const char * pFullVersion = getenv( "KDE_FULL_SESSION" ); + static const char * pSessionVersion = getenv( "KDE_SESSION_VERSION" ); + if ( pFullVersion && pSessionVersion && strcmp(pSessionVersion, "4") == 0 ) + return true; + + if ( KDEVersion( pDisplay ) == 4 ) + return true; + + return false; +} + static bool is_kde5_desktop() { static const char * pFullVersion = getenv( "KDE_FULL_SESSION" ); @@ -141,6 +215,8 @@ return DESKTOP_LXQT; if ( aOver.equalsIgnoreAsciiCase( "kde5" ) ) return DESKTOP_KDE5; + if ( aOver.equalsIgnoreAsciiCase( "kde4" ) ) + return DESKTOP_KDE4; if ( aOver.equalsIgnoreAsciiCase( "gnome" ) ) return DESKTOP_GNOME; if ( aOver.equalsIgnoreAsciiCase( "gnome-wayland" ) ) @@ -248,10 +324,16 @@ return DESKTOP_NONE; DesktopType ret; - if ( is_gnome_desktop( pDisplay ) ) - ret = DESKTOP_GNOME; - else - ret = DESKTOP_UNKNOWN; + XErrorHandler pOldHdl = XSetErrorHandler( autodect_error_handler ); + if ( is_kde4_desktop( pDisplay ) ) + ret = DESKTOP_KDE4; + else if ( is_gnome_desktop( pDisplay ) ) + ret = DESKTOP_GNOME; + else + ret = DESKTOP_UNKNOWN; + + // set the default handler again + XSetErrorHandler( pOldHdl ); XCloseDisplay( pDisplay ); diff -urN libreoffice-6.3.5.2/vcl/unx/gtk3_kde5/kde5_filepicker.cxx libreoffice-6.3.5.2-patched/vcl/unx/gtk3_kde5/kde5_filepicker.cxx --- libreoffice-6.3.5.2/vcl/unx/gtk3_kde5/kde5_filepicker.cxx 2020-02-11 22:14:56.000000000 +1000 +++ libreoffice-6.3.5.2-patched/vcl/unx/gtk3_kde5/kde5_filepicker.cxx 2020-03-29 18:18:56.397261034 +1000 @@ -248,7 +248,7 @@ // dialog there in order not to lose the custom controls and insert the custom // widget in the layout returned by QFileDialog::layout() // (which returns nullptr for native file dialogs) - if (Application::GetDesktopEnvironment() == "KDE5") + if (Application::GetDesktopEnvironment() == "KDE5" || Application::GetDesktopEnvironment() == "KDE4") { qApp->installEventFilter(this); } diff -urN libreoffice-6.3.5.2/vcl/unx/kde5/KDE5SalInstance.cxx libreoffice-6.3.5.2-patched/vcl/unx/kde5/KDE5SalInstance.cxx --- libreoffice-6.3.5.2/vcl/unx/kde5/KDE5SalInstance.cxx 2020-02-11 22:14:56.000000000 +1000 +++ libreoffice-6.3.5.2-patched/vcl/unx/kde5/KDE5SalInstance.cxx 2020-03-29 18:16:44.371267490 +1000 @@ -52,7 +52,7 @@ bool KDE5SalInstance::hasNativeFileSelection() const { - if (Application::GetDesktopEnvironment() == "KDE5") + if (Application::GetDesktopEnvironment() == "KDE5" || Application::GetDesktopEnvironment() == "KDE4") return true; return Qt5Instance::hasNativeFileSelection(); } @@ -73,7 +73,7 @@ // In order to insert custom controls, KDE5FilePicker currently relies on KFileWidget // being used in the native file picker, which is only the case for KDE Plasma. // Therefore, return the plain qt5 one in order to not lose custom controls. - if (Application::GetDesktopEnvironment() == "KDE5") + if (Application::GetDesktopEnvironment() == "KDE5" || Application::GetDesktopEnvironment() == "KDE4") return new KDE5FilePicker(context, eMode); return Qt5Instance::createPicker(context, eMode); }