]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
can tell when a window that was "closed" has stopped responding now
[chaz/openbox] / openbox / client.c
index cc721830153a715e44da59d22564ee791505f117..0f592ebe72df9595c79d22840252039f124cf171 100644 (file)
@@ -140,7 +140,7 @@ void client_remove_destroy_notify(ObClientCallback func)
     }
 }
 
-void client_set_list()
+void client_set_list(void)
 {
     Window *windows, *win_it;
     GList *it;
@@ -164,7 +164,7 @@ void client_set_list()
     stacking_set_list();
 }
 
-void client_manage_all()
+void client_manage_all(void)
 {
     guint i, j, nchild;
     Window w, *children;
@@ -450,6 +450,8 @@ void client_manage(Window window)
     g_free(monitor);
     monitor = NULL;
 
+    ob_debug_type(OB_DEBUG_FOCUS, "Going to try activate new window? %s\n",
+                  activate ? "yes" : "no");
     if (activate) {
         gboolean raise = FALSE;
 
@@ -471,10 +473,10 @@ void client_manage(Window window)
 
         /* if it's on another desktop */
         else if (!(self->desktop == screen_desktop ||
-              self->desktop == DESKTOP_ALL) &&
-            /* the timestamp is from before you changed desktops */
-            launch_time && screen_desktop_user_time &&
-            !event_time_after(launch_time, screen_desktop_user_time))
+                   self->desktop == DESKTOP_ALL) &&
+                 /* the timestamp is from before you changed desktops */
+                 launch_time && screen_desktop_user_time &&
+                 !event_time_after(launch_time, screen_desktop_user_time))
         {
             activate = FALSE;
             raise = TRUE;
@@ -526,6 +528,15 @@ void client_manage(Window window)
                               "Not focusing the window because another window "
                               "would get the focus anyway\n");
             }
+            else if (!(self->desktop == screen_desktop ||
+                       self->desktop == DESKTOP_ALL))
+            {
+                activate = FALSE;
+                raise = TRUE;
+                ob_debug_type(OB_DEBUG_FOCUS,
+                              "Not focusing the window because it is on "
+                              "another desktop and no relatives are focused ");
+            }
         }
 
         if (!activate) {
@@ -628,7 +639,7 @@ ObClient *client_fake_manage(Window window)
     return self;
 }
 
-void client_unmanage_all()
+void client_unmanage_all(void)
 {
     while (client_list != NULL)
         client_unmanage(client_list->data);
@@ -751,6 +762,11 @@ void client_unmanage(ObClient *self)
         XMapWindow(ob_display, self->window);
     }
 
+    /* these should not be left on the window ever.  other window managers
+       don't necessarily use them and it will mess them up (like compiz) */
+    PROP_ERASE(self->window, net_wm_visible_name);
+    PROP_ERASE(self->window, net_wm_visible_icon_name);
+
     /* update the list hints */
     client_set_list();
 
@@ -1491,6 +1507,10 @@ void client_update_protocols(ObClient *self)
                 /* if this protocol is requested, then the window will be
                    notified whenever we want it to receive focus */
                 self->focus_notify = TRUE;
+            else if (proto[i] == prop_atoms.net_wm_ping)
+                /* if this protocol is requested, then the window will allow
+                   pings to determine if it is still alive */
+                self->ping = TRUE;
 #ifdef SYNC
             else if (proto[i] == prop_atoms.net_wm_sync_request)
                 /* if this protocol is requested, then resizing the
@@ -1625,11 +1645,16 @@ void client_setup_decor_and_functions(ObClient *self, gboolean reconfig)
     switch (self->type) {
     case OB_CLIENT_TYPE_NORMAL:
         /* normal windows retain all of the possible decorations and
-           functionality, and are the only windows that you can fullscreen */
+           functionality, and can be fullscreen */
         self->functions |= OB_CLIENT_FUNC_FULLSCREEN;
         break;
 
     case OB_CLIENT_TYPE_DIALOG:
+        /* sometimes apps make dialog windows fullscreen for some reason (for
+           e.g. kpdf does this..) */
+        self->functions |= OB_CLIENT_FUNC_FULLSCREEN;
+        break;
+
     case OB_CLIENT_TYPE_UTILITY:
         /* these windows don't have anything added or removed by default */
         break;
@@ -3141,10 +3166,16 @@ void client_shade(ObClient *self, gboolean shade)
     frame_adjust_area(self->frame, FALSE, TRUE, FALSE);
 }
 
-void client_close(ObClient *self)
+static void client_ping_event(ObClient *self, gboolean dead)
 {
-    XEvent ce;
+    if (dead)
+        ob_debug("client 0x%x window 0x%x is not responding !!\n");
+    else
+        ob_debug("client 0x%x window 0x%x started responding again..\n");
+}
 
+void client_close(ObClient *self)
+{
     if (!(self->functions & OB_CLIENT_FUNC_CLOSE)) return;
 
     /* in the case that the client provides no means to requesting that it
@@ -3160,17 +3191,11 @@ void client_close(ObClient *self)
       explicitly killed.
     */
 
-    ce.xclient.type = ClientMessage;
-    ce.xclient.message_type =  prop_atoms.wm_protocols;
-    ce.xclient.display = ob_display;
-    ce.xclient.window = self->window;
-    ce.xclient.format = 32;
-    ce.xclient.data.l[0] = prop_atoms.wm_delete_window;
-    ce.xclient.data.l[1] = event_curtime;
-    ce.xclient.data.l[2] = 0l;
-    ce.xclient.data.l[3] = 0l;
-    ce.xclient.data.l[4] = 0l;
-    XSendEvent(ob_display, self->window, FALSE, NoEventMask, &ce);
+    PROP_MSG_TO(self->window, self->window, wm_protocols,
+                prop_atoms.wm_delete_window, event_curtime, 0, 0, 0,
+                NoEventMask);
+
+    ping_start(self, client_ping_event);
 }
 
 void client_kill(ObClient *self)
