Skip to content

Commit f6bd7b3

Browse files
dakcartonyalldawson
authored andcommittedMay 14, 2017
Add OS native interface lib, with objective-c++ interface to Mac Cocoa libraries
1 parent f8f7d60 commit f6bd7b3

17 files changed

+559
-11
lines changed
 

‎CMakeLists.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -494,8 +494,6 @@ ELSE (WIN32)
494494
ELSE ()
495495
SET (OSX_HAVE_LOADERPATH 0)
496496
ENDIF ()
497-
#this will define ${APP_SERVICES_LIBRARY}
498-
FIND_LIBRARY(APP_SERVICES_LIBRARY ApplicationServices )
499497

500498
SET (DEFAULT_BIN_SUBDIR bin)
501499
SET (QGIS_BIN_SUBDIR_REV ..)
@@ -750,6 +748,11 @@ ADD_CUSTOM_TARGET(version ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/qgsversion.h)
750748
#TEST_DATA_DIR is also used by QgsRenderChecker currently in core
751749
SET (TEST_DATA_DIR "${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata")
752750

751+
SET(USE_NATIVE_LIB FALSE)
752+
IF(APPLE)
753+
SET(USE_NATIVE_LIB TRUE)
754+
ENDIF(APPLE)
755+
753756
ADD_SUBDIRECTORY(src)
754757
ADD_SUBDIRECTORY(doc)
755758
ADD_SUBDIRECTORY(images)

‎src/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
IF(USE_NATIVE_LIB)
2+
ADD_SUBDIRECTORY(native)
3+
ENDIF(USE_NATIVE_LIB)
4+
15
ADD_SUBDIRECTORY(core)
26
ADD_SUBDIRECTORY(analysis)
37
ADD_SUBDIRECTORY(ui)

‎src/app/CMakeLists.txt

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -529,12 +529,18 @@ INCLUDE_DIRECTORIES(SYSTEM
529529
${QWTPOLAR_INCLUDE_DIR}
530530
${QCA_INCLUDE_DIR}
531531
${QTKEYCHAIN_INCLUDE_DIR}
532-
)
532+
)
533533

534534
IF(ENABLE_MODELTEST)
535535
INCLUDE_DIRECTORIES(../../tests/qt_modeltest)
536536
ENDIF(ENABLE_MODELTEST)
537537

538+
IF (USE_NATIVE_LIB)
539+
IF(APPLE)
540+
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/native/mac)
541+
ENDIF(APPLE)
542+
ENDIF(USE_NATIVE_LIB)
543+
538544
IF (ANDROID)
539545
INCLUDE_DIRECTORIES(SYSTEM ${ANDROID_NDK_TOOLCHAIN_ROOT}/sysroot/usr/include)
540546
ENDIF (ANDROID)
@@ -586,6 +592,10 @@ IF (APPLE)
586592
TARGET_LINK_LIBRARIES(qgis_app ${APP_SERVICES_LIBRARY})
587593
ENDIF(APPLE)
588594

595+
IF(USE_NATIVE_LIB)
596+
TARGET_LINK_LIBRARIES(qgis_app qgis_native)
597+
ENDIF(USE_NATIVE_LIB)
598+
589599
if(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8)
590600
SET_TARGET_PROPERTIES(qgis_app PROPERTIES STATIC_LIBRARY_FLAGS "/machine:x64")
591601
ENDIF(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8)
@@ -605,9 +615,11 @@ IF(WIN32)
605615
TARGET_LINK_LIBRARIES(qgis_app DbgHelp Qt5::WinExtras)
606616
ENDIF(WIN32)
607617

608-
IF (APPLE)
609-
TARGET_LINK_LIBRARIES(${QGIS_APP_NAME} ${APP_SERVICES_LIBRARY})
618+
IF(USE_NATIVE_LIB)
619+
TARGET_LINK_LIBRARIES(${QGIS_APP_NAME} qgis_native)
620+
ENDIF(USE_NATIVE_LIB)
610621

