kde5: copy basic kde4 blocks -> kde5 and build againt qt5/kf5 libs

Change-Id: I70f0c4147721a20459e1183ff40cf0ac8adf49e6
This commit is contained in:
Katarina Behrens
2017-08-28 18:29:20 +02:00
committed by Thorsten Behrens
parent 07cd70c86c
commit dd7a3147f1
21 changed files with 2884 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
$(eval $(call gb_CustomTarget_CustomTarget,vcl/unx/kde5))
$(call gb_CustomTarget_get_target,vcl/unx/kde5) : \
$(call gb_CustomTarget_get_workdir,vcl/unx/kde5)/KDE5XLib.moc \
$(call gb_CustomTarget_get_workdir,vcl/unx/kde5)/tst_exclude_socket_notifiers.moc \
$(call gb_CustomTarget_get_workdir,vcl/unx/kde5)/tst_exclude_posted_events.moc
$(call gb_CustomTarget_get_workdir,vcl/unx/kde5)/%.moc : \
$(SRCDIR)/vcl/unx/kde5/%.hxx \
| $(call gb_CustomTarget_get_workdir,vcl/unx/kde5)/.dir
$(call gb_Output_announce,$(subst $(WORKDIR)/,,$@),$(true),MOC,1)
$(MOC5) $< -o $@
# vim: set noet sw=4:

View File

@@ -0,0 +1,96 @@
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# This file incorporates work covered by the following license notice:
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed
# with this work for additional information regarding copyright
# ownership. The ASF licenses this file to you under the Apache
# License, Version 2.0 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.apache.org/licenses/LICENSE-2.0 .
#
$(eval $(call gb_Library_Library,vclplug_kde5))
$(eval $(call gb_Library_use_custom_headers,vclplug_kde5,vcl/unx/kde5))
$(eval $(call gb_Library_set_include,vclplug_kde5,\
$$(INCLUDE) \
-I$(SRCDIR)/vcl/inc \
))
$(eval $(call gb_Library_add_defs,vclplug_kde5,\
-DVCLPLUG_KDE5_IMPLEMENTATION \
))
$(eval $(call gb_Library_use_sdk_api,vclplug_kde5))
$(eval $(call gb_Library_use_libraries,vclplug_kde5,\
vclplug_gen \
vcl \
tl \
utl \
sot \
ucbhelper \
basegfx \
comphelper \
cppuhelper \
i18nlangtag \
i18nutil \
$(if $(ENABLE_JAVA), \
jvmaccess) \
cppu \
sal \
))
$(eval $(call gb_Library_use_externals,vclplug_kde5,\
boost_headers \
icuuc \
kde5 \
epoxy \
))
$(eval $(call gb_Library_add_libs,vclplug_kde5,\
-lX11 \
-lXext \
-lSM \
-lICE \
))
ifneq ($(KF5_HAVE_GLIB),)
$(eval $(call gb_Library_add_defs,vclplug_kde5,\
$(KF5_GLIB_CFLAGS) \
))
$(eval $(call gb_Library_add_libs,vclplug_kde5,\
$(KF5_GLIB_LIBS) \
))
endif
$(eval $(call gb_Library_add_exception_objects,vclplug_kde5,\
vcl/unx/kde5/KDE5Data \
vcl/unx/kde5/KDE5SalDisplay \
vcl/unx/kde5/KDE5SalFrame \
vcl/unx/kde5/KDE5SalGraphics \
vcl/unx/kde5/KDE5SalInstance \
vcl/unx/kde5/KDE5XLib \
vcl/unx/kde5/main \
))
ifeq ($(OS),LINUX)
$(eval $(call gb_Library_add_libs,vclplug_kde5,\
-lm \
-ldl \
-lpthread \
))
endif
# vim: set noet sw=4 ts=4:

View File

@@ -81,6 +81,12 @@ $(eval $(call gb_Module_add_targets,vcl,\
Library_vclplug_kde4 \
))
endif
ifneq ($(ENABLE_KDE5),)
$(eval $(call gb_Module_add_targets,vcl,\
CustomTarget_kde5_moc \
Library_vclplug_kde5 \
))
endif
endif
ifeq ($(OS),MACOSX)

View File

@@ -0,0 +1,28 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#pragma once
// the service names
#define FILE_PICKER_SERVICE_NAME "com.sun.star.ui.dialogs.KDE4FilePicker"
// the implementation names
#define FILE_PICKER_IMPL_NAME "com.sun.star.ui.dialogs.KDE4FilePicker"
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

68
vcl/unx/kde5/KDE5Data.cxx Normal file
View File

