]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
Add _OB_VERSION and _OB_APP_ROLE/CLASS/NAME/TYPE
[chaz/openbox] / openbox / client.c
index 6113062b9fedd74474b5f03c8ffc63ab246b466b..6799654eb81c30813d9d9b60363286d159a27139 100644 (file)
@@ -76,6 +76,7 @@ static RrImage *client_default_icon     = NULL;
 static void client_get_all(ObClient *self, gboolean real);
 static void client_get_startup_id(ObClient *self);
 static void client_get_session_ids(ObClient *self);
+static void client_save_app_rule_values(ObClient *self);
 static void client_get_area(ObClient *self);
 static void client_get_desktop(ObClient *self);
 static void client_get_state(ObClient *self);
@@ -303,6 +304,7 @@ void client_manage(Window window, ObPrompt *prompt)
     self->obwin.type = Window_Client;
     self->window = window;
     self->prompt = prompt;
+    self->managed = TRUE;
 
     /* non-zero defaults */
     self->wmstate = WithdrawnState; /* make sure it gets updated first time */
@@ -370,7 +372,8 @@ void client_manage(Window window, ObPrompt *prompt)
         (user_time != 0) &&
         /* this checks for focus=false for the window */
         (!settings || settings->focus != 0) &&
-        focus_valid_target(self, FALSE, FALSE, TRUE, FALSE, FALSE))
+        focus_valid_target(self, FALSE, FALSE, TRUE, FALSE, FALSE,
+                           settings->focus == 1))
     {
         activate = TRUE;
     }
