[PATCH] util: add Mac-specific check whether we're in a GUI session (issue2553)

Dan Villiom Podlaski Christiansen danchr at gmail.com
Wed Mar 23 03:46:45 CDT 2011


# HG changeset patch
# User Dan Villiom Podlaski Christiansen <danchr at gmail.com>
# Date 1300869814 -3600
# Node ID 6dda7d7ae77e570d6f5d3ad1a6ac50dcf839cc37
# Parent  0489f917af50e4818fb101aa4d065cc109a8631e
util: add Mac-specific check whether we're in a GUI session (issue2553)

The previous test assumed that 'os.name' was "mac" on Mac OS X. This
is not the case; 'mac' was classic Mac OS, whereas Mac OS X has 'os.name'
be 'posix'.

Please note that this change will break Mercurial on hypothetical
non-Mac OS X deployments of Darwin.

Credit to Brodie Rao for thinking of CGSessionCopyCurrentDictionary()
and Kevin Bullock for testing.

diff --git a/mercurial/osutil.c b/mercurial/osutil.c
--- a/mercurial/osutil.c
+++ b/mercurial/osutil.c
@@ -514,6 +514,22 @@ bail:
 }
 #endif
 
+#ifdef __APPLE__
+#import <ApplicationServices/ApplicationServices.h>
+
+static PyObject *isgui(PyObject *self)
+{
+    CFDictionaryRef dict = CGSessionCopyCurrentDictionary();
+
+    if (dict != NULL) {
+        CFRelease(dict);
+        return Py_True;
+    } else {
+        return Py_False;
+    }
+}
+#endif
+
 static char osutil_doc[] = "Native operating system services.";
 
 static PyMethodDef methods[] = {
@@ -524,6 +540,12 @@ static PyMethodDef methods[] = {
 	 "Open a file with POSIX-like semantics.\n"
 "On error, this function may raise either a WindowsError or an IOError."},
 #endif
+#ifdef __APPLE__
+    {
+        "isgui", (PyCFunction)isgui, METH_NOARGS,
+        "Is a CoreGraphics session available?"
+    },
+#endif
 	{NULL, NULL}
 };
 
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -769,7 +769,18 @@ def splitpath(path):
 
 def gui():
     '''Are we running in a GUI?'''
-    return os.name == "nt" or os.name == "mac" or os.environ.get("DISPLAY")
+    if sys.platform == 'darwin':
+        if 'SSH_CONNECTION' in os.environ:
+            # handle SSH access to a box where the user is logged in
+            return False
+        elif getattr(osutil, 'isgui', None):
+            # check if a CoreGraphics session is available
+            return osutil.isgui()
+        else:
+            # pure build; use a safe default
+            return True
+    else:
+        return os.name == "nt" or os.environ.get("DISPLAY")
 
 def mktempcopy(name, emptyok=False, createmode=None):
     """Create a temporary file with the same contents from name
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -314,11 +314,17 @@ extmodules = [
     Extension('mercurial.parsers', ['mercurial/parsers.c']),
     ]
 
+osutil_ldflags = []
+
+if sys.platform == 'darwin':
+    osutil_ldflags += ['-framework', 'ApplicationServices']
+
 # disable osutil.c under windows + python 2.4 (issue1364)
 if sys.platform == 'win32' and sys.version_info < (2, 5, 0, 'final'):
     pymodules.append('mercurial.pure.osutil')
 else:
-    extmodules.append(Extension('mercurial.osutil', ['mercurial/osutil.c']))
+    extmodules.append(Extension('mercurial.osutil', ['mercurial/osutil.c'],
+                                extra_link_args=osutil_ldflags))
 
 if sys.platform == 'linux2' and os.uname()[2] > '2.6':
     # The inotify extension is only usable with Linux 2.6 kernels.


More information about the Mercurial-devel mailing list