@@ -0,0 +1,68 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <QtWidgets/QStyle>
#include <QtWidgets/QApplication>
#undef Region
#include "KDE5Data.hxx"
#include "KDE5XLib.hxx"
#include "KDE5SalDisplay.hxx"
KDEData::~KDEData()
{
}
void KDEData::Init()
{
pXLib_ = new KDEXLib();
pXLib_->Init();
SetDisplay( SalKDEDisplay::self() );
}
void KDEData::initNWF()
{
ImplSVData *pSVData = ImplGetSVData();
// draw toolbars on separate lines
pSVData->maNWFData.mbDockingAreaSeparateTB = true;
// no borders for menu, theming does that
pSVData->maNWFData.mbFlatMenu = true;
// Qt theme engines may support a rollover menubar
pSVData->maNWFData.mbRolloverMenubar = true;
pSVData->maNWFData.mbNoFocusRects = true;
// Styled menus need additional space
QStyle *style = QApplication::style();
pSVData->maNWFData.mnMenuFormatBorderX =
style->pixelMetric( QStyle::PM_MenuPanelWidth ) +
style->pixelMetric( QStyle::PM_MenuHMargin );
pSVData->maNWFData.mnMenuFormatBorderY =
style->pixelMetric( QStyle::PM_MenuPanelWidth ) +
style->pixelMetric( QStyle::PM_MenuVMargin );
}
void KDEData::deInitNWF()
{
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

37
vcl/unx/kde5/KDE5Data.hxx Normal file
View File

@@ -0,0 +1,37 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#pragma once
#include <unx/saldisp.hxx>
#include <unx/saldata.hxx>
class KDEData : public X11SalData
{
public:
explicit KDEData( SalInstance *pInstance )
: X11SalData( SAL_DATA_KDE4, pInstance ) {}
virtual ~KDEData() override;
virtual void Init() override;
virtual void initNWF() override;
virtual void deInitNWF() override;
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@@ -0,0 +1,98 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include "VCLKDE5Application.hxx"
#include "KDE5SalDisplay.hxx"
#ifdef Bool
#undef Bool
#endif
#include "KDE5XLib.hxx"
#include <assert.h>
SalKDEDisplay* SalKDEDisplay::selfptr = nullptr;
SalKDEDisplay::SalKDEDisplay( Display* pDisp )
: SalX11Display( pDisp )
{
assert( selfptr == nullptr );
selfptr = this;
xim_protocol = XInternAtom( pDisp_, "_XIM_PROTOCOL", False );
}
SalKDEDisplay::~SalKDEDisplay()
{
// in case never a frame opened
static_cast<KDEXLib*>(GetXLib())->doStartup();
// clean up own members
doDestruct();
selfptr = nullptr;
// prevent SalDisplay from closing KApplication's display
pDisp_ = nullptr;
}
void SalKDEDisplay::Yield()
{
if( DispatchInternalEvent() )
return;
// Prevent blocking from Drag'n'Drop events, which may have already have processed the event
if (XEventsQueued( pDisp_, QueuedAfterReading ) == 0)
return;
DBG_ASSERT( static_cast<SalYieldMutex*>(GetSalData()->m_pInstance->GetYieldMutex())->GetThreadId() ==
osl::Thread::getCurrentIdentifier(),
"will crash soon since solar mutex not locked in SalKDEDisplay::Yield" );
/*XEvent event;
XNextEvent( pDisp_, &event );
if( checkDirectInputEvent( &event ))
return;
qApp->x11ProcessEvent( &event );*/
}
// HACK: When using Qt event loop, input methods (japanese, etc.) will get broken because
// of XFilterEvent() getting called twice, once by Qt, once by LO (bnc#665112).
// This function is therefore called before any XEvent is passed to Qt event handling
// and if it is a keyboard event and no Qt widget is the active window (i.e. we are
// processing events for some LO window), then feed the event only to LO directly and skip Qt
// completely. Skipped events are KeyPress, KeyRelease and also _XIM_PROTOCOL client message
// (seems to be necessary too, hopefully there are not other internal XIM messages that
// would need this handling).
bool SalKDEDisplay::checkDirectInputEvent( xcb_generic_event_t* ev )
{
switch (ev->response_type & ~0x80)
{
case XCB_CLIENT_MESSAGE:
case XCB_KEY_PRESS:
case XCB_KEY_RELEASE:
if( QApplication::activeWindow() == nullptr )
{
// Dispatch(ev);
return true;
}
break;
}
return false;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@@ -0,0 +1,47 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#pragma once
#include <unx/saldisp.hxx>
#include <xcb/xcb.h>
#ifdef CursorShape
#undef CursorShape
#endif
class SalKDEDisplay : public SalX11Display
{
public:
explicit SalKDEDisplay( Display* pDisp );
virtual ~SalKDEDisplay() override;
static SalKDEDisplay* self();
virtual void Yield() override;
bool checkDirectInputEvent( xcb_generic_event_t* ev );
private:
Atom xim_protocol;
static SalKDEDisplay* selfptr;
};
inline SalKDEDisplay* SalKDEDisplay::self()
{
return selfptr;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@@ -0,0 +1,381 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <memory>
#include <QtGui/QColor>
#include <QtWidgets/QStyle>
#include <QtCore/QDebug>
#include <QtWidgets/QToolTip>
#include <QtWidgets/QApplication>
#include <QtWidgets/QMenuBar>
#include <KConfig>
#include <KConfigGroup>
#include <KSharedConfig>
#undef Region
#include "KDE5SalFrame.hxx"
#include "KDE5XLib.hxx"
#include "KDE5SalGraphics.hxx"
#include <tools/color.hxx>
#include <vcl/font.hxx>
#include <vcl/settings.hxx>
#include "unx/fontmanager.hxx"
#include <svdata.hxx>
#include <boost/optional.hpp>
KDESalFrame::KDESalFrame( SalFrame* pParent, SalFrameStyleFlags nState ) :
X11SalFrame( pParent, nState )
{
}
void KDESalFrame::Show( bool bVisible, bool bNoActivate )
{
if ( !GetParent() && ! (GetStyle() & SalFrameStyleFlags::INTRO) )
{
KDEXLib* pXLib = static_cast<KDEXLib*>(GetDisplay()->GetXLib());
pXLib->doStartup();
}
X11SalFrame::Show( bVisible, bNoActivate );
}
/** Helper function to convert colors.
*/
static Color toColor( const QColor &rColor )
{
return Color( rColor.red(), rColor.green(), rColor.blue() );
}
/** Helper function to add information to Font from QFont.
Mostly grabbed from the Gtk+ vclplug (salnativewidgets-gtk.cxx).
*/
static vcl::Font toFont( const QFont &rQFont, const css::lang::Locale& rLocale )
{
psp::FastPrintFontInfo aInfo;
QFontInfo qFontInfo( rQFont );
// set family name
aInfo.m_aFamilyName = OUString( static_cast<const char *>(rQFont.family().toUtf8()), strlen( static_cast<const char *>(rQFont.family().toUtf8()) ), RTL_TEXTENCODING_UTF8 );
// set italic
aInfo.m_eItalic = ( qFontInfo.italic()? ITALIC_NORMAL: ITALIC_NONE );
// set weight
int nWeight = qFontInfo.weight();
if ( nWeight <= QFont::Light )
aInfo.m_eWeight = WEIGHT_LIGHT;
else if ( nWeight <= QFont::Normal )
aInfo.m_eWeight = WEIGHT_NORMAL;
else if ( nWeight <= QFont::DemiBold )
aInfo.m_eWeight = WEIGHT_SEMIBOLD;
else if ( nWeight <= QFont::Bold )
aInfo.m_eWeight = WEIGHT_BOLD;
else
aInfo.m_eWeight = WEIGHT_ULTRABOLD;
// set width
int nStretch = rQFont.stretch();
if ( nStretch <= QFont::UltraCondensed )
aInfo.m_eWidth = WIDTH_ULTRA_CONDENSED;
else if ( nStretch <= QFont::ExtraCondensed )
aInfo.m_eWidth = WIDTH_EXTRA_CONDENSED;
else if ( nStretch <= QFont::Condensed )
aInfo.m_eWidth = WIDTH_CONDENSED;
else if ( nStretch <= QFont::SemiCondensed )
aInfo.m_eWidth = WIDTH_SEMI_CONDENSED;
else if ( nStretch <= QFont::Unstretched )
aInfo.m_eWidth = WIDTH_NORMAL;
else if ( nStretch <= QFont::SemiExpanded )
aInfo.m_eWidth = WIDTH_SEMI_EXPANDED;
else if ( nStretch <= QFont::Expanded )
aInfo.m_eWidth = WIDTH_EXPANDED;
else if ( nStretch <= QFont::ExtraExpanded )
aInfo.m_eWidth = WIDTH_EXTRA_EXPANDED;
else
aInfo.m_eWidth = WIDTH_ULTRA_EXPANDED;
SAL_INFO( "vcl.kde4", "font name BEFORE system match: \"" << aInfo.m_aFamilyName << "\"" );
// match font to e.g. resolve "Sans"
psp::PrintFontManager::get().matchFont( aInfo, rLocale );
SAL_INFO( "vcl.kde4", "font match " <<
(aInfo.m_nID != 0 ? "succeeded" : "failed") <<
", name AFTER: \"" << aInfo.m_aFamilyName << "\"" );
// font height
int nPointHeight = qFontInfo.pointSize();
if ( nPointHeight <= 0 )
nPointHeight = rQFont.pointSize();
// Create the font
vcl::Font aFont( aInfo.m_aFamilyName, Size( 0, nPointHeight ) );
if( aInfo.m_eWeight != WEIGHT_DONTKNOW )
aFont.SetWeight( aInfo.m_eWeight );
if( aInfo.m_eWidth != WIDTH_DONTKNOW )
aFont.SetWidthType( aInfo.m_eWidth );
if( aInfo.m_eItalic != ITALIC_DONTKNOW )
aFont.SetItalic( aInfo.m_eItalic );
if( aInfo.m_ePitch != PITCH_DONTKNOW )
aFont.SetPitch( aInfo.m_ePitch );
return aFont;
}
/** Implementation of KDE integration's main method.
*/
void KDESalFrame::UpdateSettings( AllSettings& rSettings )
{
StyleSettings style( rSettings.GetStyleSettings() );
bool bSetTitleFont = false;
// General settings
QPalette pal = QApplication::palette();
style.SetToolbarIconSize( ToolbarIconSize::Large );
style.SetActiveColor(toColor(pal.color(QPalette::Active, QPalette::Window)));
style.SetDeactiveColor(toColor(pal.color(QPalette::Inactive, QPalette::Window)));
style.SetActiveTextColor(toColor(pal.color(QPalette::Active, QPalette::WindowText)));
style.SetDeactiveTextColor(toColor(pal.color(QPalette::Inactive, QPalette::WindowText)));
// WM settings
/*KConfig *pConfig = KGlobal::config().data();
if ( pConfig )
{
const char *pKey;
{
KConfigGroup aWMGroup = pConfig->group( "WM" );
pKey = "titleFont";
if (aWMGroup.hasKey(pKey))
{
vcl::Font aFont = toFont(aWMGroup.readEntry(pKey, QFont()),
rSettings.GetUILanguageTag().getLocale());
style.SetTitleFont( aFont );
bSetTitleFont = true;
}
}
KConfigGroup aIconsGroup = pConfig->group("Icons");
pKey = "Theme";
if (aIconsGroup.hasKey(pKey))
style.SetPreferredIconTheme( readEntryUntranslated(&aIconsGroup, pKey));
//toolbar
pKey = "toolbarFont";
if (aIconsGroup.hasKey(pKey))
{
vcl::Font aFont = toFont(aIconsGroup.readEntry(pKey, QFont()),
rSettings.GetUILanguageTag().getLocale());
style.SetToolFont( aFont );
}
}*/
Color aFore = toColor( pal.color( QPalette::Active, QPalette::WindowText ) );
Color aBack = toColor( pal.color( QPalette::Active, QPalette::Window ) );
Color aText = toColor( pal.color( QPalette::Active, QPalette::Text ) );
Color aBase = toColor( pal.color( QPalette::Active, QPalette::Base ) );
Color aButn = toColor( pal.color( QPalette::Active, QPalette::ButtonText ) );
Color aMid = toColor( pal.color( QPalette::Active, QPalette::Mid ) );
Color aHigh = toColor( pal.color( QPalette::Active, QPalette::Highlight ) );
Color aHighText = toColor( pal.color( QPalette::Active, QPalette::HighlightedText ) );
style.SetSkipDisabledInMenus( true );
// Foreground
style.SetRadioCheckTextColor( aFore );
style.SetLabelTextColor( aFore );
style.SetDialogTextColor( aFore );
style.SetGroupTextColor( aFore );
// Text
style.SetFieldTextColor( aText );
style.SetFieldRolloverTextColor( aText );
style.SetWindowTextColor( aText );
style.SetToolTextColor( aText );
// Base
style.SetFieldColor( aBase );
style.SetWindowColor( aBase );
style.SetActiveTabColor( aBase );
// Buttons
style.SetButtonTextColor( aButn );
style.SetButtonRolloverTextColor( aButn );
// Tabs
style.SetTabTextColor( aButn );
style.SetTabRolloverTextColor( aButn );
style.SetTabHighlightTextColor( aButn );
// Disable color
style.SetDisableColor( toColor( pal.color( QPalette::Disabled, QPalette::WindowText ) ) );
// Workspace
style.SetWorkspaceColor( aMid );
// Background
style.Set3DColors( aBack );
style.SetFaceColor( aBack );
style.SetInactiveTabColor( aBack );
style.SetDialogColor( aBack );
style.SetCheckedColorSpecialCase( );
// Selection
style.SetHighlightColor( aHigh );
style.SetHighlightTextColor( aHighText );
// Tooltip
style.SetHelpColor( toColor( QToolTip::palette().color( QPalette::Active, QPalette::ToolTipBase )));
style.SetHelpTextColor( toColor( QToolTip::palette().color( QPalette::Active, QPalette::ToolTipText )));
// Font
vcl::Font aFont = toFont( QApplication::font(), rSettings.GetUILanguageTag().getLocale() );
style.SetAppFont( aFont );
style.SetMenuFont( aFont ); // will be changed according to pMenuBar
style.SetLabelFont( aFont );
style.SetRadioCheckFont( aFont );
style.SetPushButtonFont( aFont );
style.SetFieldFont( aFont );
style.SetIconFont( aFont );
style.SetTabFont( aFont );
style.SetGroupFont( aFont );
aFont.SetWeight( WEIGHT_BOLD );
if( !bSetTitleFont )
{
style.SetTitleFont( aFont );
}
style.SetFloatTitleFont( aFont );
style.SetHelpFont( toFont( QToolTip::font(), rSettings.GetUILanguageTag().getLocale()));
int flash_time = QApplication::cursorFlashTime();
style.SetCursorBlinkTime( flash_time != 0 ? flash_time/2 : STYLE_CURSOR_NOBLINKTIME );
// Menu
std::unique_ptr<QMenuBar> pMenuBar = std::unique_ptr<QMenuBar>( new QMenuBar() );
QPalette qMenuCG = pMenuBar->palette();
// Menu text and background color, theme specific
Color aMenuFore = toColor( qMenuCG.color( QPalette::WindowText ) );
Color aMenuBack = toColor( qMenuCG.color( QPalette::Window ) );
style.SetMenuTextColor( aMenuFore );
style.SetMenuBarTextColor( style.GetPersonaMenuBarTextColor().get_value_or( aMenuFore ) );
style.SetMenuColor( aMenuBack );
style.SetMenuBarColor( aMenuBack );
style.SetMenuHighlightColor( toColor ( qMenuCG.color( QPalette::Highlight ) ) );
style.SetMenuHighlightTextColor( toColor ( qMenuCG.color( QPalette::HighlightedText ) ) );
// set special menubar highlight text color
if ( QApplication::style()->inherits( "HighContrastStyle" ) )
ImplGetSVData()->maNWFData.maMenuBarHighlightTextColor = toColor( qMenuCG.color( QPalette::HighlightedText ) );
else
ImplGetSVData()->maNWFData.maMenuBarHighlightTextColor = aMenuFore;
// set menubar rollover color
if ( pMenuBar->style()->styleHint( QStyle::SH_MenuBar_MouseTracking ) )
{
style.SetMenuBarRolloverColor( toColor ( qMenuCG.color( QPalette::Highlight ) ) );
style.SetMenuBarRolloverTextColor( ImplGetSVData()->maNWFData.maMenuBarHighlightTextColor );
}
else
{
style.SetMenuBarRolloverColor( aMenuBack );
style.SetMenuBarRolloverTextColor( aMenuFore );
}
style.SetMenuBarHighlightTextColor(style.GetMenuHighlightTextColor());
// Font
aFont = toFont( pMenuBar->font(), rSettings.GetUILanguageTag().getLocale() );
style.SetMenuFont( aFont );
// Scroll bar size
style.SetScrollBarSize( QApplication::style()->pixelMetric( QStyle::PM_ScrollBarExtent ) );
style.SetMinThumbSize( QApplication::style()->pixelMetric( QStyle::PM_ScrollBarSliderMin ));
// These colors are used for the ruler text and marks
style.SetShadowColor(toColor(pal.color(QPalette::Disabled, QPalette::WindowText)));
style.SetDarkShadowColor(toColor(pal.color(QPalette::Inactive, QPalette::WindowText)));
rSettings.SetStyleSettings( style );
}
void KDESalFrame::ReleaseGraphics( SalGraphics *pGraphics )
{
for( int i = 0; i < nMaxGraphics; i++ )
{
if( m_aGraphics[i].pGraphics.get() == pGraphics )
{
m_aGraphics[i].bInUse = false;
break;
}
}
}
void KDESalFrame::updateGraphics( bool bClear )
{
Drawable aDrawable = bClear ? None : GetWindow();
for( int i = 0; i < nMaxGraphics; i++ )
{
if( m_aGraphics[i].bInUse )
m_aGraphics[i].pGraphics->SetDrawable( aDrawable, GetScreenNumber() );
}
}
SalGraphics* KDESalFrame::AcquireGraphics()
{
if( GetWindow() )
{
for( int i = 0; i < nMaxGraphics; i++ )
{
if( ! m_aGraphics[i].bInUse )
{
m_aGraphics[i].bInUse = true;
if( ! m_aGraphics[i].pGraphics )
{
m_aGraphics[i].pGraphics.reset( new KDESalGraphics );
m_aGraphics[i].pGraphics->Init( this, GetWindow(), GetScreenNumber() );
}
return m_aGraphics[i].pGraphics.get();
}
}
}
return nullptr;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@@ -0,0 +1,53 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#pragma once
#include <memory>
#include <unx/saldisp.hxx>
#include <unx/salframe.h>
#include <unx/salgdi.h>
class KDESalFrame : public X11SalFrame
{
private:
static const int nMaxGraphics = 2;
struct GraphicsHolder
{
std::unique_ptr<X11SalGraphics> pGraphics;
bool bInUse;
GraphicsHolder() : bInUse( false ) {}
};
GraphicsHolder m_aGraphics[ nMaxGraphics ];
public:
KDESalFrame( SalFrame* pParent, SalFrameStyleFlags nStyle );
virtual SalGraphics* AcquireGraphics() override;
virtual void ReleaseGraphics( SalGraphics *pGraphics ) override;
virtual void updateGraphics( bool bClear ) override;
virtual void UpdateSettings( AllSettings& rSettings ) override;
virtual void Show( bool bVisible, bool bNoActivate = false ) override;
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,53 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#pragma once
#include <memory>
#include <rtl/string.hxx>
#include <unx/saldisp.hxx>
#include <unx/salgdi.h>
#include <QtGui/QImage>
/**
* Handles native graphics requests and performs the needed drawing operations.
*/
class KDESalGraphics : public X11SalGraphics
{
public:
virtual bool IsNativeControlSupported( ControlType, ControlPart ) override;
virtual bool hitTestNativeControl( ControlType, ControlPart,
const tools::Rectangle&, const Point&, bool& ) override;
virtual bool drawNativeControl( ControlType, ControlPart, const tools::Rectangle&,
ControlState, const ImplControlValue&, const OUString& ) override;
virtual bool getNativeControlRegion( ControlType, ControlPart, const tools::Rectangle&,
ControlState, const ImplControlValue&,
const OUString&, tools::Rectangle&, tools::Rectangle& ) override;
private:
std::unique_ptr<QImage> m_image;
QRect lastPopupRect;
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@@ -0,0 +1,70 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
//#include "KDE4FilePicker.hxx"
#include <QtCore/QAbstractEventDispatcher>
#include <QtCore/QThread>
#include <QtGui/QClipboard>
#include <QtWidgets/QApplication>
#include <QtWidgets/QFrame>
#include <QtX11Extras/QX11Info>
#include "KDE5SalInstance.hxx"
#include "KDE5SalFrame.hxx"
#include "KDE5XLib.hxx"
#include "KDE5SalDisplay.hxx"
using namespace com::sun::star;
KDESalInstance::KDESalInstance(SalYieldMutex* pMutex)
: X11SalInstance(pMutex)
{
ImplSVData* pSVData = ImplGetSVData();
delete pSVData->maAppData.mpToolkitName;
pSVData->maAppData.mpToolkitName = new OUString("kde4");
}
SalFrame* KDESalInstance::CreateFrame( SalFrame *pParent, SalFrameStyleFlags nState )
{
return new KDESalFrame( pParent, nState );
}
uno::Reference< ui::dialogs::XFilePicker2 > KDESalInstance::createFilePicker(
const uno::Reference< uno::XComponentContext >& xMSF )
{
/*KDEXLib* kdeXLib = static_cast<KDEXLib*>( mpXLib );
if (kdeXLib->allowKdeDialogs())
return uno::Reference< ui::dialogs::XFilePicker2 >(
kdeXLib->createFilePicker(xMSF) );
else*/
return X11SalInstance::createFilePicker( xMSF );
}
SalX11Display* KDESalInstance::CreateDisplay() const
{
return new SalKDEDisplay( QX11Info::display() );
}
bool KDESalInstance::IsMainThread() const
{
return qApp->thread() == QThread::currentThread();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@@ -0,0 +1,45 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#pragma once
#include <unx/salinst.h>
class SalYieldMutex;
class SalFrame;
class KDESalInstance : public X11SalInstance
{
protected:
virtual SalX11Display* CreateDisplay() const override;
public:
explicit KDESalInstance(SalYieldMutex* pMutex);
virtual SalFrame* CreateFrame( SalFrame* pParent, SalFrameStyleFlags nStyle ) override;
virtual bool hasNativeFileSelection() const override { return true; }
virtual css::uno::Reference< css::ui::dialogs::XFilePicker2 >
createFilePicker( const css::uno::Reference<
css::uno::XComponentContext >& ) override;
virtual bool IsMainThread() const override;
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

407
vcl/unx/kde5/KDE5XLib.cxx Normal file
View File

@@ -0,0 +1,407 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <QtCore/QAbstractEventDispatcher>
#include <QtCore/QThread>
#include <QtWidgets/QApplication>
#include <QtWidgets/QFrame>
#include <QtGui/QClipboard>
#include <QtGui/QFrame>
#include <QtX11Extras/QX11Info>
#include "config_kde5.h"
#include "KDE5XLib.hxx"
#include "VCLKDE5Application.hxx"
#include "KDE5SalInstance.hxx"
#include <KAboutData>
#include <KLocalizedString>
#include "unx/i18n_im.hxx"
#include "unx/i18n_xkb.hxx"
#include "unx/saldata.hxx"
#include <o3tl/make_unique.hxx>
#include "osl/process.h"
#include "KDE5SalDisplay.hxx"
#undef Bool
#if KF5_HAVE_GLIB
//#include "KDE4FilePicker.hxx"
#include "tst_exclude_socket_notifiers.moc"
#include "tst_exclude_posted_events.moc"
#endif
KDEXLib::KDEXLib() :
SalXLib(), m_bStartupDone(false),
m_nFakeCmdLineArgs( 0 ),
m_isGlibEventLoopType(false), m_allowKdeDialogs(false),
m_timerEventId( -1 ), m_postUserEventId( -1 )
{
m_timerEventId = QEvent::registerEventType();
m_postUserEventId = QEvent::registerEventType();
// the timers created here means they belong to the main thread.
// As the timeoutTimer runs the LO event queue, which may block on a dialog,
// the timer has to use a Qt::QueuedConnection, otherwise the nested event
// loop will detect the blocking timer and drop it from the polling
// freezing LO X11 processing.
timeoutTimer.setSingleShot( true );
connect( &timeoutTimer, SIGNAL( timeout()), this, SLOT( timeoutActivated()), Qt::QueuedConnection );
// QTimer::start() can be called only in its (here main) thread, so this will
// forward between threads if needed
connect( this, SIGNAL( startTimeoutTimerSignal()), this, SLOT( startTimeoutTimer()), Qt::QueuedConnection );
// this one needs to be blocking, so that the handling in main thread is processed before
// the thread emitting the signal continues
connect( this, SIGNAL( processYieldSignal( bool, bool )), this, SLOT( processYield( bool, bool )),
Qt::BlockingQueuedConnection );
// Create the File picker in the main / GUI thread and block the calling thread until
// the FilePicker is created.
connect( this, SIGNAL( createFilePickerSignal( const css::uno::Reference< css::uno::XComponentContext >&) ),
this, SLOT( createFilePicker( const css::uno::Reference< css::uno::XComponentContext >&) ),
Qt::BlockingQueuedConnection );
}
KDEXLib::~KDEXLib()
{
// free the faked cmdline arguments no longer needed by KApplication
for( int i = 0; i < m_nFakeCmdLineArgs; i++ )
{
free( m_pFreeCmdLineArgs[i] );
}
}
void KDEXLib::Init()
{
m_pInputMethod = new SalI18N_InputMethod;
m_pInputMethod->SetLocale();
XrmInitialize();
KAboutData *kAboutData = new KAboutData( I18N_NOOP("LibreOffice"),
i18n( "LibreOffice" ),
"5.1.0",
i18n( "LibreOffice with KDE Native Widget Support." ),
KAboutLicense::File,
i18n("Copyright (c) 2000, 2014 LibreOffice contributors" ),
i18n( "LibreOffice is an office suite.\n" ),
"http://libreoffice.org",
QLatin1String("libreoffice@lists.freedesktop.org"));
kAboutData->addAuthor( i18n( "Jan Holesovsky" ),
i18n( "Original author and maintainer of the KDE NWF." ),
"kendy@artax.karlin.mff.cuni.cz",
"http://artax.karlin.mff.cuni.cz/~kendy" );
kAboutData->addAuthor( i18n("Roman Shtylman"),
i18n( "Porting to KDE 4." ),
"shtylman@gmail.com", "http://shtylman.com" );
kAboutData->addAuthor( i18n("Eric Bischoff"),
i18n( "Accessibility fixes, porting to KDE 4." ),
"bischoff@kde.org" );
m_nFakeCmdLineArgs = 2;
sal_uInt32 nParams = osl_getCommandArgCount();
OString aDisplay;
OUString aParam, aBin;
for ( sal_uInt32 nIdx = 0; nIdx < nParams; ++nIdx )
{
osl_getCommandArg( nIdx, &aParam.pData );
if ( !m_pFreeCmdLineArgs && aParam == "-display" && nIdx + 1 < nParams )
{
osl_getCommandArg( nIdx + 1, &aParam.pData );
aDisplay = OUStringToOString( aParam, osl_getThreadTextEncoding() );
m_pFreeCmdLineArgs = o3tl::make_unique<char*[]>(m_nFakeCmdLineArgs + 2);
m_pFreeCmdLineArgs[ m_nFakeCmdLineArgs + 0 ] = strdup( "-display" );
m_pFreeCmdLineArgs[ m_nFakeCmdLineArgs + 1 ] = strdup( aDisplay.getStr() );
m_nFakeCmdLineArgs += 2;
}
}
if ( !m_pFreeCmdLineArgs )
m_pFreeCmdLineArgs = o3tl::make_unique<char*[]>(m_nFakeCmdLineArgs);
osl_getExecutableFile( &aParam.pData );
osl_getSystemPathFromFileURL( aParam.pData, &aBin.pData );
OString aExec = OUStringToOString( aBin, osl_getThreadTextEncoding() );
m_pFreeCmdLineArgs[0] = strdup( aExec.getStr() );
m_pFreeCmdLineArgs[1] = strdup( "--nocrashhandler" );
// make a copy of the string list for freeing it since
// KApplication manipulates the pointers inside the argument vector
// note: KApplication bad !
m_pAppCmdLineArgs = o3tl::make_unique<char*[]>(m_nFakeCmdLineArgs);
for( int i = 0; i < m_nFakeCmdLineArgs; i++ )
m_pAppCmdLineArgs[i] = m_pFreeCmdLineArgs[i];
// LO does its own session management, so prevent KDE/Qt from interfering
// (QApplication::disableSessionManagement(false) wouldn't quite do,
// since that still actually connects to the session manager, it just
// won't save the application data on session shutdown).
char* session_manager = nullptr;
if( getenv( "SESSION_MANAGER" ) != nullptr )
{
session_manager = strdup( getenv( "SESSION_MANAGER" ));
unsetenv( "SESSION_MANAGER" );
}
//m_pApplication.reset( new VCLKDEApplication() );
if( session_manager != nullptr )
{
// coverity[tainted_string] - trusted source for setenv
setenv( "SESSION_MANAGER", session_manager, 1 );
free( session_manager );
}
//KApplication::setQuitOnLastWindowClosed(false);
#if KF5_HAVE_GLIB
m_isGlibEventLoopType = QAbstractEventDispatcher::instance()->inherits( "QEventDispatcherGlib" );
// Using KDE dialogs (and their nested event loops) works only with a proper event loop integration
// that will release SolarMutex when waiting for more events.
// Moreover there are bugs in Qt event loop code that allow QClipboard recursing because the event
// loop processes also events that it should not at that point, so no dialogs in that case either.
// https://bugreports.qt-project.org/browse/QTBUG-37380
// https://bugreports.qt-project.org/browse/QTBUG-34614
if (m_isGlibEventLoopType && (0 == tst_processEventsExcludeSocket()) && tst_excludePostedEvents() == 0 )
m_allowKdeDialogs = true;
#endif
setupEventLoop();
m_pDisplay = QX11Info::display();
}
// When we use Qt event loop, it can actually use its own event loop handling, or wrap
// the Glib event loop (the latter is the default is Qt is built with Glib support
// and $QT_NO_GLIB is not set). We mostly do not care which one it is, as QSocketNotifier's
// and QTimer's can handle it transparently, but it matters for the SolarMutex, which
// needs to be unlocked shortly before entering the main sleep (e.g. select()) and locked
// immediately after. So we need to know which event loop implementation is used and
// hook accordingly.
#if KF5_HAVE_GLIB
#include <glib.h>
static GPollFunc old_gpoll = nullptr;
static gint gpoll_wrapper( GPollFD* ufds, guint nfds, gint timeout )
{
SalYieldMutexReleaser release; // release YieldMutex (and re-acquire at block end)
return old_gpoll( ufds, nfds, timeout );
}
#endif
/*static bool ( *old_qt_event_filter )( void* );
static bool qt_event_filter( void* m )
{
if( old_qt_event_filter != nullptr && old_qt_event_filter( m ))
return true;
if( SalKDEDisplay::self() && SalKDEDisplay::self()->checkDirectInputEvent( static_cast< XEvent* >( m )))
return true;
return false;
}*/
bool KDEXLib::nativeEventFilter(const QByteArray &eventType, void *message, long *)
{
if (eventType == "xcb_generic_event_t") {
xcb_generic_event_t* ev = static_cast<xcb_generic_event_t *>(message);
if( SalKDEDisplay::self() && SalKDEDisplay::self()->checkDirectInputEvent( ev ))
return true;
}
return false;
}
void KDEXLib::setupEventLoop()
{
QAbstractEventDispatcher::instance()->installNativeEventFilter( this );
#if KF5_HAVE_GLIB
if( m_isGlibEventLoopType )
{
old_gpoll = g_main_context_get_poll_func( nullptr );
g_main_context_set_poll_func( nullptr, gpoll_wrapper );
if( m_allowKdeDialogs )
QApplication::clipboard()->setProperty( "useEventLoopWhenWaiting", true );
return;
}
#endif
}
void KDEXLib::Insert( int fd, void* data, YieldFunc pending, YieldFunc queued, YieldFunc handle )
{
if( !m_isGlibEventLoopType )
return SalXLib::Insert( fd, data, pending, queued, handle );
SocketData sdata;
sdata.data = data;
sdata.pending = pending;
sdata.queued = queued;
sdata.handle = handle;
// qApp as parent to make sure it uses the main thread event loop
sdata.notifier = new QSocketNotifier( fd, QSocketNotifier::Read, qApp );
connect( sdata.notifier, SIGNAL( activated( int )), this, SLOT( socketNotifierActivated( int )));
socketData[ fd ] = sdata;
}
void KDEXLib::Remove( int fd )
{
if( !m_isGlibEventLoopType )
return SalXLib::Remove( fd );
SocketData sdata = socketData.take( fd );// according to SalXLib::Remove() this should be safe
delete sdata.notifier;
}
void KDEXLib::socketNotifierActivated( int fd )
{
const SocketData& sdata = socketData[ fd ];
sdata.handle( fd, sdata.data );
}
bool KDEXLib::Yield( bool bWait, bool bHandleAllCurrentEvents )
{
if( !m_isGlibEventLoopType )
{
bool wasEvent = false;
if( qApp->thread() == QThread::currentThread())
{
// even if we use the LO event loop, still process Qt's events,
// otherwise they can remain unhandled for quite a long while
wasEvent = processYield( false, bHandleAllCurrentEvents );
}
return SalXLib::Yield(bWait, bHandleAllCurrentEvents) || wasEvent;
}
// if we are the main thread (which is where the event processing is done),
// good, just do it
if( qApp->thread() == QThread::currentThread())
{
return processYield( bWait, bHandleAllCurrentEvents );
}
else
{
// we were called from another thread;
// release the yield lock to prevent deadlock with the main thread
// (it's ok to release it here, since even normal processYield() would
// temporarily do it while checking for new events)
SalYieldMutexReleaser aReleaser;
Q_EMIT processYieldSignal( bWait, bHandleAllCurrentEvents );
return false;
}
}
/**
* Quoting the Qt docs: [QAbstractEventDispatcher::processEvents] processes
* pending events that match flags until there are no more events to process.
*/
bool KDEXLib::processYield( bool bWait, bool )
{
QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance( qApp->thread());
bool wasEvent = false;
if ( bWait )
wasEvent = dispatcher->processEvents( QEventLoop::WaitForMoreEvents );
else
wasEvent = dispatcher->processEvents( QEventLoop::AllEvents );
return wasEvent;
}
void KDEXLib::StartTimer( sal_uLong nMS )
{
if( !m_isGlibEventLoopType )
return SalXLib::StartTimer( nMS );
timeoutTimer.setInterval( nMS );
// QTimer's can be started only in their thread (main thread here)
if( qApp->thread() == QThread::currentThread())
startTimeoutTimer();
else
Q_EMIT startTimeoutTimerSignal();
}
void KDEXLib::startTimeoutTimer()
{
timeoutTimer.start();
}
void KDEXLib::StopTimer()
{
if( !m_isGlibEventLoopType )
return SalXLib::StopTimer();
timeoutTimer.stop();
}
void KDEXLib::timeoutActivated()
{
// don't potentially wait in timeout, as QTimer is non-recursive
QApplication::postEvent(this, new QEvent(QEvent::Type( m_timerEventId )));
}
void KDEXLib::customEvent(QEvent* e)
{
if( e->type() == m_timerEventId )
X11SalData::Timeout();
else if( e->type() == m_postUserEventId )
SalKDEDisplay::self()->DispatchInternalEvent();
}
void KDEXLib::Wakeup()
{
if( !m_isGlibEventLoopType )
return SalXLib::Wakeup();
QAbstractEventDispatcher::instance( qApp->thread())->wakeUp(); // main thread event loop
}
void KDEXLib::PostUserEvent()
{
if( !m_isGlibEventLoopType )
return SalXLib::PostUserEvent();
QApplication::postEvent(this, new QEvent(QEvent::Type( m_postUserEventId )));
}
void KDEXLib::doStartup()
{
if( ! m_bStartupDone )
{
//KStartupInfo::appStarted();
m_bStartupDone = true;
SAL_INFO( "vcl.kde4", "called KStartupInfo::appStarted()" );
}
}
using namespace com::sun::star;
uno::Reference< ui::dialogs::XFilePicker2 > KDEXLib::createFilePicker(
const uno::Reference< uno::XComponentContext >& xMSF )
{
#if KF5_HAVE_GLIB
if( qApp->thread() != QThread::currentThread()) {
SalYieldMutexReleaser aReleaser;
return Q_EMIT createFilePickerSignal( xMSF );
}
return uno::Reference< ui::dialogs::XFilePicker2 >( new KDE4FilePicker( xMSF ) );
#else
(void)xMSF;
return NULL;
#endif
}
#include "KDE5XLib.moc"
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

102
vcl/unx/kde5/KDE5XLib.hxx Normal file
View File

@@ -0,0 +1,102 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#pragma once
#include <memory>
#include <unx/saldisp.hxx>
//#include <fixx11h.h>
//
#include <QtCore/QObject>
#include <QtCore/QHash>
#include <QtCore/QSocketNotifier>
#include <QtCore/QTimer>
#include <QtCore/QAbstractNativeEventFilter>
#include <unx/salinst.h>
class VCLKDEApplication;
class KDEXLib : public QObject, public QAbstractNativeEventFilter, public SalXLib
{
Q_OBJECT
private:
bool m_bStartupDone;
std::unique_ptr<VCLKDEApplication> m_pApplication;
std::unique_ptr<char*[]> m_pFreeCmdLineArgs;
std::unique_ptr<char*[]> m_pAppCmdLineArgs;
int m_nFakeCmdLineArgs;
struct SocketData
{
void* data;
YieldFunc pending;
YieldFunc queued;
YieldFunc handle;
QSocketNotifier* notifier;
};
QHash< int, SocketData > socketData; // key is fd
QTimer timeoutTimer;
bool m_isGlibEventLoopType;
bool m_allowKdeDialogs;
int m_timerEventId;
int m_postUserEventId;
private:
void setupEventLoop();
private Q_SLOTS:
void socketNotifierActivated( int fd );
void timeoutActivated();
void startTimeoutTimer();
static bool processYield( bool bWait, bool bHandleAllCurrentEvents );
Q_SIGNALS:
void startTimeoutTimerSignal();
void processYieldSignal( bool bWait, bool bHandleAllCurrentEvents );
css::uno::Reference< css::ui::dialogs::XFilePicker2 >
createFilePickerSignal( const css::uno::Reference< css::uno::XComponentContext >& );
public:
KDEXLib();
virtual ~KDEXLib() override;
virtual void Init() override;
virtual bool Yield( bool bWait, bool bHandleAllCurrentEvents ) override;
virtual void Insert( int fd, void* data, YieldFunc pending, YieldFunc queued, YieldFunc handle ) override;
virtual void Remove( int fd ) override;
virtual void StartTimer( sal_uLong nMS ) override;
virtual void StopTimer() override;
virtual void Wakeup() override;
virtual void PostUserEvent() override;
void doStartup();
bool allowKdeDialogs() { return m_allowKdeDialogs; }
virtual void customEvent(QEvent* e) override;
public Q_SLOTS:
css::uno::Reference< css::ui::dialogs::XFilePicker2 >
createFilePicker( const css::uno::Reference< css::uno::XComponentContext >& );
public:
virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *) override;
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@@ -0,0 +1,75 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include "VCLKDE5Application.hxx"
#include <QtGui/QClipboard>
#include <QtCore/QEvent>
#include "KDE5SalDisplay.hxx"
VCLKDEApplication::VCLKDEApplication() :
KApplication()
{
}
// various hacks to be performed before re-entering Qt's event loop
// because of showing a Qt dialog
void VCLKDEApplication::preDialogSetup()
{
// KFileDialog integration requires using event loop with QClipboard.
// Opening the KDE file dialog here can lead to QClipboard
// asking for clipboard contents. If LO core is the owner of the clipboard
// content, without event loop use this will block for 5 seconds and timeout,
// since the clipboard thread will not be able to acquire SolarMutex
// and thus won't be able to respond. If the event loops
// are properly integrated and QClipboard can use a nested event loop
// (see the KDE VCL plug), then this won't happen.
// We cannot simply release SolarMutex here, because the event loop started
// by the file dialog would also call back to LO code.
assert( QApplication::clipboard()->property( "useEventLoopWhenWaiting" ).toBool() );
}
// various hacks to be performed after a Qt dialog has been closed
void VCLKDEApplication::postDialogCleanup()
{
// HACK: KFileDialog uses KConfig("kdeglobals") for saving some settings
// (such as the auto-extension flag), but that doesn't update KGlobal::config()
// (which is probably a KDE bug), so force reading the new configuration,
// otherwise the next opening of the dialog would use the old settings.
KGlobal::config()->reparseConfiguration();
// HACK: If Qt owns clipboard or selection, give up on their ownership now. Otherwise
// LO core might ask for the contents, but it would block while doing so (i.e. it
// doesn't seem to have an equivalent of QClipboard's "useEventLoopWhenWaiting"),
// therefore QClipboard wouldn't be able to respond, and whole LO would block until
// a timeout. Given that Klipper is most probably running, giving up clipboard/selection
// ownership will not only avoid the blocking, but even pasting that content in LO
// will in fact work, if Klipper can handle it.
// Technically proper solution would be of course to allow Qt to process QClipboard
// events while LO waits for clipboard contents, or short-circuit to QClipboard somehow
// (it's a mystery why LO's clipboard handling has its own thread when whole LO can
// get blocked by both trying to send and receive clipboard contents anyway).
QClipboard* clipboard = QApplication::clipboard();
if( clipboard->ownsSelection())
clipboard->clear( QClipboard::Selection );
if( clipboard->ownsClipboard())
clipboard->clear();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@@ -0,0 +1,40 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#ifndef _VCLKDE5APPLICATION_HXX_
#define _VCLKDE5APPLICATION_HXX_
#pragma once
#include <QtWidgets/QApplication>
#include <QtCore/QAbstractNativeEventFilter>
#undef Region
class VCLKDEApplication : public QApplication, public QAbstractNativeEventFilter
{
public:
VCLKDEApplication();
static void preDialogSetup();
static void postDialogCleanup();
};
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

88
vcl/unx/kde5/main.cxx Normal file
View File

@@ -0,0 +1,88 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <QtGui/QApplication>
#include "KDE5Data.hxx"
#include "KDE5SalInstance.hxx"
#include <vclpluginapi.h>
#include <rtl/string.hxx>
/// entry point for the KDE4 VCL plugin
extern "C" {
VCLPLUG_KDE4_PUBLIC SalInstance* create_SalInstance()
{
/* #i92121# workaround deadlocks in the X11 implementation
*/
static const char* pNoXInitThreads = getenv( "SAL_NO_XINITTHREADS" );
/* #i90094#
from now on we know that an X connection will be
established, so protect X against itself
*/
if( ! ( pNoXInitThreads && *pNoXInitThreads ) )
{
#if QT_VERSION >= 0x040800
// let Qt call XInitThreads(), so that also Qt knows it's been used
// (otherwise QPixmap may warn about threads not being initialized)
QApplication::setAttribute( Qt::AA_X11InitThreads );
#else
XInitThreads();
// just in case somebody builds with old version and then upgrades Qt,
// otherwise this is a no-op
QApplication::setAttribute( static_cast< Qt::ApplicationAttribute >( 10 ));
#endif
}
#if QT_VERSION < 0x050000
// Qt 4.x support needs >= 4.1.0
OString aVersion( qVersion() );
SAL_INFO( "vcl.kde4", "qt version string is " << aVersion );
sal_Int32 nIndex = 0, nMajor = 0, nMinor = 0;
nMajor = aVersion.getToken( 0, '.', nIndex ).toInt32();
if( nIndex > 0 )
nMinor = aVersion.getToken( 0, '.', nIndex ).toInt32();
if( nMajor != 4 || nMinor < 1 )
{
#if OSL_DEBUG_LEVEL > 1
sal_Int32 nMicro = 0;
if( nIndex > 0 )
nMicro = aVersion.getToken( 0, '.', nIndex ).toInt32();
SAL_INFO( "vcl.kde4", "unsuitable qt version " << nMajor << "." << nMinor << "." << nMicro );
#endif
return nullptr;
}
#endif
KDESalInstance* pInstance = new KDESalInstance( new SalYieldMutex() );
SAL_INFO( "vcl.kde4", "created KDESalInstance " << &pInstance );
// initialize SalData
KDEData *salData = new KDEData( pInstance );
salData->Init();
salData->initNWF();
pInstance->SetLib(salData->GetLib());
return pInstance;
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@@ -0,0 +1,67 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*
* This code is based on the SocketEventsTester from the Qt4 test suite.
*/
#pragma once
#include <QtCore/QCoreApplication>
#include <QtCore/QEventLoop>
const QEvent::Type eventType = QEvent::User;
class TestExcludePostedEvents
: public QObject
{
Q_OBJECT
public:
TestExcludePostedEvents();
virtual bool event( QEvent* e ) override;
bool processed;
};
TestExcludePostedEvents::TestExcludePostedEvents()
: processed( false )
{
}
bool TestExcludePostedEvents::event( QEvent* e )
{
if( e->type() == eventType )
processed = true;
return QObject::event( e );
}
#define QVERIFY(a) \
if (!a) return 1;
static int tst_excludePostedEvents()
{
TestExcludePostedEvents test;
QCoreApplication::postEvent( &test, new QEvent( eventType ));
QEventLoop loop;
loop.processEvents(QEventLoop::ExcludeUserInputEvents
| QEventLoop::ExcludeSocketNotifiers
// | QEventLoop::WaitForMoreEvents
| QEventLoop::X11ExcludeTimers);
QVERIFY( !test.processed );
loop.processEvents();
QVERIFY( test.processed );
return 0;
}

View File

@@ -0,0 +1,80 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*
* This code is based on the SocketEventsTester from the Qt4 test suite.
*/
#pragma once
#include <QtCore/QCoreApplication>
#include <QtCore/QEventLoop>
#include <QtCore/QSocketNotifier>
#include <unistd.h>
class TestExcludeSocketNotifiers
: public QObject
{
Q_OBJECT
public:
TestExcludeSocketNotifiers( const int* pipes );
virtual ~TestExcludeSocketNotifiers() override;
bool received;
public slots:
void slotReceived();
private:
const int* pipes;
};
TestExcludeSocketNotifiers::TestExcludeSocketNotifiers( const int* thePipes )
: received( false )
, pipes( thePipes )
{
}
TestExcludeSocketNotifiers::~TestExcludeSocketNotifiers()
{
close( pipes[ 0 ] );
close( pipes[ 1 ] );
}
void TestExcludeSocketNotifiers::slotReceived()
{
received = true;
}
#define QVERIFY(a) \
if (!a) return 1;
static int tst_processEventsExcludeSocket()
{
int pipes[ 2 ];
if( pipe( pipes ) < 0 )
return 1;
TestExcludeSocketNotifiers test( pipes );
QSocketNotifier notifier( pipes[ 0 ], QSocketNotifier::Read );
QObject::connect( &notifier, SIGNAL( activated( int )), &test, SLOT( slotReceived()));
char dummy = 'a';
if( 1 != write( pipes[ 1 ], &dummy, 1 ) )
return 1;
QEventLoop loop;
loop.processEvents( QEventLoop::ExcludeSocketNotifiers );
QVERIFY( !test.received );
loop.processEvents();
QVERIFY( test.received );
return 0;
}