From ab6aa5463ffdd5cfaf729eb1f5407be749ba1090 Mon Sep 17 00:00:00 2001 From: Thomas James Alexander Thurman Date: Fri, 6 Mar 2009 22:51:02 +0000 Subject: [PATCH] add optional dependency on gtop. Include "(as username)" in the titlebar * configure.in: add optional dependency on gtop. * src/core/window-props.c: Include "(as username)" in the titlebar if a window is running as another user. * src/core/window.c: check for PID before name, since the rendering of the name can now depend on the PID. Closes #549389. svn path=/trunk/; revision=4181 --- ChangeLog | 10 +++++ configure.in | 14 ++++++ src/core/window-props.c | 99 ++++++++++++++++++++++++++++++++++++++++- src/core/window.c | 2 +- 4 files changed, 123 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d97825ade..046f32e22 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2009-03-06 Thomas Thurman + + * configure.in: add optional dependency on gtop. + * src/core/window-props.c: Include "(as username)" + in the titlebar if a window is running as another user. + * src/core/window.c: check for PID before name, since + the rendering of the name can now depend on the PID. + + Closes #549389. + 2009-02-21 Matthias Clasen * src/core/bell.c: Don't force CA_PROP_CANBERRA_ENABLE to 1. diff --git a/configure.in b/configure.in index d53b56db5..3884d8974 100644 --- a/configure.in +++ b/configure.in @@ -284,6 +284,20 @@ if test x$have_xcursor = xyes; then AC_DEFINE(HAVE_XCURSOR, , [Building with Xcursor support]) fi +AC_MSG_CHECKING([libgtop]) +if $PKG_CONFIG libgtop-2.0; then + have_gtop=yes + else + have_gtop=no + fi + AC_MSG_RESULT($have_gtop) + +if test x$have_gtop = xyes; then + echo "Building with libgtop" + METACITY_PC_MODULES="$METACITY_PC_MODULES libgtop-2.0" + AC_DEFINE(HAVE_GTOP, , [Building with libgtop]) +fi + PKG_CHECK_MODULES(METACITY, $METACITY_PC_MODULES) AC_PATH_XTRA diff --git a/src/core/window-props.c b/src/core/window-props.c index 2ef3597a5..02b88458f 100644 --- a/src/core/window-props.c +++ b/src/core/window-props.c @@ -47,6 +47,16 @@ #include #include #include +#include +#include +#include + +#ifdef HAVE_GTOP +#include +#include +#include +#endif /* HAVE_GTOP */ + #ifndef HOST_NAME_MAX /* Solaris headers apparently don't define this so do so manually; #326745 */ #define HOST_NAME_MAX 255 @@ -337,6 +347,32 @@ reload_net_wm_user_time_window (MetaWindow *window, } } +/** + * Finds who owns a particular process, if we can. + * + * \param process The process's ID. + * \result Set to the ID of the user, if we returned true. + * + * \result True if we could tell. + */ +static gboolean +owner_of_process (pid_t process, uid_t *result) +{ +#ifdef HAVE_GTOP + glibtop_proc_uid process_details; + + glibtop_get_proc_uid (&process_details, process); + + *result = process_details.uid; + return TRUE; +#else + /* I don't know, maybe we could do something hairy like see whether + * /proc/$PID exists and who owns it, in case they have procfs. + */ + return FALSE; +#endif /* HAVE_GTOP */ +} + #define MAX_TITLE_LENGTH 512 /** @@ -369,15 +405,76 @@ set_title_text (MetaWindow *window, modified = TRUE; } /* if WM_CLIENT_MACHINE indicates this machine is on a remote host - * lets place that hostname in the title */ + * let's place that hostname in the title */ else if (window->wm_client_machine && !gethostname (hostname, HOST_NAME_MAX + 1) && strcmp (hostname, window->wm_client_machine)) { + /* Translators: the title of a window from another machine */ *target = g_strdup_printf (_("%s (on %s)"), title, window->wm_client_machine); modified = TRUE; } + else if (window->net_wm_pid != -1) + { + /* We know the process which owns this window; perhaps we can + * find out the name of its owner (if it's not us). + */ + + char *found_name = NULL; + + uid_t window_owner = 0; + gboolean window_owner_known = + owner_of_process (window->net_wm_pid, &window_owner); + + /* Assume a window with unknown ownership is ours (call it usufruct!) */ + gboolean window_owner_is_us = + !window_owner_known || window_owner==getuid (); + + if (window_owner_is_us) + { + /* we own it, so fall back to the simple case */ + *target = g_strdup (title); + } + else + { + /* it belongs to window_owner. So what's their name? */ + + if (window_owner==0) + { + /* Simple case-- don't bother to look it up. It's root. */ + *target = g_strdup_printf (_("%s (as superuser)"), + title); + } + else + { + /* Okay, let's look up the name. */ + struct passwd *pwd; + + errno = 0; + pwd = getpwuid (window_owner); + if (errno==0 || pwd==NULL) + { + found_name = pwd->pw_name; + } + + if (found_name) + /* Translators: the title of a window owned by another user + * on this machine */ + *target = g_strdup_printf (_("%s (as %s)"), + title, + found_name); + else + /* Translators: the title of a window owned by another user + * on this machine, whose name we don't know */ + *target = g_strdup_printf (_("%s (as another user)"), + title); + } + /* either way we changed it */ + modified = TRUE; + + } + } else *target = g_strdup (title); diff --git a/src/core/window.c b/src/core/window.c index c9bc037fc..6de86ee3c 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -572,9 +572,9 @@ meta_window_new_with_attrs (MetaDisplay *display, */ i = 0; initial_props[i++] = display->atom_WM_CLIENT_MACHINE; + initial_props[i++] = display->atom__NET_WM_PID; initial_props[i++] = display->atom__NET_WM_NAME; initial_props[i++] = XA_WM_CLASS; - initial_props[i++] = display->atom__NET_WM_PID; initial_props[i++] = XA_WM_NAME; initial_props[i++] = display->atom__NET_WM_ICON_NAME; initial_props[i++] = XA_WM_ICON_NAME;