@@ -252,6 +252,20 @@ - (BOOL)acceptsFirstResponder;
252
252
253
253
/* ---------------------------- Python classes ---------------------------- */
254
254
255
+ // Acquire the GIL, call a method with no args, discarding the result and
256
+ // printing any exception.
257
+ static void gil_call_method (PyObject* obj, const char * name)
258
+ {
259
+ PyGILState_STATE gstate = PyGILState_Ensure ();
260
+ PyObject* result = PyObject_CallMethod (obj, name, NULL );
261
+ if (result) {
262
+ Py_DECREF (result);
263
+ } else {
264
+ PyErr_Print ();
265
+ }
266
+ PyGILState_Release (gstate);
267
+ }
268
+
255
269
static bool backend_inited = false ;
256
270
257
271
static void lazy_init (void ) {
@@ -837,13 +851,13 @@ static CGFloat _get_device_scale(CGContextRef cr)
837
851
FigureManager_new, /* tp_new */
838
852
};
839
853
840
- @interface NavigationToolbar2Handler : NSObject
841
- { PyObject* toolbar;
854
+ @interface NavigationToolbar2Handler : NSObject {
855
+ PyObject* toolbar;
842
856
NSButton * panbutton;
843
857
NSButton * zoombutton;
844
858
}
845
859
- (NavigationToolbar2Handler*)initWithToolbar : (PyObject*)toolbar ;
846
- - (void )installCallbacks : (SEL [7 ])actions forButtons : (NSButton *[7 ])buttons ;
860
+ - (void )installCallbacks : (SEL [7 ])actions forButtons : (NSButton *[7 ])buttons ;
847
861
- (void )home : (id )sender ;
848
862
- (void )back : (id )sender ;
849
863
- (void )forward : (id )sender ;
@@ -863,118 +877,43 @@ - (void)save_figure:(id)sender;
863
877
864
878
@implementation NavigationToolbar2Handler
865
879
- (NavigationToolbar2Handler*)initWithToolbar : (PyObject*)theToolbar
866
- { [self init ];
880
+ {
881
+ [self init ];
867
882
toolbar = theToolbar;
868
883
return self;
869
884
}
870
885
871
- - (void )installCallbacks : (SEL [7 ])actions forButtons : (NSButton *[7 ])buttons
886
+ - (void )installCallbacks : (SEL [7 ])actions forButtons : (NSButton *[7 ])buttons
872
887
{
873
888
int i;
874
- for (i = 0 ; i < 7 ; i++)
875
- {
889
+ for (i = 0 ; i < 7 ; i++) {
876
890
SEL action = actions[i];
877
891
NSButton * button = buttons[i];
878
892
[button setTarget: self ];
879
893
[button setAction: action];
880
- if (action== @selector (pan: )) { panbutton = button; }
881
- if (action== @selector (zoom: )) { zoombutton = button; }
894
+ if (action == @selector (pan: )) { panbutton = button; }
895
+ if (action == @selector (zoom: )) { zoombutton = button; }
882
896
}
883
897
}
884
898
885
- -(void )home : (id )sender
886
- { PyObject* result;
887
- PyGILState_STATE gstate;
888
- gstate = PyGILState_Ensure ();
889
- result = PyObject_CallMethod (toolbar, " home" , " " );
890
- if (result)
891
- Py_DECREF (result);
892
- else
893
- PyErr_Print ();
894
- PyGILState_Release (gstate);
895
- }
896
-
897
- -(void )back : (id )sender
898
- { PyObject* result;
899
- PyGILState_STATE gstate;
900
- gstate = PyGILState_Ensure ();
901
- result = PyObject_CallMethod (toolbar, " back" , " " );
902
- if (result)
903
- Py_DECREF (result);
904
- else
905
- PyErr_Print ();
906
- PyGILState_Release (gstate);
907
- }
908
-
909
- -(void )forward : (id )sender
910
- { PyObject* result;
911
- PyGILState_STATE gstate;
912
- gstate = PyGILState_Ensure ();
913
- result = PyObject_CallMethod (toolbar, " forward" , " " );
914
- if (result)
915
- Py_DECREF (result);
916
- else
917
- PyErr_Print ();
918
- PyGILState_Release (gstate);
919
- }
899
+ -(void )home : (id )sender { gil_call_method (toolbar, " home" ); }
900
+ -(void )back : (id )sender { gil_call_method (toolbar, " back" ); }
901
+ -(void )forward : (id )sender { gil_call_method (toolbar, " forward" ); }
920
902
921
903
-(void )pan : (id )sender
922
- { PyObject* result;
923
- PyGILState_STATE gstate;
924
- if ([sender state ])
925
- {
926
- if (zoombutton) [zoombutton setState: NO ];
927
- }
928
- gstate = PyGILState_Ensure ();
929
- result = PyObject_CallMethod (toolbar, " pan" , " " );
930
- if (result)
931
- Py_DECREF (result);
932
- else
933
- PyErr_Print ();
934
- PyGILState_Release (gstate);
904
+ {
905
+ if ([sender state ]) { [zoombutton setState: NO ]; }
906
+ gil_call_method (toolbar, " pan" );
935
907
}
936
908
937
909
-(void )zoom : (id )sender
938
- { PyObject* result;
939
- PyGILState_STATE gstate;
940
- if ([sender state ])
941
- {
942
- if (panbutton) [panbutton setState: NO ];
943
- }
944
- gstate = PyGILState_Ensure ();
945
- result = PyObject_CallMethod (toolbar, " zoom" , " " );
946
- if (result)
947
- Py_DECREF (result);
948
- else
949
- PyErr_Print ();
950
- PyGILState_Release (gstate);
951
- }
952
-
953
- -(void )configure_subplots : (id )sender
954
910
{
955
- PyObject* result;
956
- PyGILState_STATE gstate;
957
- gstate = PyGILState_Ensure ();
958
- result = PyObject_CallMethod (toolbar, " configure_subplots" , NULL );
959
- if (result) {
960
- Py_DECREF (result);
961
- } else {
962
- PyErr_Print ();
963
- }
964
- PyGILState_Release (gstate);
911
+ if ([sender state ]) { [panbutton setState: NO ]; }
912
+ gil_call_method (toolbar, " zoom" );
965
913
}
966
914
967
- -(void )save_figure : (id )sender
968
- { PyObject* result;
969
- PyGILState_STATE gstate;
970
- gstate = PyGILState_Ensure ();
971
- result = PyObject_CallMethod (toolbar, " save_figure" , " " );
972
- if (result)
973
- Py_DECREF (result);
974
- else
975
- PyErr_Print ();
976
- PyGILState_Release (gstate);
977
- }
915
+ -(void )configure_subplots : (id )sender { gil_call_method (toolbar, " configure_subplots" ); }
916
+ -(void )save_figure : (id )sender { gil_call_method (toolbar, " save_figure" ); }
978
917
@end
979
918
980
919
static PyObject*
@@ -1352,19 +1291,7 @@ - (NSRect)constrainFrameRect:(NSRect)rect toScreen:(NSScreen*)screen
1352
1291
return suggested;
1353
1292
}
1354
1293
1355
- - (BOOL )closeButtonPressed
1356
- {
1357
- PyObject* result;
1358
- PyGILState_STATE gstate;
1359
- gstate = PyGILState_Ensure ();
1360
- result = PyObject_CallMethod (manager, " close" , " " );
1361
- if (result)
1362
- Py_DECREF (result);
1363
- else
1364
- PyErr_Print ();
1365
- PyGILState_Release (gstate);
1366
- return YES ;
1367
- }
1294
+ - (BOOL )closeButtonPressed { gil_call_method (manager, " close" ); }
1368
1295
1369
1296
- (void )close
1370
1297
{
@@ -1966,15 +1893,7 @@ - (void)flagsChanged:(NSEvent*)event
1966
1893
1967
1894
static void timer_callback (CFRunLoopTimerRef timer, void * info)
1968
1895
{
1969
- PyObject* method = info;
1970
- PyGILState_STATE gstate = PyGILState_Ensure ();
1971
- PyObject* result = PyObject_CallFunction (method, NULL );
1972
- if (result) {
1973
- Py_DECREF (result);
1974
- } else {
1975
- PyErr_Print ();
1976
- }
1977
- PyGILState_Release (gstate);
1896
+ gil_call_method (info, " _on_timer" );
1978
1897
}
1979
1898
1980
1899
static void context_cleanup (const void * info)
@@ -2013,12 +1932,12 @@ static void context_cleanup(const void* info)
2013
1932
PyErr_SetString (PyExc_RuntimeError, " _on_timer should be a Python method" );
2014
1933
goto exit ;
2015
1934
}
2016
- Py_INCREF (py_on_timer );
1935
+ Py_INCREF (self );
2017
1936
context.version = 0 ;
2018
1937
context.retain = NULL ;
2019
1938
context.release = context_cleanup;
2020
1939
context.copyDescription = NULL ;
2021
- context.info = py_on_timer ;
1940
+ context.info = self ;
2022
1941
timer = CFRunLoopTimerCreate (kCFAllocatorDefault ,
2023
1942
firstFire,
2024
1943
interval,
0 commit comments