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 56309643..2de3ae89 100755 --- a/build.py +++ b/build.py @@ -371,6 +371,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.")), @@ -1305,6 +1306,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 53c60d3c..4a1cd0c3 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 d5a585de..e422c475 100644 --- a/demo/Main.py +++ b/demo/Main.py @@ -1526,7 +1526,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 f80e94e7..ac53ed07 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',