622+
IF (APPLE)
611623
SET_TARGET_PROPERTIES(${QGIS_APP_NAME} PROPERTIES
612624
INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/${QGIS_LIB_DIR}
613625
INSTALL_RPATH_USE_LINK_PATH true

‎src/app/qgisapp.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ Q_GUI_EXPORT extern int qt_defaultDpiX();
101101
#ifdef Q_OS_MACX
102102
#include <ApplicationServices/ApplicationServices.h>
103103

104+
// Virtual interfaces to Cocoa objective-c frameworks/classes/calls
105+
// cocoainitializer is to handle objective-c garbage collection
106+
// see: http://el-tramo.be/blog/mixing-cocoa-and-qt/
107+
//#include "cocoainitializer.h"
108+
#include "qgsmacappkit.h"
109+
104110
// check macro breaks QItemDelegate
105111
#ifdef check
106112
#undef check
@@ -6120,9 +6126,10 @@ void QgisApp::bringAllToFront()
61206126
{
61216127
#ifdef Q_OS_MAC
61226128
// Bring forward all open windows while maintaining layering order
6123-
ProcessSerialNumber psn;
6124-
GetCurrentProcess( &psn );
6125-
SetFrontProcess( &psn );
6129+
// method valid for Mac OS X >= 10.6
6130+
QgsNSRunningApplication* nsrapp = new QgsNSRunningApplication();
6131+
nsrapp->currentAppActivateIgnoringOtherApps();
6132+
delete nsrapp;
61266133
#endif
61276134
}
61286135

‎src/core/CMakeLists.txt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,12 @@ INCLUDE_DIRECTORIES(SYSTEM
10441044
${QTKEYCHAIN_INCLUDE_DIR}
10451045
)
10461046

1047+
IF(USE_NATIVE_LIB)
1048+
IF(APPLE)
1049+
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/native/mac)
1050+
ENDIF(APPLE)
1051+
ENDIF(USE_NATIVE_LIB)
1052+
10471053
#for PAL classes
10481054
IF (WIN32)
10491055
ADD_DEFINITIONS("-D_HAVE_WINDOWS_H_")
@@ -1112,9 +1118,9 @@ IF (WIN32)
11121118
TARGET_LINK_LIBRARIES(qgis_core wsock32 ${SETUPAPI_LIBRARY} DbgHelp)
11131119
ENDIF (WIN32)
11141120

1115-
IF(APPLE)
1116-
TARGET_LINK_LIBRARIES(qgis_core "-framework CoreFoundation -framework IOKit")
1117-
ENDIF(APPLE)
1121+
IF(USE_NATIVE_LIB)
1122+
TARGET_LINK_LIBRARIES(qgis_core qgis_native)
1123+
ENDIF(USE_NATIVE_LIB)
11181124

11191125
IF (NOT WITH_INTERNAL_QEXTSERIALPORT)
11201126
TARGET_LINK_LIBRARIES(qgis_core ${QEXTSERIALPORT_LIBRARY})

