Răsfoiți Sursa

Merge branch 'release/1.9.x'

rdb 9 ani în urmă
părinte
comite
4283a63a7d

+ 22 - 5
direct/src/showbase/ShowBase.py

@@ -201,7 +201,9 @@ class ShowBase(DirectObject.DirectObject):
         ## This is used to store the wx.Application object used when want-wx is
         ## This is used to store the wx.Application object used when want-wx is
         ## set or base.startWx() is called.
         ## set or base.startWx() is called.
         self.wxApp = None
         self.wxApp = None
+        self.wxAppCreated = False
         self.tkRoot = None
         self.tkRoot = None
+        self.tkRootCreated = False
 
 
         # This is used for syncing multiple PCs in a distributed cluster
         # This is used for syncing multiple PCs in a distributed cluster
         try:
         try:
@@ -259,6 +261,17 @@ class ShowBase(DirectObject.DirectObject):
             random.seed(seed)
             random.seed(seed)
             #whrandom.seed(seed & 0xff, (seed >> 8) & 0xff, (seed >> 16) & 0xff)
             #whrandom.seed(seed & 0xff, (seed >> 8) & 0xff, (seed >> 16) & 0xff)
 
 
+        # For some reason, wx needs to be initialized before the graphics window
+        if sys.platform == "darwin":
+            if self.config.GetBool("want-wx", 0):
+                wx = importlib.import_module('wx')
+                self.wxApp = wx.App()
+
+            # Same goes for Tk, which uses a conflicting NSApplication
+            if self.config.GetBool("want-tk", 0):
+                Pmw = importlib.import_module('Pmw')
+                self.tkRoot = Pmw.initialise()
+
         # Open the default rendering window.
         # Open the default rendering window.
         if self.windowType != 'none':
         if self.windowType != 'none':
             props = WindowProperties.getDefault()
             props = WindowProperties.getDefault()
@@ -2821,7 +2834,7 @@ class ShowBase(DirectObject.DirectObject):
         updated, but wxPython owns the main loop (which seems to make
         updated, but wxPython owns the main loop (which seems to make
         it happier than the other way around). """
         it happier than the other way around). """
 
 
-        if self.wxApp:
+        if self.wxAppCreated:
             # Don't do this twice.
             # Don't do this twice.
             return
             return
 
 
@@ -2831,8 +2844,9 @@ class ShowBase(DirectObject.DirectObject):
         # by modulefinder when packaging an application.
         # by modulefinder when packaging an application.
         wx = importlib.import_module('wx')
         wx = importlib.import_module('wx')
 
 
-        # Create a new base.wxApp.
-        self.wxApp = wx.PySimpleApp(redirect = False)
+        if not self.wxApp:
+            # Create a new base.wxApp.
+            self.wxApp = wx.PySimpleApp(redirect = False)
 
 
         if ConfigVariableBool('wx-main-loop', True):
         if ConfigVariableBool('wx-main-loop', True):
             # Put wxPython in charge of the main loop.  It really
             # Put wxPython in charge of the main loop.  It really
@@ -2867,6 +2881,7 @@ class ShowBase(DirectObject.DirectObject):
                 return task.again
                 return task.again
 
 
             self.taskMgr.add(wxLoop, 'wxLoop')
             self.taskMgr.add(wxLoop, 'wxLoop')
+        self.wxAppCreated = True
 
 
     def __wxTimerCallback(self, event):
     def __wxTimerCallback(self, event):
         if Thread.getCurrentThread().getCurrentTask():
         if Thread.getCurrentThread().getCurrentTask():
@@ -2901,7 +2916,7 @@ class ShowBase(DirectObject.DirectObject):
         updated, but Tkinter owns the main loop (which seems to make
         updated, but Tkinter owns the main loop (which seems to make
         it happier than the other way around). """
         it happier than the other way around). """
 
 
-        if self.tkRoot:
+        if self.tkRootCreated:
             # Don't do this twice.
             # Don't do this twice.
             return
             return
 
 
@@ -2911,7 +2926,8 @@ class ShowBase(DirectObject.DirectObject):
         Pmw = importlib.import_module('Pmw')
         Pmw = importlib.import_module('Pmw')
 
 
         # Create a new Tk root.
         # Create a new Tk root.
-        self.tkRoot = Pmw.initialise()
+        if not self.tkRoot:
+            self.tkRoot = Pmw.initialise()
         builtins.tkroot = self.tkRoot
         builtins.tkroot = self.tkRoot
 
 
         init_app_for_gui()
         init_app_for_gui()
@@ -2947,6 +2963,7 @@ class ShowBase(DirectObject.DirectObject):
                 return task.again
                 return task.again
 
 
             self.taskMgr.add(tkLoop, 'tkLoop')
             self.taskMgr.add(tkLoop, 'tkLoop')
+        self.tkRootCreated = True
 
 
     def __tkTimerCallback(self):
     def __tkTimerCallback(self):
         if not Thread.getCurrentThread().getCurrentTask():
         if not Thread.getCurrentThread().getCurrentTask():

+ 2 - 1
dtool/src/interrogate/interfaceMaker.cxx

@@ -133,7 +133,8 @@ check_protocols() {
     if (func->_ifunc.get_name() == "__traverse__") {
     if (func->_ifunc.get_name() == "__traverse__") {
       // If we have a method named __traverse__, we implement Python's cyclic
       // If we have a method named __traverse__, we implement Python's cyclic
       // garbage collection protocol.
       // garbage collection protocol.
-      _protocol_types |= PT_python_gc;
+      //XXX disabled for now because it's too unstable.
+      //_protocol_types |= PT_python_gc;
     }
     }
   }
   }
 
 

+ 6 - 5
dtool/src/interrogate/interfaceMakerPythonNative.cxx

@@ -2862,10 +2862,9 @@ write_module_class(ostream &out, Object *obj) {
   }
   }
 
 
   string gcflag;
   string gcflag;
