--- gnome-control-center-2.30.1.orig/capplets/keyboard/gnome-keyboard-properties-dialog.ui 2010-06-01 13:35:44.209124944 +0200
+++ gnome-control-center-2.30.1/capplets/keyboard/gnome-keyboard-properties-dialog.ui 2010-06-01 13:37:25.982521195 +0200
@@ -501,7 +501,7 @@
</packing>
</child>
<child>
- <object class="GtkVBox" id="vbox33">
+ <object class="GtkVBox" id="layout_tab_widget">
<property name="visible">True</property>
<property name="border_width">12</property>
<property name="orientation">vertical</property>
--- gnome-control-center-2.30.1.orig/capplets/keyboard/gnome-keyboard-properties.c 2010-06-01 13:35:44.228217173 +0200
+++ gnome-control-center-2.30.1/capplets/keyboard/gnome-keyboard-properties.c 2010-06-01 13:42:40.045501900 +0200
@@ -38,11 +38,72 @@
#include "gnome-keyboard-properties-a11y.h"
#include "gnome-keyboard-properties-xkb.h"
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <ucred.h>
+#include <gdk/gdkx.h>
+
enum {
RESPONSE_APPLY = 1,
RESPONSE_CLOSE
};
+/*
+ * Function to determine if a connection is local or not.
+ * Returns: FALSE for remote, TRUE for local
+ */
+static gboolean
+is_xclient_local (Display *dpy) {
+ int c = ConnectionNumber(dpy);
+ struct stat statbuf;
+ gboolean rv = FALSE;
+ ucred_t *ucred = NULL;
+ const char *disp_name;
+
+ if (c >= 0) {
+ /*
+ * stat the connection fd. If we succeed and the type of file
+ * is a FIFO, then we must be local.
+ */
+ if ((fstat(c, &statbuf) >= 0) && S_ISFIFO(statbuf.st_mode)) {
+ return TRUE;
+ }
+ /*
+ * Then call getpeerucred - if it succeeds, the other end of the
+ * connection must be on the same machine (though possibly in a
+ * different zone).
+ */
+ if (getpeerucred(c, &ucred) == 0) {
+ if (ucred_getzoneid(ucred) != -1) {
+ /* If disp_name starts with ':' then it's local
+ * Treats apps running in nested Xservers as remote :( */
+ disp_name = g_getenv ("DISPLAY");
+
+ if (disp_name && disp_name[0] == ':')
+ rv = TRUE;
+ }
+ ucred_free(ucred);
+ }
+ }
+ return rv;
+}
+
+static gboolean
+is_xserver_local (void) {
+ const char *dt_xserver_loc;
+ const char *gdm_xserver_loc;
+
+ dt_xserver_loc = g_getenv ("DTXSERVERLOCATION");
+ gdm_xserver_loc = g_getenv ("GDM_XSERVER_LOCATION");
+
+ if ((dt_xserver_loc && strcmp (dt_xserver_loc, "remote") == 0) ||
+ (gdm_xserver_loc && strcmp (gdm_xserver_loc, "xdmcp") == 0))
+ return FALSE;
+
+ return TRUE;
+}
+
static GtkBuilder *
create_dialog (void)
{
@@ -79,6 +140,18 @@
image = gtk_image_new_from_stock (GTK_STOCK_REFRESH, GTK_ICON_SIZE_BUTTON);
gtk_button_set_image (GTK_BUTTON (WID ("xkb_reset_to_defaults")), image);
+ /* Unless we have both xclient/xserver running in the local */
+ /* machine we won't display the keyboard layout tab */
+
+ Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+
+
+ if (!is_xclient_local(dpy) || !is_xserver_local()) {
+ GtkWidget *layout_tab = WID ("layout_tab_widget");
+
+ gtk_widget_hide (layout_tab);
+ }
+
return dialog;
}