kde5: copy basic kde4 blocks -> kde5 and build againt qt5/kf5 libs
Change-Id: I70f0c4147721a20459e1183ff40cf0ac8adf49e6
This commit is contained in:
committed by
Thorsten Behrens
parent
07cd70c86c
commit
dd7a3147f1
23
vcl/CustomTarget_kde5_moc.mk
Normal file
23
vcl/CustomTarget_kde5_moc.mk
Normal 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:
|
96
vcl/Library_vclplug_kde5.mk
Normal file
96
vcl/Library_vclplug_kde5.mk
Normal 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:
|
@@ -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)
|
||||
|
28
vcl/unx/kde5/FPServiceInfo.hxx
Normal file
28
vcl/unx/kde5/FPServiceInfo.hxx
Normal 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
68
vcl/unx/kde5/KDE5Data.cxx
Normal 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
37
vcl/unx/kde5/KDE5Data.hxx
Normal 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: */
|
98
vcl/unx/kde5/KDE5SalDisplay.cxx
Normal file
98
vcl/unx/kde5/KDE5SalDisplay.cxx
Normal 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: */
|
47
vcl/unx/kde5/KDE5SalDisplay.hxx
Normal file
47
vcl/unx/kde5/KDE5SalDisplay.hxx
Normal 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: */
|
381
vcl/unx/kde5/KDE5SalFrame.cxx
Normal file
381
vcl/unx/kde5/KDE5SalFrame.cxx
Normal 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: */
|
53
vcl/unx/kde5/KDE5SalFrame.hxx
Normal file
53
vcl/unx/kde5/KDE5SalFrame.hxx
Normal 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: */
|
1020
vcl/unx/kde5/KDE5SalGraphics.cxx
Normal file
1020
vcl/unx/kde5/KDE5SalGraphics.cxx
Normal file
File diff suppressed because it is too large
Load Diff
53
vcl/unx/kde5/KDE5SalGraphics.hxx
Normal file
53
vcl/unx/kde5/KDE5SalGraphics.hxx
Normal 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: */
|
70
vcl/unx/kde5/KDE5SalInstance.cxx
Normal file
70
vcl/unx/kde5/KDE5SalInstance.cxx
Normal 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: */
|
45
vcl/unx/kde5/KDE5SalInstance.hxx
Normal file
45
vcl/unx/kde5/KDE5SalInstance.hxx
Normal 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
407
vcl/unx/kde5/KDE5XLib.cxx
Normal 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
102
vcl/unx/kde5/KDE5XLib.hxx
Normal 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: */
|
75
vcl/unx/kde5/VCLKDE5Application.cxx
Normal file
75
vcl/unx/kde5/VCLKDE5Application.cxx
Normal 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: */
|
40
vcl/unx/kde5/VCLKDE5Application.hxx
Normal file
40
vcl/unx/kde5/VCLKDE5Application.hxx
Normal 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
88
vcl/unx/kde5/main.cxx
Normal 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: */
|
67
vcl/unx/kde5/tst_exclude_posted_events.hxx
Normal file
67
vcl/unx/kde5/tst_exclude_posted_events.hxx
Normal 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;
|
||||
}
|
80
vcl/unx/kde5/tst_exclude_socket_notifiers.hxx
Normal file
80
vcl/unx/kde5/tst_exclude_socket_notifiers.hxx
Normal 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( ¬ifier, 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;
|
||||
}
|
Reference in New Issue
Block a user