From a57bec2e714bb124f841e4c14df4036d903ec572 Mon Sep 17 00:00:00 2001
From: Scott Talbert
Date: Thu, 25 Feb 2016 20:53:33 -0500
Subject: [PATCH] Add support for building with GTK3
---
TODO.txt | 2 --
build.py | 3 +++
buildtools/config.py | 10 ++++++++--
demo/AUI_DockingWindowMgr.py | 2 +-
demo/About.py | 2 +-
demo/HtmlWindow.py | 2 +-
demo/Main.py | 2 +-
demo/SystemSettings.py | 3 ++-
etg/_core.py | 2 ++
etg/window.py | 2 +-
src/app_ex.cpp | 1 -
src/core_ex.cpp | 4 +++-
src/window_ex.cpp | 7 ++++++-
wscript | 7 ++++++-
wx/lib/mixins/listctrl.py | 2 +-
wx/lib/wxcairo.py | 21 ++++++++++++++++-----
wx/py/editwindow.py | 3 ++-
17 files changed, 54 insertions(+), 21 deletions(-)
diff --git a/TODO.txt b/TODO.txt
index af696826..effcce46 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -171,8 +171,6 @@ other dev stuff
* Check gui_scripts entry points.
- * Add build support for gtk3
-
* wx.Window.DoEraseBackground?
* The sphinxtools are too agressive at ignoring content beyond a #. If the hash
diff --git a/build.py b/build.py
index d084d522..468ef6cc 100755
--- a/build.py
+++ b/build.py
@@ -369,6 +369,7 @@ def makeOptionParser():
("python", ("", "The python executable to build for.")),
("debug", (False, "Build wxPython with debug symbols")),
("keep_hash_lines",(False, "Don't remove the '#line N' lines from the SIP generated code")),
+ ("gtk3", (False, "On Linux build for gtk3 (default gtk2)")),
("osx_cocoa", (True, "Build the OSX Cocoa port on Mac (default)")),
("osx_carbon", (False, "Build the OSX Carbon port on Mac (unsupported)")),
("mac_framework", (False, "Build wxWidgets as a Mac framework.")),
@@ -1272,6 +1273,8 @@ def cmd_build_py(options, args):
build_options.append('--jobs=%s' % options.jobs)
if options.relwithdebug:
build_options.append('--msvc_relwithdebug')
+ if options.gtk3:
+ build_options.append('--gtk3')
build_options.append('--python="%s"' % PYTHON)
build_options.append('--out=%s' % wafBuildDir) # this needs to be the last option
diff --git a/buildtools/config.py b/buildtools/config.py
index 1232afe5..c403bc7f 100644
--- a/buildtools/config.py
+++ b/buildtools/config.py
@@ -56,8 +56,8 @@ class Configuration(object):
WXPORT = 'gtk2'
# On Linux/Unix there are several ports of wxWidgets available.
# Setting this value lets you select which will be used for the
- # wxPython build. Possibilites are 'gtk', 'gtk2' and 'x11'.
- # Currently only gtk and gtk2 works.
+ # wxPython build. Possibilities are 'gtk', 'gtk2', 'gtk3' and 'x11'.
+ # Currently only gtk, gtk2 and gtk3 work.
BUILD_BASE = "build"
# Directory to use for temporary build files.
@@ -280,6 +280,9 @@ class Configuration(object):
elif self.WXPORT == 'gtk2':
self.WXPLAT = '__WXGTK__'
portcfg = os.popen('pkg-config gtk+-2.0 --cflags', 'r').read()[:-1]
+ elif self.WXPORT == 'gtk3':
+ self.WXPLAT = '__WXGTK__'
+ portcfg = os.popen('pkg-config gtk+-3.0 --cflags', 'r').read()[:-1]
elif self.WXPORT == 'x11':
msg("WARNING: The wxX11 port is no supported")
self.WXPLAT = '__WXX11__'
@@ -349,6 +352,9 @@ class Configuration(object):
def parseCmdLine(self):
self.debug = '--debug' in sys.argv or '-g' in sys.argv
+ if '--gtk3' in sys.argv:
+ self.WXPORT = 'gtk3'
+
# the values of the items in the class namespace that start
# with an upper case letter can be overridden on the command
# line
diff --git a/demo/AUI_DockingWindowMgr.py b/demo/AUI_DockingWindowMgr.py
index 1d6d8ff2..8bd842e9 100644
--- a/demo/AUI_DockingWindowMgr.py
+++ b/demo/AUI_DockingWindowMgr.py
@@ -722,7 +722,7 @@ class PyAUIFrame(wx.Frame):
def CreateHTMLCtrl(self):
ctrl = wx.html.HtmlWindow(self, -1, wx.DefaultPosition, wx.Size(400, 300))
- if "gtk2" in wx.PlatformInfo:
+ if "gtk2" in wx.PlatformInfo or "gtk3" in wx.PlatformInfo:
ctrl.SetStandardFonts()
ctrl.SetPage(self.GetIntroText())
return ctrl
diff --git a/demo/About.py b/demo/About.py
index 5f6ee1dc..9315d068 100644
--- a/demo/About.py
+++ b/demo/About.py
@@ -49,7 +49,7 @@ demo item so you can learn how to use the classes yourself.
def __init__(self, parent):
wx.Dialog.__init__(self, parent, -1, 'About the wxPython demo',)
html = wx.html.HtmlWindow(self, -1, size=(420, -1))
- if "gtk2" in wx.PlatformInfo:
+ if "gtk2" in wx.PlatformInfo or "gtk3" in wx.PlatformInfo:
html.SetStandardFonts()
py_version = sys.version.split()[0]
txt = self.text % (wx.VERSION_STRING,
diff --git a/demo/HtmlWindow.py b/demo/HtmlWindow.py
index 676db2d6..7582fba7 100644
--- a/demo/HtmlWindow.py
+++ b/demo/HtmlWindow.py
@@ -17,7 +17,7 @@ class MyHtmlWindow(html.HtmlWindow):
def __init__(self, parent, id, log):
html.HtmlWindow.__init__(self, parent, id, style=wx.NO_FULL_REPAINT_ON_RESIZE)
self.log = log
- if "gtk2" in wx.PlatformInfo:
+ if "gtk2" in wx.PlatformInfo or "gtk3" in wx.PlatformInfo:
self.SetStandardFonts()
def OnLinkClicked(self, linkinfo):
diff --git a/demo/Main.py b/demo/Main.py
index 87627817..6cc3a53d 100644
--- a/demo/Main.py
+++ b/demo/Main.py
@@ -1795,7 +1795,7 @@ class wxPythonDemo(wx.Frame):
panel.Bind(wx.EVT_SIZE, OnOvrSize)
panel.Bind(wx.EVT_ERASE_BACKGROUND, EmptyHandler)
- if "gtk2" in wx.PlatformInfo:
+ if "gtk2" in wx.PlatformInfo or "gtk3" in wx.PlatformInfo:
self.ovr.SetStandardFonts()
self.SetOverview(self.overviewText, mainOverview)
diff --git a/demo/SystemSettings.py b/demo/SystemSettings.py
index 715f3e33..0625005c 100644
--- a/demo/SystemSettings.py
+++ b/demo/SystemSettings.py
@@ -124,7 +124,8 @@ class SysColorPanel(SysPanelBase):
self._box = (50, 15) # Color box dimensions
self._maxw = 0
self._vals = [ color for color in dir(wx)
- if color.startswith('SYS_COLOUR_') ]
+ if color.startswith('SYS_COLOUR_') and
+ color != 'SYS_COLOUR_MAX' ]
def OnPaint(self, evt):
dc = wx.AutoBufferedPaintDCFactory(self)
diff --git a/etg/_core.py b/etg/_core.py
index ae102994..14385949 100644
--- a/etg/_core.py
+++ b/etg/_core.py
@@ -264,6 +264,8 @@ def run():
port = 'gtk'
if 'gtk2' in wx.PlatformInfo:
port = 'gtk2'
+ elif 'gtk3' in wx.PlatformInfo:
+ port = 'gtk3'
else:
port = '???'
return "%s %s (phoenix)" % (wx.VERSION_STRING, port)
diff --git a/etg/window.py b/etg/window.py
index b6021d77..614af23e 100644
--- a/etg/window.py
+++ b/etg/window.py
@@ -162,7 +162,7 @@ def run():
c.find('SetDoubleBuffered').setCppCode("""\
- #if defined(__WXGTK20__) || defined(__WXMSW__)
+ #if defined(__WXGTK20__) || defined(__WXGTK3__) || defined(__WXMSW__)
self->SetDoubleBuffered(on);
#endif
""")
diff --git a/src/app_ex.cpp b/src/app_ex.cpp
index e4183262..3df7545d 100644
--- a/src/app_ex.cpp
+++ b/src/app_ex.cpp
@@ -2,7 +2,6 @@
#ifdef __WXGTK__
#include
#include
-#include
#endif
#ifdef __WXMAC__
diff --git a/src/core_ex.cpp b/src/core_ex.cpp
index 6ddb0aa3..feed75fb 100644
--- a/src/core_ex.cpp
+++ b/src/core_ex.cpp
@@ -168,7 +168,9 @@ void wxPyCoreModuleInject(PyObject* moduleDict)
_AddInfoString("wxOSX-cocoa");
#endif
#ifdef __WXGTK__
-#ifdef __WXGTK20__
+#ifdef __WXGTK3__
+ _AddInfoString("gtk3");
+#elif __WXGTK20__
_AddInfoString("gtk2");
#else
_AddInfoString("gtk1");
diff --git a/src/window_ex.cpp b/src/window_ex.cpp
index 30378888..e4159328 100644
--- a/src/window_ex.cpp
+++ b/src/window_ex.cpp
@@ -6,11 +6,16 @@
#ifdef __WXGTK__
#include
#include
-#include
+#ifdef __WXGTK3__
+#define GetXWindow(wxwin) (wxwin)->m_wxwindow ? \
+ GDK_WINDOW_XID(gtk_widget_get_window((wxwin)->m_wxwindow)) : \
+ GDK_WINDOW_XID(gtk_widget_get_window((wxwin)->m_widget))
+#else
#define GetXWindow(wxwin) (wxwin)->m_wxwindow ? \
GDK_WINDOW_XWINDOW((wxwin)->m_wxwindow->window) : \
GDK_WINDOW_XWINDOW((wxwin)->m_widget->window)
#endif
+#endif
diff --git a/wscript b/wscript
index 83aba8a4..2aeba2fa 100644
--- a/wscript
+++ b/wscript
@@ -46,6 +46,8 @@ def options(opt):
help='One or more comma separated architecture names to be used for '
'the Mac builds. Should be at least a subset of the architectures '
'used by wxWidgets and Python')
+ opt.add_option('--gtk3', dest='gtk3', action='store_true', default=False,
+ help='On Linux build for gtk3 (default gtk2)')
opt.add_option('--msvc_arch', dest='msvc_arch', default='x86', action='store',
help='The architecture to target for MSVC builds. Supported values '
'are: "x86" or "x64"')
@@ -224,7 +226,10 @@ def configure(conf):
# GTK2 port of wxWidgets. If we ever support other ports then
# this code will need to be adjusted.
if not isDarwin:
- gtkflags = os.popen('pkg-config gtk+-2.0 --cflags', 'r').read()[:-1]
+ if conf.options.gtk3:
+ gtkflags = os.popen('pkg-config gtk+-3.0 --cflags', 'r').read()[:-1]
+ else:
+ gtkflags = os.popen('pkg-config gtk+-2.0 --cflags', 'r').read()[:-1]
conf.env.CFLAGS_WX += gtkflags.split()
conf.env.CXXFLAGS_WX += gtkflags.split()
diff --git a/wx/lib/mixins/listctrl.py b/wx/lib/mixins/listctrl.py
index d0d52047..6007dd62 100644
--- a/wx/lib/mixins/listctrl.py
+++ b/wx/lib/mixins/listctrl.py
@@ -261,7 +261,7 @@ class ListCtrlAutoWidthMixin:
We automatically resize the last column in the list.
"""
- if 'gtk2' in wx.PlatformInfo:
+ if 'gtk2' in wx.PlatformInfo or 'gtk3' in wx.PlatformInfo:
self._doResize()
else:
wx.CallAfter(self._doResize)
diff --git a/wx/lib/wxcairo.py b/wx/lib/wxcairo.py
index a1cf21b2..c35c19fb 100644
--- a/wx/lib/wxcairo.py
+++ b/wx/lib/wxcairo.py
@@ -117,11 +117,18 @@ def ContextFromDC(dc):
elif 'wxGTK' in wx.PlatformInfo:
- # Get the GdkDrawable from the dc
- drawable = voidp( dc.GetHandle() )
+ if 'gtk3' in wx.PlatformInfo:
+ # With wxGTK3, GetHandle() returns a cairo context directly
+ ctxptr = voidp( dc.GetHandle() )
- # Call a GDK API to create a cairo context
- ctxptr = gdkLib.gdk_cairo_create(drawable)
+ # pyCairo will try to destroy it so we need to increase ref count
+ cairoLib.cairo_reference(ctxptr)
+ else:
+ # Get the GdkDrawable from the dc
+ drawable = voidp( dc.GetHandle() )
+
+ # Call a GDK API to create a cairo context
+ ctxptr = gdkLib.gdk_cairo_create(drawable)
# Turn it into a pycairo context object
ctx = pycairoAPI.Context_FromContext(ctxptr, pycairoAPI.Context_Type, None)
@@ -300,7 +307,11 @@ def _findHelper(names, key, msg):
def _findGDKLib():
- return _findHelper(['gdk-x11-2.0'], 'gdk',
+ if 'gtk3' in wx.PlatformInfo:
+ libname = 'gdk-3'
+ else:
+ libname = 'gdk-x11-2.0'
+ return _findHelper([libname], 'gdk',
"Unable to find the GDK shared library")
def _findPangoCairoLib():
diff --git a/wx/py/editwindow.py b/wx/py/editwindow.py
index efa126bf..f223669f 100644
--- a/wx/py/editwindow.py
+++ b/wx/py/editwindow.py
@@ -27,7 +27,8 @@ if 'wxMSW' in wx.PlatformInfo:
'calltipfg' : '#404040',
}
-elif 'wxGTK' in wx.PlatformInfo and 'gtk2' in wx.PlatformInfo:
+elif 'wxGTK' in wx.PlatformInfo and ('gtk2' in wx.PlatformInfo or
+ 'gtk3' in wx.PlatformInfo):
FACES = { 'times' : 'Serif',
'mono' : 'Monospace',
'helv' : 'Sans',