diff --git a/eekboard/eekboard-keyboard.c b/eekboard/eekboard-keyboard.c
index b9730d2a..db6e30c2 100644
--- a/eekboard/eekboard-keyboard.c
+++ b/eekboard/eekboard-keyboard.c
@@ -37,6 +37,7 @@ G_DEFINE_TYPE (EekboardKeyboard, eekboard_keyboard, G_TYPE_DBUS_PROXY);
 struct _EekboardKeyboardPrivate
 {
     EekKeyboard *description;
+    gboolean visible;
 };
 
 static void
@@ -46,21 +47,27 @@ eekboard_keyboard_real_g_signal (GDBusProxy  *self,
                                  GVariant    *parameters)
 {
     EekboardKeyboard *keyboard = EEKBOARD_KEYBOARD (self);
-    guint *keycode;
+    EekboardKeyboardPrivate *priv = EEKBOARD_KEYBOARD_GET_PRIVATE (keyboard);
 
     if (g_strcmp0 (signal_name, "KeyPressed") == 0) {
-
+        guint keycode;
         g_variant_get (parameters, "(u)", &keycode);
         g_signal_emit_by_name (keyboard, "key-pressed", keycode);
         return;
     }
 
     if (g_strcmp0 (signal_name, "KeyReleased") == 0) {
+        guint keycode;
         g_variant_get (parameters, "(u)", &keycode);
         g_signal_emit_by_name (keyboard, "key-released", keycode);
         return;
     }
 
+    if (g_strcmp0 (signal_name, "VisibilityChanged") == 0) {
+        g_variant_get (parameters, "(b)", &priv->visible);
+        return;
+    }
+
     g_return_if_reached ();
 }
 
@@ -134,6 +141,7 @@ eekboard_keyboard_init (EekboardKeyboard *self)
 
     priv = self->priv = EEKBOARD_KEYBOARD_GET_PRIVATE(self);
     priv->description = NULL;
+    priv->visible = FALSE;
 }
 
 /**
@@ -287,3 +295,14 @@ eekboard_keyboard_release_key (EekboardKeyboard *keyboard,
                        proxy_call_async_ready_cb,
                        NULL);
 }
+
+gboolean
+eekboard_keyboard_get_visible (EekboardKeyboard *keyboard)
+{
+    EekboardKeyboardPrivate *priv;
+
+    g_assert (EEKBOARD_IS_KEYBOARD(keyboard));
+
+    priv = EEKBOARD_KEYBOARD_GET_PRIVATE (keyboard);
+    return priv->visible;
+}
diff --git a/eekboard/eekboard-keyboard.h b/eekboard/eekboard-keyboard.h
index 7268e688..19f04dc5 100644
--- a/eekboard/eekboard-keyboard.h
+++ b/eekboard/eekboard-keyboard.h
@@ -65,6 +65,7 @@ void              eekboard_keyboard_press_key   (EekboardKeyboard *keyboard,
                                                  guint             keycode);
 void              eekboard_keyboard_release_key (EekboardKeyboard *keyboard,
                                                  guint             keycode);
+gboolean          eekboard_keyboard_get_visible (EekboardKeyboard *keyboard);
 
 G_END_DECLS
 #endif  /* EEKBOARD_KEYBOARD_H */
diff --git a/src/server.c b/src/server.c
index 3aa1ec66..7ffed6d0 100644
--- a/src/server.c
+++ b/src/server.c
@@ -64,6 +64,9 @@ static const gchar introspection_xml[] =
     "    "
     "      "
     "    "
+    "    "
+    "      "
+    "    "
     "  "
     "";
 
@@ -113,6 +116,26 @@ on_destroy (GtkWidget *widget, gpointer user_data)
     server->widget = NULL;
 }
 
+static void
+on_notify_visible (GObject *object, GParamSpec *spec, gpointer user_data)
+{
+    EekboardServer *server = user_data;
+    gboolean visible;
+    GError *error;
+
+    g_object_get (object, "visible", &visible, NULL);
+
+    error = NULL;
+    g_dbus_connection_emit_signal (server->connection,
+                                   "com.redhat.eekboard.Keyboard",
+                                   "/com/redhat/eekboard/Keyboard",
+                                   "com.redhat.eekboard.Keyboard",
+                                   "VisibilityChanged",
+                                   g_variant_new ("(b)", visible),
+                                   &error);
+    g_assert_no_error (error);
+}
+
 static void
 update_widget (EekboardServer *server)
 {
@@ -156,6 +179,8 @@ update_widget (EekboardServer *server)
     server->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
     g_signal_connect (server->window, "destroy",
                       G_CALLBACK(on_destroy), server);
+    g_signal_connect (server->window, "notify::visible",
+                      G_CALLBACK(on_notify_visible), server);
     gtk_container_add (GTK_CONTAINER(server->window), server->widget);
 
     gtk_widget_set_can_focus (server->window, FALSE);
@@ -312,7 +337,6 @@ handle_method_call (GDBusConnection       *connection,
     if (g_strcmp0 (method_name, "SetDescription") == 0) {
         EekSerializable *serializable;
         GVariant *variant;
-        gchar *data;
 
         g_variant_get (parameters, "(v)", &variant);
         serializable = eek_serializable_deserialize (variant);
@@ -387,6 +411,7 @@ handle_method_call (GDBusConnection       *connection,
         g_assert (server->window);
         gtk_widget_show_all (server->window);
         g_dbus_method_invocation_return_value (invocation, NULL);
+        g_object_notify (G_OBJECT(server->window), "visible");
         return;
     }
 
@@ -394,6 +419,7 @@ handle_method_call (GDBusConnection       *connection,
         if (server->window)
             gtk_widget_hide (server->window);
         g_dbus_method_invocation_return_value (invocation, NULL);
+        g_object_notify (G_OBJECT(server->window), "visible");
         return;
     }