@@ -3796,7 +3821,7 @@ static void detect_edge(Rect area, ObDirection dir,
     gint edge_start, edge_size, head, tail;
     gboolean skip_head = FALSE, skip_tail = FALSE;
 
-    switch(dir) {
+    switch (dir) {
         case OB_DIRECTION_NORTH:
         case OB_DIRECTION_SOUTH:
             edge_start = area.x;
@@ -3816,7 +3841,7 @@ static void detect_edge(Rect area, ObDirection dir,
                 edge_start, edge_size))
         return;
 
-    switch(dir) {
+    switch (dir) {
         case OB_DIRECTION_NORTH:
             head = RECT_BOTTOM(area);
             tail = RECT_TOP(area);
@@ -3825,38 +3850,54 @@ static void detect_edge(Rect area, ObDirection dir,
             head = RECT_TOP(area);
             tail = RECT_BOTTOM(area);
             break;
-        case OB_DIRECTION_EAST:
-            head = RECT_LEFT(area);
-            tail = RECT_RIGHT(area);
-            break;
         case OB_DIRECTION_WEST:
             head = RECT_RIGHT(area);
             tail = RECT_LEFT(area);
             break;
+        case OB_DIRECTION_EAST:
+            head = RECT_LEFT(area);
+            tail = RECT_RIGHT(area);
+            break;
         default:
             g_assert_not_reached();
     }
-    switch(dir) {
+    switch (dir) {
         case OB_DIRECTION_NORTH:
         case OB_DIRECTION_WEST:
+            /* check if our window is past the head of this window */
             if (my_head <= head + 1)
                 skip_head = TRUE;
+            /* check if our window's tail is past the tail of this window */
             if (my_head + my_size - 1 <= tail)
                 skip_tail = TRUE;
-            if (head < *dest)
+            /* check if the head of this window is closer than the previously
+               chosen edge (take into account that the previously chosen
+               edge might have been a tail, not a head) */
+            if (head + (*near_edge ? 0 : my_size) < *dest)
                 skip_head = TRUE;
-            if (tail - my_size < *dest)
+            /* check if the tail of this window is closer than the previously
+               chosen edge (take into account that the previously chosen
+               edge might have been a head, not a tail) */
+            if (tail - (!*near_edge ? 0 : my_size) < *dest)
                 skip_tail = TRUE;
             break;
         case OB_DIRECTION_SOUTH:
         case OB_DIRECTION_EAST:
+            /* check if our window is past the head of this window */
             if (my_head >= head - 1)
                 skip_head = TRUE;
+            /* check if our window's tail is past the tail of this window */
             if (my_head - my_size + 1 >= tail)
                 skip_tail = TRUE;
-            if (head > *dest)
+            /* check if the head of this window is closer than the previously
+               chosen edge (take into account that the previously chosen
+               edge might have been a tail, not a head) */
+            if (head - (*near_edge ? 0 : my_size) > *dest)
                 skip_head = TRUE;
-            if (tail + my_size > *dest)
+            /* check if the tail of this window is closer than the previously
+               chosen edge (take into account that the previously chosen
+               edge might have been a head, not a tail) */
+            if (tail + (!*near_edge ? 0 : my_size) > *dest)
                 skip_tail = TRUE;
             break;
         default:
@@ -3875,7 +3916,6 @@ static void detect_edge(Rect area, ObDirection dir,
         *dest = tail;
         *near_edge = FALSE;
     }
-
 }
 
 void client_find_edge_directional(ObClient *self, ObDirection dir,
@@ -3893,7 +3933,7 @@ void client_find_edge_directional(ObClient *self, ObDirection dir,
     mon = screen_area(self->desktop, SCREEN_AREA_ONE_MONITOR,
                       &self->frame->area);
 
-    switch(dir) {
+    switch (dir) {
     case OB_DIRECTION_NORTH:
         if (my_head >= RECT_TOP(*mon) + 1)
             edge = RECT_TOP(*mon) - 1;
@@ -3925,7 +3965,7 @@ void client_find_edge_directional(ObClient *self, ObDirection dir,
     *dest = edge;
     *near_edge = TRUE;
 
-    for(it = client_list; it; it = g_list_next(it)) {
+    for (it = client_list; it; it = g_list_next(it)) {
         ObClient *cur = it->data;
 
         /* skip windows to not bump into */
@@ -3945,6 +3985,8 @@ void client_find_edge_directional(ObClient *self, ObDirection dir,
     dock_get_area(&dock_area);
     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,
@@ -4095,7 +4137,7 @@ void client_find_resize_directional(ObClient *self, ObDirection side,
     *h -= self->frame->size.top + self->frame->size.bottom;
 }
 
-ObClient* client_under_pointer()
+ObClient* client_under_pointer(void)
 {
     gint x, y;
     GList *it;
This page took 0.033981 seconds and 4 git commands to generate.