‎src/native/CMakeLists.txt

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#############################################################
2+
# locate native libs
3+
4+
SET(NATIVE_LINK_LIBS)
5+
6+
IF(APPLE)
7+
SET(APPLE_LIB_LIST ApplicationServices CoreFoundation IOKit AppKit)
8+
FOREACH(_lib ${APPLE_LIB_LIST})
9+
STRING(TOUPPER ${_lib} _lib_var)
10+
# prefer /System/Library/Frameworks, in case CMAKE_FIND_FRAMEWORK=LAST, etc.
11+
FIND_LIBRARY(APPLE_${_lib_var}_LIBRARY
12+
NAMES ${_lib}
13+
PATHS /System/Library/Frameworks
14+
NO_DEFAULT_PATH
15+
)
16+
# if not found, drop back to standard find paths
17+
FIND_LIBRARY(APPLE_${_lib_var}_LIBRARY ${_lib})
18+
19+
IF(NOT APPLE_${_lib_var}_LIBRARY)
20+
MESSAGE(FATAL_ERROR "Couldn't find Apple's '${_lib}' framework or library")
21+
ENDIF(NOT APPLE_${_lib_var}_LIBRARY)
22+
23+
LIST(APPEND NATIVE_LINK_LIBS "-framework ${_lib}")
24+
ENDFOREACH(_lib ${APPLE_LIB_LIST})
25+
ENDIF(APPLE)
26+
27+
#############################################################
28+
# sources
29+
30+
SET(QGIS_CORE_SRCS)
31+
32+
IF(APPLE)
33+
SET(QGIS_APP_OBJC_SRCS
34+
mac/cocoainitializer.mm
35+
mac/qgsmacappkit.mm
36+
)
37+
38+
SET_SOURCE_FILES_PROPERTIES(${QGIS_APP_OBJC_SRCS} PROPERTIES COMPILE_FLAGS "-x objective-c++")
39+
40+
SET(QGIS_CORE_SRCS ${QGIS_CORE_SRCS}
41+
${QGIS_APP_OBJC_SRCS}
42+
mac/qgsmacnative.cpp
43+
)
44+
ENDIF(APPLE)
45+
46+
SET(QGIS_CORE_MOC_HDRS)
47+
48+
QT4_WRAP_CPP(QGIS_CORE_MOC_SRCS ${QGIS_CORE_MOC_HDRS})
49+
50+
# install headers
51+
52+
IF(APPLE)
53+
SET (QGIS_CORE_HDRS ${QGIS_CORE_HDRS}
54+
mac/qgsmacnative.h
55+
mac/cocoainitializer.h
56+
mac/qgsmacappkit.h
57+
)
58+
ENDIF(APPLE)
59+
60+
INCLUDE_DIRECTORIES(
61+
${CMAKE_CURRENT_SOURCE_DIR}
62+
)
63+
64+
IF(APPLE)
65+
INCLUDE_DIRECTORIES(mac)
66+
ENDIF(APPLE)
67+
68+
# Test data dir for QgsRenderChecker
69+
ADD_DEFINITIONS(-DTEST_DATA_DIR="\\"${TEST_DATA_DIR}\\"")
70+
71+
#############################################################
72+
# qgis_native library
73+
74+
ADD_LIBRARY(qgis_native SHARED ${QGIS_CORE_SRCS} ${QGIS_CORE_MOC_SRCS} ${QGIS_CORE_HDRS} ${QGIS_CORE_MOC_HDRS})
75+
76+
IF(NOT APPLE)
77+
INSTALL(FILES ${QGIS_CORE_HDRS} ${QGIS_CORE_MOC_HDRS} DESTINATION ${QGIS_INCLUDE_DIR})
78+
ELSE(NOT APPLE)
79+
SET_TARGET_PROPERTIES(qgis_native PROPERTIES
80+
CLEAN_DIRECT_OUTPUT 1
81+
FRAMEWORK 1
82+
FRAMEWORK_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}"
83+
MACOSX_FRAMEWORK_INFO_PLIST "${CMAKE_SOURCE_DIR}/mac/framework.info.plist.in"
84+
MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${COMPLETE_VERSION}
85+
MACOSX_FRAMEWORK_IDENTIFIER org.qgis.qgis2_native
86+
BUILD_WITH_INSTALL_RPATH TRUE
87+
PUBLIC_HEADER "${QGIS_CORE_HDRS};${QGIS_CORE_MOC_HDRS}"
88+
LINK_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}"
89+
)
90+
ENDIF(NOT APPLE)
91+
92+
#generate unversioned libs for android
93+
IF(NOT ANDROID)
94+
SET_TARGET_PROPERTIES(qgis_native PROPERTIES
95+
VERSION ${COMPLETE_VERSION}
96+
SOVERSION ${COMPLETE_VERSION}
97+
)
98+
ENDIF(NOT ANDROID)
99+
100+
TARGET_LINK_LIBRARIES(qgis_native "${NATIVE_LINK_LIBS}")
101+
102+
# install
103+
104+
INSTALL(TARGETS qgis_native
105+
RUNTIME DESTINATION ${QGIS_BIN_DIR}
106+
LIBRARY DESTINATION ${QGIS_LIB_DIR}
107+
ARCHIVE DESTINATION ${QGIS_LIB_DIR}
108+
FRAMEWORK DESTINATION ${QGIS_FW_SUBDIR}
109+
PUBLIC_HEADER DESTINATION ${QGIS_INCLUDE_DIR})
110+
111+
# Mac dev frameworks
112+
113+
IF (APPLE AND QGIS_MACAPP_INSTALL_DEV)
114+
INSTALL(TARGETS qgis_native FRAMEWORK DESTINATION ${QGIS_MACAPP_DEV_PREFIX})
115+
INSTALL(CODE "EXECUTE_PROCESS(COMMAND install_name_tool -id \"${QGIS_MACAPP_DEV_PREFIX}/qgis_native.framework/Versions/${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}/qgis_native\" \"$ENV{DESTDIR}${QGIS_MACAPP_DEV_PREFIX}/qgis_native.framework/qgis_native\")")
116+
ENDIF (APPLE AND QGIS_MACAPP_INSTALL_DEV)

