Skip to content

Commit 310a819

Browse files
committed
Set the app icon in the MacOsX manager
Minor fixes Be more pythonic - fail safely rather than prevent failure Some image types may not be handled. OS updates may change which image types are valid. Rather than check, the code will fail if pdf's aren't allowed. If we need more complexity than that, we can update the code. Change to static method for setting icon
1 parent 9d73164 commit 310a819

File tree

2 files changed

+47
-5
lines changed

2 files changed

+47
-5
lines changed

lib/matplotlib/backends/backend_macosx.py

+2
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ class FigureManagerMac(_macosx.FigureManager, FigureManagerBase):
6767
"""
6868
def __init__(self, canvas, num):
6969
_macosx.FigureManager.__init__(self, canvas)
70+
icon_path = str(cbook._get_data_path('images/matplotlib.pdf'))
71+
_macosx.FigureManager.set_icon(icon_path)
7072
FigureManagerBase.__init__(self, canvas, num)
7173
if mpl.rcParams['toolbar'] == 'toolbar2':
7274
self.toolbar = NavigationToolbar2Mac(canvas)

src/_macosx.m

+45-5
Original file line numberDiff line numberDiff line change
@@ -611,24 +611,25 @@ static CGFloat _get_device_scale(CGContextRef cr)
611611
View* view;
612612
PyObject* size;
613613
int width, height;
614-
PyObject* obj;
615614
FigureCanvas* canvas;
616615

617616
if (!self->window) {
618617
PyErr_SetString(PyExc_RuntimeError, "NSWindow* is NULL");
619618
return -1;
620619
}
620+
static char* kwlist[3] = { "canvas", NULL };
621+
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!", kwlist,
622+
&FigureCanvasType, &canvas)) {
623+
return -1;
624+
}
621625

622-
if (!PyArg_ParseTuple(args, "O", &obj)) { return -1; }
623-
624-
canvas = (FigureCanvas*)obj;
625626
view = canvas->view;
626627
if (!view) { /* Something really weird going on */
627628
PyErr_SetString(PyExc_RuntimeError, "NSView* is NULL");
628629
return -1;
629630
}
630631

631-
size = PyObject_CallMethod(obj, "get_width_height", "");
632+
size = PyObject_CallMethod((PyObject*)canvas, "get_width_height", "");
632633
if (!size) { return -1; }
633634
if (!PyArg_ParseTuple(size, "ii", &width, &height)) {
634635
Py_DECREF(size);
@@ -697,6 +698,41 @@ static CGFloat _get_device_scale(CGContextRef cr)
697698
Py_RETURN_NONE;
698699
}
699700

701+
static PyObject*
702+
FigureManager_set_icon(PyObject* null, PyObject* args, PyObject* kwds) {
703+
PyObject* icon_path;
704+
static char* kwlist[3] = { "icon_path", NULL };
705+
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&", kwlist,
706+
&PyUnicode_FSDecoder, &icon_path)) {
707+
return NULL;
708+
}
709+
const char* icon_path_ptr = PyUnicode_AsUTF8(icon_path);
710+
if (!icon_path_ptr) {
711+
Py_DECREF(icon_path);
712+
return NULL;
713+
}
714+
@autoreleasepool {
715+
NSString* ns_icon_path = [NSString stringWithUTF8String: icon_path_ptr];
716+
Py_DECREF(icon_path);
717+
if (!ns_icon_path) {
718+
PyErr_SetString(PyExc_RuntimeError, "Could not convert to NSString*");
719+
return NULL;
720+
}
721+
NSImage* image = [[[NSImage alloc] initByReferencingFile: ns_icon_path] autorelease];
722+
if (!image) {
723+
PyErr_SetString(PyExc_RuntimeError, "Could not create NSImage*");
724+
return NULL;
725+
}
726+
if (!image.valid) {
727+
PyErr_SetString(PyExc_RuntimeError, "Image is not valid");
728+
return NULL;
729+
}
730+
NSApplication* app = [NSApplication sharedApplication];
731+
app.applicationIconImage = image;
732+
}
733+
Py_RETURN_NONE;
734+
}
735+
700736
static PyObject*
701737
FigureManager_set_window_title(FigureManager* self,
702738
PyObject *args, PyObject *kwds)
@@ -769,6 +805,10 @@ static CGFloat _get_device_scale(CGContextRef cr)
769805
{"destroy",
770806
(PyCFunction)FigureManager_destroy,
771807
METH_NOARGS},
808+
{"set_icon",
809+
(PyCFunction)FigureManager_set_icon,
810+
METH_STATIC | METH_VARARGS | METH_KEYWORDS,
811+
"Set application icon"},
772812
{"set_window_title",
773813
(PyCFunction)FigureManager_set_window_title,
774814
METH_VARARGS},

0 commit comments

Comments
 (0)