Merge branch 'backport' into work
[mikachu/openbox.git] / openbox / client.c
index b57d616..a055e63 100644 (file)
@@ -414,12 +414,14 @@ void client_manage(Window window, ObPrompt *prompt)
                   activate ? "yes" : "no");
     if (activate) {
         gboolean raise = FALSE;
-        gboolean relative_focused = FALSE;
+        gboolean relative_focused;
+        gboolean parent_focused;
 
+        parent_focused = (focus_client != NULL &&
+                          client_search_focus_parent(self));
         relative_focused = (focus_client != NULL &&
-                            client_search_focus_tree_full(self) != NULL &&
-                            client_search_focus_group_full(self) != NULL);
-
+                            (client_search_focus_tree_full(self) != NULL ||
+                             client_search_focus_group_full(self) != NULL));
 
         /* This is focus stealing prevention */
         ob_debug_type(OB_DEBUG_FOCUS,
@@ -427,6 +429,12 @@ void client_manage(Window window, ObPrompt *prompt)
                       "launched at %u (last user interaction time %u)",
                       self->window, map_time, launch_time,
                       event_last_user_time);
+        ob_debug_type(OB_DEBUG_FOCUS,
+                      "Current focus_client: %s",
+                      (focus_client ? focus_client->title : "(none)"));
+        ob_debug_type(OB_DEBUG_FOCUS,
+                      "parent focuesed: %d  relative focused: %d",
+                      parent_focused, relative_focused);
 
         if (menu_frame_visible || moveresize_in_progress) {
             activate = FALSE;
@@ -454,7 +462,8 @@ void client_manage(Window window, ObPrompt *prompt)
         else if (focus_client) {
             /* If the user is working in another window right now, then don't
                steal focus */
-            if (event_last_user_time && launch_time &&
+            if (!parent_focused &&
+                event_last_user_time && launch_time &&
                 event_time_after(event_last_user_time, launch_time) &&
                 event_last_user_time != launch_time &&
                 event_time_after(event_last_user_time,
@@ -463,7 +472,8 @@ void client_manage(Window window, ObPrompt *prompt)
                 activate = FALSE;
                 ob_debug_type(OB_DEBUG_FOCUS,
                               "Not focusing the window because the user is "
-                              "working in another window");
+                              "working in another window that is not "
+                              "its parent");
             }
             /* If the new window is a transient (and its relatives aren't
                focused) */
@@ -3339,12 +3349,20 @@ void client_close(ObClient *self)
 #define OB_KILL_RESULT_NO 0
 #define OB_KILL_RESULT_YES 1
 
-static void client_kill_requested(ObPrompt *p, gint result, gpointer data)
+static gboolean client_kill_requested(ObPrompt *p, gint result, gpointer data)
 {
     ObClient *self = data;
 
     if (result == OB_KILL_RESULT_YES)
         client_kill(self);
+    return TRUE; /* call the cleanup func */
+}
+
+static void client_kill_cleanup(ObPrompt *p, gpointer data)
+{
+    ObClient *self = data;
+
+    g_assert(p == self->kill_prompt);
 
     prompt_unref(self->kill_prompt);
     self->kill_prompt = NULL;
@@ -3391,11 +3409,13 @@ static void client_prompt_kill(ObClient *self)
         answers[0].text = _("Cancel");  /* "no" */
         answers[1].text = y;            /* "yes" */
 
-        self->kill_prompt = prompt_new(m, answers,
+        self->kill_prompt = prompt_new(m, NULL, answers,
                                        sizeof(answers)/sizeof(answers[0]),
                                        OB_KILL_RESULT_NO, /* default = no */
                                        OB_KILL_RESULT_NO, /* cancel = no */
-                                       client_kill_requested, self);
+                                       client_kill_requested,
+                                       client_kill_cleanup,
+                                       self);
         g_free(m);
     }
 
@@ -3948,6 +3968,21 @@ ObClient *client_search_focus_parent(ObClient *self)
     return NULL;
 }
 
+ObClient *client_search_focus_parent_full(ObClient *self)
+{
+    GSList *it;
+    ObClient *ret = NULL;
+
+    for (it = self->parents; it; it = g_slist_next(it)) {
+        if (client_focused(it->data))
+            ret = it->data;
+        else
+            ret = client_search_focus_parent_full(it->data);
+        if (ret) break;
+    }
+    return ret;
+}
+
 ObClient *client_search_parent(ObClient *self, ObClient *search)
 {
     GSList *it;