-  // Disabled for now because it's too unstable.
-  /*if (obj->_protocol_types & Object::PT_python_gc) {
+  if (obj->_protocol_types & Object::PT_python_gc) {
     gcflag = " | Py_TPFLAGS_HAVE_GC";
     gcflag = " | Py_TPFLAGS_HAVE_GC";
-  }*/
+  }
 
 
   // long tp_flags;
   // long tp_flags;
   if (has_local_getbuffer) {
   if (has_local_getbuffer) {
@@ -2891,10 +2890,12 @@ write_module_class(ostream &out, Object *obj) {
   }
   }
 
 
   // traverseproc tp_traverse;
   // traverseproc tp_traverse;
-  write_function_slot(out, 4, slots, "tp_traverse");
+  out << "    0, // tp_traverse\n";
+  //write_function_slot(out, 4, slots, "tp_traverse");
 
 
   // inquiry tp_clear;
   // inquiry tp_clear;
-  write_function_slot(out, 4, slots, "tp_clear");
+  out << "    0, // tp_clear\n";
+  //write_function_slot(out, 4, slots, "tp_clear");
 
 
   // richcmpfunc tp_richcompare;
   // richcmpfunc tp_richcompare;
   if (has_local_richcompare) {
   if (has_local_richcompare) {

+ 20 - 0
panda/src/cocoadisplay/cocoaPandaApp.mm

@@ -25,4 +25,24 @@
     [super sendEvent: event];
     [super sendEvent: event];
   }
   }
 }
 }
+
+- (void) _setup: (void *) interp {
+  // This is called by Tk when it launches and naively assumes that it is
+  // the first to create an NSApplication.  We can't do anything about it
+  // at this point except display an error message.
+
+  cocoadisplay_cat.error()
+    << "Detected attempt to initialize Tk after creating a Panda window.  "
+       "This will likely cause a crash.\n"
+       "To fix this, set 'want-tk true' in Config.prc to force "
+       "initialization of Tk before opening the Panda window.\n";
+}
+
+- (void) _setupEventLoop {
+  NSAutoreleasePool *pool = [NSAutoreleasePool new];
+  [self finishLaunching];
+  [self setWindowsNeedUpdate:YES];
+  [pool drain];
+}
+
 @end
 @end

+ 4 - 3
samples/particles/particle_panel.py

@@ -17,13 +17,14 @@ try:
 except:
 except:
     sys.exit("Please install Python megawidgets")
     sys.exit("Please install Python megawidgets")
 
 
+# Makes sure that Panda is configured to play nice with Tkinter
+from panda3d.core import *
+loadPrcFileData("", "want-tk true")
+
 # Open the Panda window
 # Open the Panda window
 from direct.showbase.ShowBase import ShowBase
 from direct.showbase.ShowBase import ShowBase
 base = ShowBase()
 base = ShowBase()
 
 
-# Makes sure that Panda is configured to play nice with Tkinter
-base.startTk()
-
 from direct.tkpanels.ParticlePanel import ParticlePanel
 from direct.tkpanels.ParticlePanel import ParticlePanel
 
 
 pp = ParticlePanel()             # Create the panel
 pp = ParticlePanel()             # Create the panel