‎src/native/README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
README for qgis_native lib
2+
==========================
3+
4+
This library is intended to offer abstraction to the host OS's underlying public
5+
interfaces. This is useful for OSes that provide interfaces in languages other
6+
than C/C++, or for grouping calls to OS-specific code so that it only needs to
7+
be updated in one place in the source tree. It is advisable to leverage existing
8+
functions provided by Qt, rather than rely upon OS-specific code, unless such
9+
code extends the application to provide a better OS-specific user experience or
10+
solve a problem.
11+
12+
Example
13+
-------
14+
15+
As of Mac OS X 10.9 (Mavericks) many system public API calls to Carbon libraries
16+
(based upon C) have been deprecated in favor of modern Cocoa libraries (written
17+
in Objective-C), which can no longer be directly called from C++. Coalescing
18+
and mixing these new calls in a library, using Objective-C++ allows not only
19+
access to the Apple system Objective-C libraries and frameworks, but also those
20+
from third-parties, like the auto-updating Sparkle.framework.
21+
22+
See also: http://el-tramo.be/blog/mixing-cocoa-and-qt/
23+
http://sparkle.andymatuschak.org/

‎src/native/mac/cocoainitializer.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/***************************************************************************
2+
cocoaInitializer.h - used to enable Cocoa’s memory management
3+
-------------------
4+
copyright : (C) 2008 by Remko Troncon
5+
email : remco at el-tramo dot be
6+
url : http://el-tramo.be/blog/mixing-cocoa-and-qt/
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
Redistribution and use in source and binary forms, with or without
11+
modification, are permitted provided that the following conditions are
12+
met:
13+
14+
(1) Redistributions of source code must retain the above copyright
15+
notice, this list of conditions and the following disclaimer.
16+
17+
(2) Redistributions in binary form must reproduce the above copyright
18+
notice, this list of conditions and the following disclaimer in
19+
the documentation and/or other materials provided with the
20+
distribution.
21+
22+
(3)The name of the author may not be used to
23+
endorse or promote products derived from this software without
24+
specific prior written permission.
25+
26+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27+
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29+
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
30+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34+
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
35+
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36+
POSSIBILITY OF SUCH DAMAGE.
37+
***************************************************************************/
38+
39+
#ifndef COCOAINITIALIZER_H
40+
#define COCOAINITIALIZER_H
41+
42+
43+
class CocoaInitializer
44+
{
45+
public:
46+
CocoaInitializer();
47+
~CocoaInitializer();
48+
49+
private:
50+
class Private;
51+
Private* d;
52+
};
53+
54+
#endif // COCOAINITIALIZER_H

‎src/native/mac/cocoainitializer.mm

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/***************************************************************************
2+
cocoaInitializer.mm - used to enable Cocoa’s memory management
3+
-------------------
4+
copyright : (C) 2008 by Remko Troncon
5+
email : remco at el-tramo dot be
6+
url : http://el-tramo.be/blog/mixing-cocoa-and-qt/
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
Redistribution and use in source and binary forms, with or without
11+
modification, are permitted provided that the following conditions are
12+
met:
13+
14+
(1) Redistributions of source code must retain the above copyright
15+
notice, this list of conditions and the following disclaimer.
16+
17+
(2) Redistributions in binary form must reproduce the above copyright
18+
notice, this list of conditions and the following disclaimer in
19+
the documentation and/or other materials provided with the
20+
distribution.
21+
22+
(3)The name of the author may not be used to
23+
endorse or promote products derived from this software without
24+
specific prior written permission.
25+
26+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27+
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29+
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
30+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34+
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
35+
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36+
POSSIBILITY OF SUCH DAMAGE.
37+
***************************************************************************/
38+
39+
#include "CocoaInitializer.h"
40+
41+
#include <AppKit/AppKit.h>
42+
#include <Cocoa/Cocoa.h>
43+
44+
class CocoaInitializer::Private
45+
{
46+
public:
47+
NSAutoreleasePool* autoReleasePool_;
48+
};
49+
50+
CocoaInitializer::CocoaInitializer()
51+
{
52+
d = new CocoaInitializer::Private();
53+
NSApplicationLoad();
54+
d->autoReleasePool_ = [[NSAutoreleasePool alloc] init];
55+
}
56+
57+
CocoaInitializer::~CocoaInitializer()
58+
{
59+
[d->autoReleasePool_ release];
60+
delete d;
61+
}

0 commit comments

Comments
 (0)
Please sign in to comment.