@@ -505,9 +508,10 @@ void client_manage(Window window, ObPrompt *prompt)
 
         if (!activate) {
             /* if the client isn't stealing focus, then hilite it so the user
-               knows it is there */
-            /* XXX don't do this if we're restoring from a session */
-            client_hilite(self, TRUE);
+               knows it is there, but don't do this if we're restoring from a
+               session */
+            if (!client_restore_session_stacking(self))
+                client_hilite(self, TRUE);
         }
     }
     else {
@@ -630,6 +634,8 @@ void client_unmanage(ObClient *self)
 
     mouse_grab_for_client(self, FALSE);
 
+    self->managed = FALSE;
+
     /* remove the window from our save set, unless we are managing an internal
        ObPrompt window */
     if (!self->prompt)
@@ -1158,6 +1164,9 @@ static void client_get_all(ObClient *self, gboolean real)
        from per-app settings */
     client_get_session_ids(self);
 
+    /* save the values of the variables used for app rule matching */
+    client_save_app_rule_values(self);
+
     /* now we got everything that can affect the decorations */
     if (!real)
         return;
@@ -2109,7 +2118,7 @@ void client_update_strut(ObClient *self)
         STRUT_PARTIAL_SET(strut, 0, 0, 0, 0,
                           0, 0, 0, 0, 0, 0, 0, 0);
 
-    if (!STRUT_EQUAL(strut, self->strut)) {
+    if (!PARTIAL_STRUT_EQUAL(strut, self->strut)) {
         self->strut = strut;
 
         /* updating here is pointless while we're being mapped cuz we're not in
@@ -2365,6 +2374,38 @@ static void client_get_session_ids(ObClient *self)
     }
 }
 
+/*! Save the properties used for app matching rules, as seen by Openbox when
+  the window mapped, so that users can still access them later if the app
+  changes them */
+static void client_save_app_rule_values(ObClient *self)
+{
+    const gchar *type;
+
+    PROP_SETS(self->window, ob_app_role, self->role);
+    PROP_SETS(self->window, ob_app_name, self->name);
+    PROP_SETS(self->window, ob_app_class, self->class);
+
+    switch (self->type) {
+    case OB_CLIENT_TYPE_NORMAL:
+        type = "normal"; break;
+    case OB_CLIENT_TYPE_DIALOG:
+        type = "dialog"; break;
+    case OB_CLIENT_TYPE_UTILITY:
+        type = "utility"; break;
+    case OB_CLIENT_TYPE_MENU:
+        type = "menu"; break;
+    case OB_CLIENT_TYPE_TOOLBAR:
+        type = "toolbar"; break;
+    case OB_CLIENT_TYPE_SPLASH:
+        type = "splash"; break;
+    case OB_CLIENT_TYPE_DESKTOP:
+        type = "desktop"; break;
+    case OB_CLIENT_TYPE_DOCK:
+        type = "dock"; break;
+    }
+    PROP_SETS(self->window, ob_app_type, type);
+}
+
 static void client_change_wm_state(ObClient *self)
 {
     gulong state[2];
@@ -2621,10 +2662,6 @@ gboolean client_hide(ObClient *self)
     gboolean hide = FALSE;
 
     if (!client_should_show(self)) {
-        if (self == focus_client) {
-            event_cancel_all_key_grabs();
-        }
-
         /* We don't need to ignore enter events here.
            The window can hide/iconify in 3 different ways:
            1 - through an x message. in this case we ignore all enter events
@@ -3875,8 +3912,6 @@ gboolean client_focus(ObClient *self)
        go moving on us */
     event_halt_focus_delay();
 
-    event_cancel_all_key_grabs();
-
     xerror_set_ignore(TRUE);
     xerror_occured = FALSE;
 
@@ -3935,10 +3970,12 @@ static void client_present(ObClient *self, gboolean here, gboolean raise,
 }
 
 /* this function exists to map to the net_active_window message in the ewmh */
-void client_activate(ObClient *self, gboolean here, gboolean raise,
+void client_activate(ObClient *self, gboolean desktop,
+                     gboolean here, gboolean raise,
                      gboolean unshade, gboolean user)
 {
-    if ((user && (self->desktop == DESKTOP_ALL ||
+    if ((user && (desktop ||
+                  self->desktop == DESKTOP_ALL ||
                   self->desktop == screen_desktop)) ||
         client_can_steal_focus(self, event_curtime, CurrentTime))
     {
@@ -4239,39 +4276,26 @@ void client_find_edge_directional(ObClient *self, ObDirection dir,
                                   gint *dest, gboolean *near_edge)
 {
     GList *it;
-    Rect *a, *mon;
+    Rect *a;
     Rect dock_area;
     gint edge;
+    guint i;
 
     a = screen_area(self->desktop, SCREEN_AREA_ALL_MONITORS,
                     &self->frame->area);
-    mon = screen_area(self->desktop, SCREEN_AREA_ONE_MONITOR,
-                      &self->frame->area);
 
     switch (dir) {
     case OB_DIRECTION_NORTH:
-        if (my_head >= RECT_TOP(*mon) + 1)
-            edge = RECT_TOP(*mon) - 1;
-        else
-            edge = RECT_TOP(*a) - 1;
+        edge = RECT_TOP(*a) - 1;
         break;
     case OB_DIRECTION_SOUTH:
-        if (my_head <= RECT_BOTTOM(*mon) - 1)
-            edge = RECT_BOTTOM(*mon) + 1;
-        else
-            edge = RECT_BOTTOM(*a) + 1;
+        edge = RECT_BOTTOM(*a) + 1;
         break;
     case OB_DIRECTION_EAST:
-        if (my_head <= RECT_RIGHT(*mon) - 1)
-            edge = RECT_RIGHT(*mon) + 1;
-        else
-            edge = RECT_RIGHT(*a) + 1;
+        edge = RECT_RIGHT(*a) + 1;
         break;
     case OB_DIRECTION_WEST:
-        if (my_head >= RECT_LEFT(*mon) + 1)
-            edge = RECT_LEFT(*mon) - 1;
-        else
-            edge = RECT_LEFT(*a) - 1;
+        edge = RECT_LEFT(*a) - 1;
         break;
     default:
         g_assert_not_reached();
@@ -4280,6 +4304,15 @@ void client_find_edge_directional(ObClient *self, ObDirection dir,
     *dest = edge;
     *near_edge = TRUE;
 
+    /* search for edges of monitors */
+    for (i = 0; i < screen_num_monitors; ++i) {
+        Rect *area = screen_area(self->desktop, i, NULL);
+        detect_edge(*area, dir, my_head, my_size, my_edge_start,
+                    my_edge_size, dest, near_edge);
+        g_free(area);
+    }
+
+    /* search for edges of clients */
     for (it = client_list; it; it = g_list_next(it)) {
         ObClient *cur = it->data;
 
@@ -4301,7 +4334,6 @@ void client_find_edge_directional(ObClient *self, ObDirection dir,
     detect_edge(dock_area, dir, my_head, my_size, my_edge_start,
                 my_edge_size, dest, near_edge);
     g_free(a);
-    g_free(mon);
 }
 
 void client_find_move_directional(ObClient *self, ObDirection dir,
This page took 0.029034 seconds and 4 git commands to generate.