]> Dogcows Code - chaz/openbox/commitdiff
Merge branch 'backport'
authorDana Jansens <danakj@orodu.net>
Sun, 5 Aug 2007 03:35:36 +0000 (23:35 -0400)
committerDana Jansens <danakj@orodu.net>
Sun, 5 Aug 2007 03:35:36 +0000 (23:35 -0400)
37 files changed:
CHANGELOG
Makefile.am
data/rc.xml
data/rc.xsd
openbox/actions/desktop.c
openbox/actions/growtoedge.c
openbox/actions/restart.c
openbox/actions/unfocus.c
openbox/client.c
openbox/client.h
openbox/client_list_combined_menu.c
openbox/client_list_menu.c
openbox/client_menu.c
openbox/config.c
openbox/config.h
openbox/dock.c
openbox/event.c
openbox/event.h
openbox/focus.c
openbox/focus.h
openbox/frame.c
openbox/frame.h
openbox/framerender.c
openbox/modkeys.c
openbox/moveresize.c
openbox/openbox.c
openbox/place.c
openbox/prop.c
openbox/prop.h
openbox/propwin.c [deleted file]
openbox/propwin.h [deleted file]
openbox/resist.c
openbox/screen.c
openbox/screen.h
po/no.po
po/zh_TW.po
render/theme.c

index 27789e6e1b4b136043ad3dddf1d10c1350303a62..fd68f09bc790415defbd2541b7e3e15068779563 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,44 @@
+3.4.4:
+  * Updated Traditional Chinese translation
+  * Updated Norwegian translation
+  * Fix for MoveToEdge skipping edges sometimes
+  * Let you specify the vertical and horizontal padding independently in themes
+  * Fix so that if you select an omnipresent window on another desktop in the
+    client list menus, it will go to that desktop
+  * Make the GrowToEdge action shrink once there is no more room to grow,
+    similar to in 3.4.2, but shrinking to edges as well
+  * Move the Send To and Layers submenus to the top of the client menu
+  * Fix race causing omnipresent windows to lose focus when switching desktops
+    very quickly
+  * Don't focus new windows on other desktops if they aren't related to the
+    currently focused window
+  * Add corner resizing areas in the inner client border (Fixes themes such
+    as Onyx)
+  * New focus stealing prevention that is smart and not intrusive and not
+    annoying
+  * Revert a small change in 3.4.3 that caused windows to be placed funny in
+    Smart placement when there was a dock or something on the side of the
+    screen
+  * Show a notification when switching desktops
+  * Fix for delayed focus-follows-mouse interrupting move/resize or menus
+  * Make screen edge warp keep warping without having the move the mouse 1
+    pixel
+  * Fix for resizing terminals in the top/left sides getting a little confused
+  * Fix to keep oldschool (Non-EWMH) fullscreen windows from being moved and
+    resized inside of the struts (Fixes Acroread)
+  * Accept the <command> option for the Restart command, similar to the Execute
+    action
+  * Don't make clicking on dock apps sometimes act like clicking on the root
+    window (Don't propogate button events up)
+  * Fix a bug introduced in 3.4.3 which caused the Windows key as a modifier
+    for bindings to not work properly
+  * Let windows skip across monitors in a Xinerama setup when using MoveToEdge
+    or Shift-arrow in an interactive move
+  * Make move and resize take the dock into account for resistance
+  * Raise new windows when it makes sense, when they aren't being focused
+  * Change default config to use click events for mouse wheel bindings instead
+    of presses
+
 3.4.3:
   * Add Ukrainian translation
   * Updated translations:
index dd6d68354a65251f12af08635c9f9a45ca48eda2..34ee07e44ec2ad77446df83e792231e6be1f4bf5 100644 (file)
@@ -249,8 +249,6 @@ openbox_openbox_SOURCES = \
        openbox/popup.h \
        openbox/prop.c \
        openbox/prop.h \
-       openbox/propwin.c \
-       openbox/propwin.h \
        openbox/resist.c \
        openbox/resist.h \
        openbox/screen.c \
index caa38c673f7a6fa0970ef3f2a7f1d64f041caa7c..e54cb04da7f41c2dd2d0dd3004b27582f2b6ef35 100644 (file)
     <name>desktop 2</name>
     -->
   </names>
+  <popupTime>875</popupTime>
+  <!-- The number of milliseconds to show the popup for when switching
+       desktops.  Set this to 0 to disable the popup. -->
 </desktops>
 
 <resize>
   <doubleClickTime>200</doubleClickTime>
   <!-- in milliseconds (1000 = 1 second) -->
   <screenEdgeWarpTime>400</screenEdgeWarpTime>
-  <!-- time before changing desktops when the pointer touches the edge of the
-       screen while moving a window, in milliseconds (1000 = 1 second),
-       0 disables warping -->
+  <!-- Time before changing desktops when the pointer touches the edge of the
+       screen while moving a window, in milliseconds (1000 = 1 second).
+       Set this to 0 to disable warping -->
 
   <context name="Frame">
     <mousebind button="A-Left" action="Press">
index 24a0f91f7e1272d5766d822ac22b0150b537af0d..adafc5f498b528bcdbd861e45d254b9a564a1e39 100644 (file)
@@ -89,6 +89,7 @@
                 <xsd:element maxOccurs="unbounded" name="name" type="xsd:string"/>
             </xsd:complexType>
         </xsd:element>
+        <xsd:element minOccurs="0" name="popupTime" type="xsd:integer"/>
     </xsd:complexType>
     <xsd:complexType name="resize">
         <xsd:element minOccurs="0" name="drawContents" type="ob:bool"/>
index d3a0d0c30edeaba16c5387053400328d1b8ca906..75949be2e5fc2d1c40622f07e87a75b676a2a461 100644 (file)
@@ -132,10 +132,8 @@ static gboolean run_func(ObActionsData *data, gpointer options)
         d = o->abs.desktop;
         break;
     case RELATIVE:
-        d = screen_cycle_desktop(o->rel.dir,
-                                 o->rel.wrap,
-                                 o->rel.linear,
-                                 FALSE, TRUE, FALSE);
+        d = screen_find_desktop(screen_desktop,
+                                o->rel.dir, o->rel.wrap, o->rel.linear);
         break;
     }
 
index 501c64dee9ac74a1f669b3f7ce48b7e9023a3a06..2e2b7011cf80a86d2d70d20313d94c1fbf0671a5 100644 (file)
@@ -57,39 +57,89 @@ static void free_func(gpointer options)
     g_free(o);
 }
 
+static gboolean do_grow(ObActionsData *data, gint x, gint y, gint w, gint h)
+{
+    gint realw, realh, lw, lh;
+
+    realw = w;
+    realh = h;
+    client_try_configure(data->client, &x, &y, &realw, &realh,
+                         &lw, &lh, TRUE);
+    /* if it's going to be resized smaller than it intended, don't
+       move the window over */
+    if (x != data->client->area.x) x += w - realw;
+    if (y != data->client->area.y) y += h - realh;
+
+    if (x != data->client->area.x || y != data->client->area.y ||
+        realw != data->client->area.width ||
+        realh != data->client->area.height)
+    {
+        actions_client_move(data, TRUE);
+        client_move_resize(data->client, x, y, realw, realh);
+        actions_client_move(data, FALSE);
+        return TRUE;
+    }
+    return FALSE;
+}
+
 /* Always return FALSE because its not interactive */
 static gboolean run_func(ObActionsData *data, gpointer options)
 {
     Options *o = options;
+    gint x, y, w, h;
+    ObDirection opp;
+    gint half;
 
-    if (data->client) {
-        gint x, y, w, h, realw, realh, lw, lh;
-
+    if (!data->client ||
         /* don't allow vertical resize if shaded */
-        if (o->dir != OB_DIRECTION_NORTH || o->dir != OB_DIRECTION_SOUTH ||
-            !data->client->shaded)
-        {
-            client_find_resize_directional(data->client, o->dir, TRUE,
-                                           &x, &y, &w, &h);
-            realw = w;
-            realh = h;
-            client_try_configure(data->client, &x, &y, &realw, &realh,
-                                 &lw, &lh, TRUE);
-            /* if it's going to be resized smaller than it intended, don't
-               move the window over */
-            if (x != data->client->area.x) x += w - realw;
-            if (y != data->client->area.y) y += h - realh;
-
-            if (x != data->client->area.x || y != data->client->area.y ||
-                w != data->client->area.width ||
-                h != data->client->area.height)
-            {
-                actions_client_move(data, TRUE);
-                client_move_resize(data->client, x, y, realw, realh);
-                actions_client_move(data, FALSE);
-            }
+        ((o->dir == OB_DIRECTION_NORTH || o->dir == OB_DIRECTION_SOUTH) &&
+         data->client->shaded))
+    {
+        return FALSE;
+    }
+
+    /* try grow */
+    client_find_resize_directional(data->client, o->dir, TRUE,
+                                   &x, &y, &w, &h);
+    if (do_grow(data, x, y, w, h))
+        return FALSE;
+
+    /* we couldn't grow, so try shrink! */
+    opp = (o->dir == OB_DIRECTION_NORTH ? OB_DIRECTION_SOUTH :
+           (o->dir == OB_DIRECTION_SOUTH ? OB_DIRECTION_NORTH :
+            (o->dir == OB_DIRECTION_EAST ? OB_DIRECTION_WEST :
+             OB_DIRECTION_EAST)));
+    client_find_resize_directional(data->client, opp, FALSE,
+                                   &x, &y, &w, &h);
+    switch (opp) {
+    case OB_DIRECTION_NORTH:
+        half = data->client->area.y + data->client->area.height / 2;
+        if (y > half) {
+            h += y - half;
+            y = half;
+        }
+        break;
+    case OB_DIRECTION_SOUTH:
+        half = data->client->area.height / 2;
+        if (h < half)
+            h = half;
+        break;
+    case OB_DIRECTION_WEST:
+        half = data->client->area.x + data->client->area.width / 2;
+        if (x > half) {
+            w += x - half;
+            x = half;
         }
+        break;
+    case OB_DIRECTION_EAST:
+        half = data->client->area.width / 2;
+        if (w < half)
+            w = half;
+        break;
+    default: g_assert_not_reached();
     }
+    if (do_grow(data, x, y, w, h))
+        return FALSE;
 
     return FALSE;
 }
index f7f1dfc0bb40f954b8496990bdeaf4603465b757..fff0a87f8558a09c56ef2276de4880e4769eec89 100644 (file)
@@ -25,7 +25,9 @@ static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
 
     o = g_new0(Options, 1);
 
-    if ((n = parse_find_node("execute", node))) {
+    if ((n = parse_find_node("command", node)) ||
+        (n = parse_find_node("execute", node)))
+    {
         gchar *s = parse_string(doc, n);
         o->cmd = parse_expand_tilde(s);
         g_free(s);
index 70384f4d2528b4016174aaeedf4bccb6f0196555..0527d2a06d6dd7e986f3d488d9df5d79338fb313 100644 (file)
@@ -12,6 +12,6 @@ void action_unfocus_startup()
 static gboolean run_func(ObActionsData *data, gpointer options)
 {
     if (data->client && data->client == focus_client)
-        focus_fallback(FALSE, FALSE, TRUE);
+        focus_fallback(FALSE, FALSE, TRUE, FALSE);
     return FALSE;
 }
index a7b616d22eb2f5fd7db0ff62497db7d4a9dfb363..f97bd43062d97b4168d66a606ab2df776278db66 100644 (file)
@@ -32,7 +32,6 @@
 #include "event.h"
 #include "grab.h"
 #include "focus.h"
-#include "propwin.h"
 #include "stacking.h"
 #include "openbox.h"
 #include "group.h"
@@ -213,8 +212,9 @@ void client_manage(Window window)
     XWMHints *wmhint;
     gboolean activate = FALSE;
     ObAppSettings *settings;
-    gint placex, placey, placew, placeh;
     gboolean transient = FALSE;
+    Rect place, *monitor;
+    Time launch_time, map_time;
 
     grab_server(TRUE);
 
@@ -253,6 +253,8 @@ void client_manage(Window window)
 
     ob_debug("Managing window: 0x%lx\n", window);
 
+    map_time = event_get_server_time();
+
     /* choose the events we want to receive on the CLIENT window */
     attrib_set.event_mask = CLIENT_EVENTMASK;
     attrib_set.do_not_propagate_mask = CLIENT_NOPROPAGATEMASK;
@@ -269,7 +271,6 @@ void client_manage(Window window)
     self->wmstate = WithdrawnState; /* make sure it gets updated first time */
     self->gravity = NorthWestGravity;
     self->desktop = screen_num_desktops; /* always an invalid value */
-    self->user_time = focus_client ? focus_client->user_time : CurrentTime;
 
     /* get all the stuff off the window */
     client_get_all(self, TRUE);
@@ -300,10 +301,8 @@ void client_manage(Window window)
     /* now we have all of the window's information so we can set this up */
     client_setup_decor_and_functions(self, FALSE);
 
-    {
-        Time t = sn_app_started(self->startup_id, self->class);
-        if (t) self->user_time = t;
-    }
+    /* tell startup notification that this app started */
+    launch_time = sn_app_started(self->startup_id, self->class);
 
     /* do this after we have a frame.. it uses the frame to help determine the
        WM_STATE to apply. */
@@ -337,10 +336,8 @@ void client_manage(Window window)
     frame_adjust_client_area(self->frame);
 
     /* where the frame was placed is where the window was originally */
-    placex = self->area.x;
-    placey = self->area.y;
-    placew = self->area.width;
-    placeh = self->area.height;
+    place = self->area;
+    monitor = screen_physical_area_monitor(screen_find_monitor(&place));
 
     /* figure out placement for the window if the window is new */
     if (ob_state() == OB_STATE_RUNNING) {
@@ -350,7 +347,7 @@ void client_manage(Window window)
                    (self->positioned == USPosition ? "user specified" :
                     (self->positioned == (PPosition | USPosition) ?
                      "program + user specified" :
-                     "BADNESS !?")))), placex, placey);
+                     "BADNESS !?")))), place.x, place.y);
 
         ob_debug("Sized: %s @ %d %d\n",
                  (!self->sized ? "no" :
@@ -358,14 +355,15 @@ void client_manage(Window window)
                    (self->sized == USSize ? "user specified" :
                     (self->sized == (PSize | USSize) ?
                      "program + user specified" :
-                     "BADNESS !?")))), placew, placeh);
+                     "BADNESS !?")))), place.width, place.height);
 
         /* splash screens are also returned as TRUE for transient,
            and so will be forced on screen below */
-        transient = place_client(self, &placex, &placey, settings);
+        transient = place_client(self, &place.x, &place.y, settings);
 
         /* make sure the window is visible. */
-        client_find_onscreen(self, &placex, &placey, placew, placeh,
+        client_find_onscreen(self, &place.x, &place.y,
+                             place.width, place.height,
                              /* non-normal clients has less rules, and
                                 windows that are being restored from a
                                 session do also. we can assume you want
@@ -385,7 +383,13 @@ void client_manage(Window window)
                               (!((self->positioned & USPosition) ||
                                  (settings && settings->pos_given)) &&
                                client_normal(self) &&
-                               !self->session)));
+                               !self->session &&
+                               /* don't move oldschool fullscreen windows to
+                                  fit inside the struts (fixes Acroread, which
+                                  makes its fullscreen window fit the screen
+                                  but it is not USSize'd or USPosition'd) */
+                               !(self->decorations == 0 &&
+                                 RECT_EQUAL(place, *monitor)))));
     }
 
     /* if the window isn't user-sized, then make it fit inside
@@ -401,34 +405,34 @@ void client_manage(Window window)
         (transient ||
          (!(self->sized & USSize || self->positioned & USPosition) &&
           client_normal(self) &&
-          !self->session)))
+          !self->session &&
+          /* don't shrink oldschool fullscreen windows to fit inside the
+             struts (fixes Acroread, which makes its fullscreen window
+             fit the screen but it is not USSize'd or USPosition'd) */
+          !(self->decorations == 0 && RECT_EQUAL(place, *monitor)))))
     {
-        Rect placer;
+        Rect *a = screen_area(self->desktop, SCREEN_AREA_ONE_MONITOR, &place);
 
-        RECT_SET(placer, placex, placey, placew, placeh);
-        frame_rect_to_frame(self->frame, &placer);
+        /* get the size of the frame */
+        place.width += self->frame->size.left + self->frame->size.right;
+        place.height += self->frame->size.top + self->frame->size.bottom;
 
-        Rect *a = screen_area(self->desktop, SCREEN_AREA_ONE_MONITOR, &placer);
+        /* fit the window inside the area */
+        place.width = MIN(place.width, a->width);
+        place.height = MIN(place.height, a->height);
 
-        /* shrink by the frame's area */
-        a->width -= self->frame->size.left + self->frame->size.right;
-        a->height -= self->frame->size.top + self->frame->size.bottom;
+        ob_debug("setting window size to %dx%d\n", place.width, place.height);
 
-        /* fit the window inside the area */
-        if (placew > a->width || self->area.height > a->height) {
-            placew = MIN(self->area.width, a->width);
-            placeh = MIN(self->area.height, a->height);
+        /* get the size of the client back */
+        place.width -= self->frame->size.left + self->frame->size.right;
+        place.height -= self->frame->size.top + self->frame->size.bottom;
 
-            ob_debug("setting window size to %dx%d\n",
-                     self->area.width, self->area.height);
-        }
         g_free(a);
     }
 
-
     ob_debug("placing window 0x%x at %d, %d with size %d x %d. "
              "some restrictions may apply\n",
-             self->window, placex, placey, placew, placeh);
+             self->window, place.x, place.y, place.width, place.height);
     if (self->session)
         ob_debug("  but session requested %d, %d  %d x %d instead, "
                  "overriding\n",
@@ -440,20 +444,25 @@ void client_manage(Window window)
 
        this also places the window
     */
-    client_apply_startup_state(self, placex, placey, placew, placeh);
+    client_apply_startup_state(self, place.x, place.y,
+                               place.width, place.height);
+
+    g_free(monitor);
+    monitor = NULL;
 
     if (activate) {
-        guint32 last_time = focus_client ?
-            focus_client->user_time : CurrentTime;
+        gboolean raise = FALSE;
 
         /* This is focus stealing prevention */
         ob_debug_type(OB_DEBUG_FOCUS,
-                      "Want to focus new window 0x%x with time %u "
-                      "(last time %u)\n",
-                      self->window, self->user_time, last_time);
+                      "Want to focus new window 0x%x at time %u "
+                      "launched at %u (last user interaction time %u)\n",
+                      self->window, map_time, launch_time,
+                      event_last_user_time);
 
         if (menu_frame_visible || moveresize_in_progress) {
             activate = FALSE;
+            raise = TRUE;
             ob_debug_type(OB_DEBUG_FOCUS,
                           "Not focusing the window because the user is inside "
                           "an Openbox menu or is move/resizing a window and "
@@ -462,12 +471,13 @@ 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 */
-            self->user_time && screen_desktop_user_time &&
-            !event_time_after(self->user_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;
             ob_debug_type(OB_DEBUG_FOCUS,
                           "Not focusing the window because its on another "
                           "desktop\n");
@@ -476,26 +486,25 @@ void client_manage(Window window)
         else if (focus_client && client_search_focus_tree_full(self) == NULL &&
                  client_search_focus_group_full(self) == NULL)
         {
-            /* If time stamp is old, don't steal focus */
-            if (self->user_time && last_time &&
-                !event_time_after(self->user_time, last_time))
+            /* If the user is working in another window right now, then don't
+               steal focus */
+            if (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,
+                                 map_time - OB_EVENT_USER_TIME_DELAY))
             {
                 activate = FALSE;
                 ob_debug_type(OB_DEBUG_FOCUS,
-                              "Not focusing the window because the time is "
-                              "too old\n");
+                              "Not focusing the window because the user is "
+                              "working in another window\n");
             }
-            /* If its a transient (and parents aren't focused) and the time
-               is ambiguous (either the current focus target doesn't have
-               a timestamp, or they are the same (we probably inherited it
-               from them) */
-            else if (client_has_parent(self) &&
-                     (!last_time || self->user_time == last_time))
-            {
+            /* If its a transient (and its parents aren't focused) */
+            else if (client_has_parent(self)) {
                 activate = FALSE;
                 ob_debug_type(OB_DEBUG_FOCUS,
                               "Not focusing the window because it is a "
-                              "transient, and the time is very ambiguous\n");
+                              "transient, and its relatives aren't focused\n");
             }
             /* Don't steal focus from globally active clients.
                I stole this idea from KWin. It seems nice.
@@ -512,20 +521,33 @@ void client_manage(Window window)
                anyway */
             else if (client_focus_target(self) != self) {
                 activate = FALSE;
+                raise = TRUE;
                 ob_debug_type(OB_DEBUG_FOCUS,
                               "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) {
             ob_debug_type(OB_DEBUG_FOCUS,
-                          "Focus stealing prevention activated for %s with "
-                          "time %u (last time %u)\n",
-                          self->title, self->user_time, last_time);
+                          "Focus stealing prevention activated for %s at "
+                          "time %u (last user interactioon time %u)\n",
+                          self->title, map_time, event_last_user_time);
             /* if the client isn't focused, then hilite it so the user
                knows it is there */
             client_hilite(self, TRUE);
+            /* we may want to raise it even tho we're not activating it */
+            if (raise && !client_restore_session_stacking(self))
+                stacking_raise(CLIENT_AS_WINDOW(self));
         }
     }
     else {
@@ -653,9 +675,6 @@ void client_unmanage(ObClient *self)
     /* remove the window from our save set */
     XChangeSaveSet(ob_display, self->window, SetModeDelete);
 
-    /* kill the property windows */
-    propwin_remove(self->user_time_window, OB_PROPWIN_USER_TIME, self);
-
     /* update the focus lists */
     focus_order_remove(self);
     if (client_focused(self)) {
@@ -1095,9 +1114,6 @@ static void client_get_all(ObClient *self, gboolean real)
     client_get_colormap(self);
     client_update_strut(self);
     client_update_icons(self);
-    client_update_user_time_window(self);
-    if (!self->user_time_window) /* check if this would have been called */
-        client_update_user_time(self);
     client_update_icon_geometry(self);
 }
 
@@ -2098,62 +2114,6 @@ void client_update_icons(ObClient *self)
         frame_adjust_icon(self->frame);
 }
 
-void client_update_user_time(ObClient *self)
-{
-    guint32 time;
-    gboolean got = FALSE;
-
-    if (self->user_time_window)
-        got = PROP_GET32(self->user_time_window,
-                         net_wm_user_time, cardinal, &time);
-    if (!got)
-        got = PROP_GET32(self->window, net_wm_user_time, cardinal, &time);
-
-    if (got) {
-        /* we set this every time, not just when it grows, because in practice
-           sometimes time goes backwards! (ntpdate.. yay....) so.. if it goes
-           backward we don't want all windows to stop focusing. we'll just
-           assume noone is setting times older than the last one, cuz that
-           would be pretty stupid anyways
-        */
-        self->user_time = time;
-
-        /*ob_debug("window %s user time %u\n", self->title, time);*/
-    }
-}
-
-void client_update_user_time_window(ObClient *self)
-{
-    guint32 w;
-
-    if (!PROP_GET32(self->window, net_wm_user_time_window, window, &w))
-        w = None;
-
-    if (w != self->user_time_window) {
-        /* remove the old window */
-        propwin_remove(self->user_time_window, OB_PROPWIN_USER_TIME, self);
-        self->user_time_window = None;
-
-        if (self->group && self->group->leader == w) {
-            ob_debug_type(OB_DEBUG_APP_BUGS, "Window is setting its "
-                          "_NET_WM_USER_TYPE_WINDOW to its group leader\n");
-            /* do it anyways..? */
-        }
-        else if (w == self->window) {
-            ob_debug_type(OB_DEBUG_APP_BUGS, "Window is setting its "
-                          "_NET_WM_USER_TIME_WINDOW to itself\n");
-            w = None; /* don't do it */
-        }
-
-        /* add the new window */
-        propwin_add(w, OB_PROPWIN_USER_TIME, self);
-        self->user_time_window = w;
-
-        /* and update from it */
-        client_update_user_time(self);
-    }
-}
-
 void client_update_icon_geometry(ObClient *self)
 {
     guint num;
@@ -3635,34 +3595,7 @@ static void client_present(ObClient *self, gboolean here, gboolean raise,
 void client_activate(ObClient *self, gboolean here, gboolean raise,
                      gboolean unshade, gboolean user)
 {
-    guint32 last_time = focus_client ? focus_client->user_time : CurrentTime;
-    gboolean allow = FALSE;
-
-    /* if the currently focused app doesn't set a user_time, then it can't
-       benefit from any focus stealing prevention.
-
-       if the timestamp is missing in the request then let it go through
-       even if it is source=app, because EVERY APPLICATION DOES THIS because
-       GTK IS VERY BUGGY AND HARDCODES source=application... WHY!?
-    */
-    if (!last_time || !event_curtime)
-        allow = TRUE;
-    /* otherwise, if they didn't give a time stamp or if it is too old, they
-       don't get focus */
-    else
-        allow = event_time_after(event_curtime, last_time);
-
-    ob_debug_type(OB_DEBUG_FOCUS,
-                  "Want to activate window 0x%x with time %u (last time %u), "
-                  "source=%s allowing? %d\n",
-                  self->window, event_curtime, last_time,
-                  (user ? "user" : "application"), allow);
-
-    if (allow)
-        client_present(self, here, raise, unshade);
-    else
-        /* don't focus it but tell the user it wants attention */
-        client_hilite(self, TRUE);
+    client_present(self, here, raise, unshade);
 }
 
 static void client_bring_windows_recursive(ObClient *self,
@@ -3872,7 +3805,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;
@@ -3892,7 +3825,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);
@@ -3901,38 +3834,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:
@@ -3951,7 +3900,6 @@ static void detect_edge(Rect area, ObDirection dir,
         *dest = tail;
         *near_edge = FALSE;
     }
-
 }
 
 void client_find_edge_directional(ObClient *self, ObDirection dir,
@@ -3969,27 +3917,27 @@ 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))
+        if (my_head >= RECT_TOP(*mon) + 1)
             edge = RECT_TOP(*mon) - 1;
         else
             edge = RECT_TOP(*a) - 1;
         break;
     case OB_DIRECTION_SOUTH:
-        if (my_head <= RECT_BOTTOM(*mon))
+        if (my_head <= RECT_BOTTOM(*mon) - 1)
             edge = RECT_BOTTOM(*mon) + 1;
         else
             edge = RECT_BOTTOM(*a) + 1;
         break;
     case OB_DIRECTION_EAST:
-        if (my_head <= RECT_RIGHT(*mon))
+        if (my_head <= RECT_RIGHT(*mon) - 1)
             edge = RECT_RIGHT(*mon) + 1;
         else
             edge = RECT_RIGHT(*a) + 1;
         break;
     case OB_DIRECTION_WEST:
-        if (my_head >= RECT_LEFT(*mon))
+        if (my_head >= RECT_LEFT(*mon) + 1)
             edge = RECT_LEFT(*mon) - 1;
         else
             edge = RECT_LEFT(*a) - 1;
@@ -4001,7 +3949,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 */
index cba1aebbd901ee4fb12ab15e5bf8aa818b86d80c..b4b165f8035c68c61d2214b4c59fdceb387dc46d 100644 (file)
@@ -289,15 +289,9 @@ struct _ObClient
 
     /*! Where the window should iconify to/from */
     Rect icon_geometry;
-
-    /*! The time when the client last received user interaction */
-    guint32 user_time;
-    /*! A separate window for the client to update it's user_time on */
-    Window  user_time_window;
 };
 
 extern GList      *client_list;
-extern GHashTable *client_user_time_window_map;
 
 void client_startup(gboolean reconfig);
 void client_shutdown(gboolean reconfig);
@@ -606,10 +600,6 @@ void client_update_title(ObClient *self);
 void client_update_strut(ObClient *self);
 /*! Updates the window's icons */
 void client_update_icons(ObClient *self);
-/*! Updates the window's user time */
-void client_update_user_time(ObClient *self);
-/*! Updates the window's user time window */
-void client_update_user_time_window(ObClient *self);
 /*! Updates the window's icon geometry (where to iconify to/from) */
 void client_update_icon_geometry(ObClient *self);
 
index 556245df3981970e61471c1248478924d1680afa..bb4921909fea315665d051937cc5c51e4a08c846 100644 (file)
@@ -32,7 +32,7 @@
 
 ObMenu *combined_menu;
 
-#define CLIENT -1
+#define SEPARATOR -1
 #define ADD_DESKTOP -2
 #define REMOVE_DESKTOP -3
 
@@ -49,7 +49,7 @@ static gboolean self_update(ObMenuFrame *frame, gpointer data)
         gboolean empty = TRUE;
         gboolean onlyiconic = TRUE;
 
-        menu_add_separator(menu, CLIENT, screen_desktop_names[desktop]);
+        menu_add_separator(menu, SEPARATOR, screen_desktop_names[desktop]);
         for (it = focus_order; it; it = g_list_next(it)) {
             ObClient *c = it->data;
             if (client_normal(c) && (!c->skip_taskbar || c->iconic) &&
@@ -61,11 +61,11 @@ static gboolean self_update(ObMenuFrame *frame, gpointer data)
 
                 if (c->iconic) {
                     gchar *title = g_strdup_printf("(%s)", c->icon_title);
-                    e = menu_add_normal(menu, CLIENT, title, NULL, FALSE);
+                    e = menu_add_normal(menu, desktop, title, NULL, FALSE);
                     g_free(title);
                 } else {
                     onlyiconic = FALSE;
-                    e = menu_add_normal(menu, CLIENT, c->title, NULL, FALSE);
+                    e = menu_add_normal(menu, desktop, c->title, NULL, FALSE);
                 }
 
                 if (config_menu_client_list_icons
@@ -87,7 +87,7 @@ static gboolean self_update(ObMenuFrame *frame, gpointer data)
             /* no entries or only iconified windows, so add a
              * way to go to this desktop without uniconifying a window */
             if (!empty)
-                menu_add_separator(menu, CLIENT, NULL);
+                menu_add_separator(menu, SEPARATOR, NULL);
 
             e = menu_add_normal(menu, desktop, _("Go there..."), NULL, TRUE);
             if (desktop == screen_desktop)
@@ -95,7 +95,7 @@ static gboolean self_update(ObMenuFrame *frame, gpointer data)
         }
     }
 
-    menu_add_separator(menu, CLIENT, _("Manage desktops"));
+    menu_add_separator(menu, SEPARATOR, _("Manage desktops"));
     menu_add_normal(menu, ADD_DESKTOP, _("_Add new desktop"), NULL, TRUE);
     menu_add_normal(menu, REMOVE_DESKTOP, _("_Remove last desktop"),
                     NULL, TRUE);
@@ -106,11 +106,7 @@ static gboolean self_update(ObMenuFrame *frame, gpointer data)
 static void menu_execute(ObMenuEntry *self, ObMenuFrame *f,
                          ObClient *c, guint state, gpointer data)
 {
-    if (self->id == CLIENT) {
-        if (self->data.normal.data) /* it's set to NULL if its destroyed */
-            client_activate(self->data.normal.data, FALSE, TRUE, TRUE, TRUE);
-    }
-    else if (self->id == ADD_DESKTOP) {
+    if (self->id == ADD_DESKTOP) {
         screen_add_desktop(FALSE);
         menu_frame_hide_all();
     }
@@ -118,8 +114,18 @@ static void menu_execute(ObMenuEntry *self, ObMenuFrame *f,
         screen_remove_desktop(FALSE);
         menu_frame_hide_all();
     }
-    else
-        screen_set_desktop(self->id, TRUE);
+    else {
+        ObClient *t = self->data.normal.data;
+        if (t) { /* it's set to NULL if its destroyed */
+            client_activate(t, FALSE, TRUE, TRUE, TRUE);
+            /* if the window is omnipresent then we need to go to its
+               desktop */
+            if (t->desktop == DESKTOP_ALL)
+                screen_set_desktop(self->id, FALSE);
+        }
+        else
+            screen_set_desktop(self->id, TRUE);
+    }
 }
 
 static void client_dest(ObClient *client, gpointer data)
index 25bb623054971d341b1bfc6b2145fc004b640978..5f6a832d0952208c93da24df4f06aaa00d14b0bf 100644 (file)
@@ -37,7 +37,7 @@ typedef struct
     guint desktop;
 } DesktopData;
 
-#define CLIENT -1
+#define SEPARATOR -1
 #define ADD_DESKTOP -2
 #define REMOVE_DESKTOP -3
 
@@ -63,11 +63,11 @@ static gboolean desk_menu_update(ObMenuFrame *frame, gpointer data)
 
             if (c->iconic) {
                 gchar *title = g_strdup_printf("(%s)", c->icon_title);
-                e = menu_add_normal(menu, CLIENT, title, NULL, FALSE);
+                e = menu_add_normal(menu, d->desktop, title, NULL, FALSE);
                 g_free(title);
             } else {
                 onlyiconic = FALSE;
-                e = menu_add_normal(menu, CLIENT, c->title, NULL, FALSE);
+                e = menu_add_normal(menu, d->desktop, c->title, NULL, FALSE);
             }
 
             if (config_menu_client_list_icons
@@ -88,7 +88,7 @@ static gboolean desk_menu_update(ObMenuFrame *frame, gpointer data)
         /* no entries or only iconified windows, so add a
          * way to go to this desktop without uniconifying a window */
         if (!empty)
-            menu_add_separator(menu, CLIENT, NULL);
+            menu_add_separator(menu, SEPARATOR, NULL);
 
         e = menu_add_normal(menu, d->desktop, _("Go there..."), NULL, TRUE);
         if (d->desktop == screen_desktop)
@@ -101,9 +101,13 @@ static gboolean desk_menu_update(ObMenuFrame *frame, gpointer data)
 static void desk_menu_execute(ObMenuEntry *self, ObMenuFrame *f,
                               ObClient *c, guint state, gpointer data)
 {
-    if (self->id == CLIENT) {
-        if (self->data.normal.data) /* it's set to NULL if its destroyed */
-            client_activate(self->data.normal.data, FALSE, TRUE, TRUE, TRUE);
+    ObClient *t = self->data.normal.data;
+    if (t) { /* it's set to NULL if its destroyed */
+        client_activate(t, FALSE, TRUE, TRUE, TRUE);
+        /* if the window is omnipresent then we need to go to its
+           desktop */
+        if (t->desktop == DESKTOP_ALL)
+            screen_set_desktop(self->id, FALSE);
     }
     else
         screen_set_desktop(self->id, TRUE);
@@ -148,7 +152,7 @@ static gboolean self_update(ObMenuFrame *frame, gpointer data)
         desktop_menus = g_slist_append(desktop_menus, submenu);
     }
 
-    menu_add_separator(menu, CLIENT, NULL);
+    menu_add_separator(menu, SEPARATOR, NULL);
     menu_add_normal(menu, ADD_DESKTOP, _("_Add new desktop"), NULL, TRUE);
     menu_add_normal(menu, REMOVE_DESKTOP, _("_Remove last desktop"),
                     NULL, TRUE);
index 43f98c74cdf75758b2aa080df583b07d957c4df6..203d93aca1a381b161385feda9edc82e4d0e2b31 100644 (file)
@@ -377,6 +377,10 @@ void client_menu_startup()
     menu_set_place_func(menu, client_menu_place);
     menu_set_execute_func(menu, client_menu_execute);
 
+    menu_add_submenu(menu, CLIENT_SEND_TO, SEND_TO_MENU_NAME);
+
+    menu_add_submenu(menu, CLIENT_LAYER, LAYER_MENU_NAME);
+
     e = menu_add_normal(menu, CLIENT_RESTORE, _("R_estore"), NULL, TRUE);
     e->data.normal.mask = ob_rr_theme->max_toggled_mask;
     e->data.normal.mask_normal_color = ob_rr_theme->menu_color;
@@ -411,12 +415,6 @@ void client_menu_startup()
 
     menu_add_separator(menu, -1, NULL);
 
-    menu_add_submenu(menu, CLIENT_SEND_TO, SEND_TO_MENU_NAME);
-
-    menu_add_submenu(menu, CLIENT_LAYER, LAYER_MENU_NAME);
-
-    menu_add_separator(menu, -1, NULL);
-
     e = menu_add_normal(menu, CLIENT_CLOSE, _("_Close"), NULL, TRUE);
     e->data.normal.mask = ob_rr_theme->close_mask;
     e->data.normal.mask_normal_color = ob_rr_theme->menu_color;
index 0d6efc9250e5d83ef790b94accd2a38c5988906b..2bdd1966ef4012297e8c19f2fe15ecfa87cf8558 100644 (file)
@@ -57,6 +57,7 @@ RrFont *config_font_osd;
 gint    config_desktops_num;
 GSList *config_desktops_names;
 guint   config_screen_firstdesk;
+guint   config_desktop_popup_time;
 
 gboolean config_resize_redraw;
 gboolean config_resize_four_corners;
@@ -478,7 +479,7 @@ static void parse_focus(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
     if ((n = parse_find_node("followMouse", node)))
         config_focus_follow = parse_bool(doc, n);
     if ((n = parse_find_node("focusDelay", node)))
-        config_focus_delay = parse_int(doc, n) * 1000;
+        config_focus_delay = parse_int(doc, n);
     if ((n = parse_find_node("raiseOnFocus", node)))
         config_focus_raise = parse_bool(doc, n);
     if ((n = parse_find_node("focusLast", node)))
@@ -634,6 +635,8 @@ static void parse_desktops(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
             nname = parse_find_node("name", nname->next);
         }
     }
+    if ((n = parse_find_node("popupTime", node)))
+        config_desktop_popup_time = parse_int(doc, n);
 }
 
 static void parse_resize(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
@@ -724,9 +727,9 @@ static void parse_dock(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
     if ((n = parse_find_node("autoHide", node)))
         config_dock_hide = parse_bool(doc, n);
     if ((n = parse_find_node("hideDelay", node)))
-        config_dock_hide_delay = parse_int(doc, n) * 1000;
+        config_dock_hide_delay = parse_int(doc, n);
     if ((n = parse_find_node("showDelay", node)))
-        config_dock_show_delay = parse_int(doc, n) * 1000;
+        config_dock_show_delay = parse_int(doc, n);
     if ((n = parse_find_node("moveButton", node))) {
         gchar *str = parse_string(doc, n);
         guint b, s;
@@ -900,6 +903,7 @@ void config_startup(ObParseInst *i)
     config_desktops_num = 4;
     config_screen_firstdesk = 1;
     config_desktops_names = NULL;
+    config_desktop_popup_time = 875;
 
     parse_register(i, "desktops", parse_desktops, NULL);
 
index 42bf35346770964de08b3774ce3c75d36174ad2b..9d0602e28b13b62630c742a146cf949ff584f370 100644 (file)
@@ -64,7 +64,7 @@ struct _ObAppSettings
 extern gboolean config_focus_new;
 /*! Focus windows when the mouse enters them */
 extern gboolean config_focus_follow;
-/*! Timeout for focusing windows on focus follows mouse, in microseconds */
+/*! Timeout for focusing windows on focus follows mouse, in milliseconds */
 extern guint    config_focus_delay;
 /*! If windows should automatically be raised when they are focused in
  focus follows mouse */
@@ -109,9 +109,9 @@ extern gint config_dock_y;
 extern ObOrientation config_dock_orient;
 /*! Whether to auto-hide the dock when the pointer is not over it */
 extern gboolean config_dock_hide;
-/*! The number of microseconds to wait before hiding the dock */
+/*! The number of milliseconds to wait before hiding the dock */
 extern guint config_dock_hide_delay;
-/*! The number of microseconds to wait before showing the dock */
+/*! The number of milliseconds to wait before showing the dock */
 extern guint config_dock_show_delay;
 /*! The mouse button to be used to move dock apps */
 extern guint config_dock_app_move_button;
@@ -145,6 +145,8 @@ extern gint config_desktops_num;
 extern guint config_screen_firstdesk;
 /*! Names for the desktops */
 extern GSList *config_desktops_names;
+/*! Amount of time to show the desktop switch dialog */
+extern guint config_desktop_popup_time;
 
 /*! The keycode of the key combo which resets the keybaord chains */
 extern guint config_keyboard_reset_keycode;
@@ -165,11 +167,11 @@ extern gint config_resist_win;
 /*! Number of pixels to resist while crossing a screen's edge */
 extern gint config_resist_edge;
 
-/*! delay for hiding menu when opening */
+/*! Delay for hiding menu when opening in milliseconds */
 extern guint    config_menu_hide_delay;
 /*! Center menus vertically about the parent entry */
 extern gboolean config_menu_middle;
-/*! delay before opening a submenu */
+/*! Delay before opening a submenu in milliseconds */
 extern guint    config_submenu_show_delay;
 /*! show icons in client_list_menu */
 extern gboolean config_menu_client_list_icons;
index 990c8208406b7f2838051bb2ea01e8a4786fe663..3b32758afc0d5fba131a0024d2628dd9cd5858b3 100644 (file)
@@ -30,6 +30,8 @@
 #define DOCK_EVENT_MASK (ButtonPressMask | ButtonReleaseMask | \
                          EnterWindowMask | LeaveWindowMask)
 #define DOCKAPP_EVENT_MASK (StructureNotifyMask)
+#define DOCK_NOPROPAGATEMASK (ButtonPressMask | ButtonReleaseMask | \
+                              ButtonMotionMask)
 
 static ObDock *dock;
 
@@ -83,11 +85,13 @@ void dock_startup(gboolean reconfig)
 
     attrib.event_mask = DOCK_EVENT_MASK;
     attrib.override_redirect = True;
+    attrib.do_not_propagate_mask = DOCK_NOPROPAGATEMASK;
     dock->frame = XCreateWindow(ob_display, RootWindow(ob_display, ob_screen),
                                 0, 0, 1, 1, 0,
                                 RrDepth(ob_rr_inst), InputOutput,
                                 RrVisual(ob_rr_inst),
-                                CWOverrideRedirect | CWEventMask,
+                                CWOverrideRedirect | CWEventMask |
+                                CWDontPropagate,
                                 &attrib);
     dock->a_frame = RrAppearanceCopy(ob_rr_theme->osd_hilite_bg);
     XSetWindowBorder(ob_display, dock->frame,
@@ -624,15 +628,17 @@ void dock_hide(gboolean hide)
 {
     if (!hide) {
         if (dock->hidden && config_dock_hide) {
-            ob_main_loop_timeout_add(ob_main_loop, config_dock_show_delay,
-                                 show_timeout, NULL, g_direct_equal, NULL);
+            ob_main_loop_timeout_add(ob_main_loop,
+                                     config_dock_show_delay * 1000,
+                                     show_timeout, NULL, g_direct_equal, NULL);
         } else if (!dock->hidden && config_dock_hide) {
             ob_main_loop_timeout_remove(ob_main_loop, hide_timeout);
         }
     } else {
         if (!dock->hidden && config_dock_hide) {
-            ob_main_loop_timeout_add(ob_main_loop, config_dock_hide_delay,
-                                 hide_timeout, NULL, g_direct_equal, NULL);
+            ob_main_loop_timeout_add(ob_main_loop,
+                                     config_dock_hide_delay * 1000,
+                                     hide_timeout, NULL, g_direct_equal, NULL);
         } else if (dock->hidden && config_dock_hide) {
             ob_main_loop_timeout_remove(ob_main_loop, show_timeout);
         }
index 746be2c4f7aa4e7016cc6a228fea8304bfc2764d..9c47c04a3a49e42290a94bfea25dd6ba4adb122c 100644 (file)
@@ -34,7 +34,6 @@
 #include "menuframe.h"
 #include "keyboard.h"
 #include "modkeys.h"
-#include "propwin.h"
 #include "mouse.h"
 #include "mainloop.h"
 #include "focus.h"
@@ -90,7 +89,6 @@ static gboolean event_handle_menu(XEvent *e);
 static void event_handle_dock(ObDock *s, XEvent *e);
 static void event_handle_dockapp(ObDockApp *app, XEvent *e);
 static void event_handle_client(ObClient *c, XEvent *e);
-static void event_handle_user_time_window_clients(GSList *l, XEvent *e);
 static void event_handle_user_input(ObClient *client, XEvent *e);
 static gboolean is_enter_focus_event_ignored(XEvent *e);
 
@@ -99,8 +97,8 @@ static gboolean focus_delay_cmp(gconstpointer d1, gconstpointer d2);
 static gboolean focus_delay_func(gpointer data);
 static void focus_delay_client_dest(ObClient *client, gpointer data);
 
-/* The time for the current event being processed */
 Time event_curtime = CurrentTime;
+Time event_last_user_time = CurrentTime;
 
 static gboolean focus_left_screen = FALSE;
 /*! A list of ObSerialRanges which are to be ignored for mouse enter events */
@@ -238,15 +236,17 @@ static void event_set_curtime(XEvent *e)
         break;
     }
 
+    /* watch that if we get an event earlier than the last specified user_time,
+       which can happen if the clock goes backwards, we erase the last
+       specified user_time */
+    if (t && event_last_user_time && event_time_after(event_last_user_time, t))
+        event_last_user_time = CurrentTime;
+
     event_curtime = t;
 }
 
 static void event_hack_mods(XEvent *e)
 {
-#ifdef XKB
-    XkbStateRec xkb_state;
-#endif
-
     switch (e->type) {
     case ButtonPress:
     case ButtonRelease:
@@ -437,7 +437,6 @@ static void event_process(const XEvent *ec, gpointer data)
     ObDock *dock = NULL;
     ObDockApp *dockapp = NULL;
     ObWindow *obwin = NULL;
-    GSList *timewinclients = NULL;
     XEvent ee, *e;
     ObEventData *ed = data;
 
@@ -446,27 +445,24 @@ static void event_process(const XEvent *ec, gpointer data)
     e = &ee;
 
     window = event_get_window(e);
-    if (e->type != PropertyNotify ||
-        !(timewinclients = propwin_get_clients(window,
-                                               OB_PROPWIN_USER_TIME)))
-        if ((obwin = g_hash_table_lookup(window_map, &window))) {
-            switch (obwin->type) {
-            case Window_Dock:
-                dock = WINDOW_AS_DOCK(obwin);
-                break;
-            case Window_DockApp:
-                dockapp = WINDOW_AS_DOCKAPP(obwin);
-                break;
-            case Window_Client:
-                client = WINDOW_AS_CLIENT(obwin);
-                break;
-            case Window_Menu:
-            case Window_Internal:
-                /* not to be used for events */
-                g_assert_not_reached();
-                break;
-            }
+    if ((obwin = g_hash_table_lookup(window_map, &window))) {
+        switch (obwin->type) {
+        case Window_Dock:
+            dock = WINDOW_AS_DOCK(obwin);
+            break;
+        case Window_DockApp:
+            dockapp = WINDOW_AS_DOCKAPP(obwin);
+            break;
+        case Window_Client:
+            client = WINDOW_AS_CLIENT(obwin);
+            break;
+        case Window_Menu:
+        case Window_Internal:
+            /* not to be used for events */
+            g_assert_not_reached();
+            break;
         }
+    }
 
     event_set_curtime(e);
     event_hack_mods(e);
@@ -493,7 +489,7 @@ static void event_process(const XEvent *ec, gpointer data)
 
             focus_left_screen = FALSE;
 
-            focus_fallback(FALSE, config_focus_under_mouse, TRUE);
+            focus_fallback(FALSE, config_focus_under_mouse, TRUE, TRUE);
 
             /* We don't get a FocusOut for this case, because it's just moving
                from our Inferior up to us. This happens when iconifying a
@@ -502,10 +498,10 @@ static void event_process(const XEvent *ec, gpointer data)
             /* focus_set_client(NULL) has already been called */
             client_calc_layer(client);
         }
-        if (e->xfocus.detail == NotifyPointerRoot ||
-            e->xfocus.detail == NotifyDetailNone ||
-            e->xfocus.detail == NotifyInferior ||
-            e->xfocus.detail == NotifyNonlinear)
+        else if (e->xfocus.detail == NotifyPointerRoot ||
+                 e->xfocus.detail == NotifyDetailNone ||
+                 e->xfocus.detail == NotifyInferior ||
+                 e->xfocus.detail == NotifyNonlinear)
         {
             XEvent ce;
 
@@ -545,7 +541,8 @@ static void event_process(const XEvent *ec, gpointer data)
                 */
 
                 if (!focus_left_screen)
-                    focus_fallback(FALSE, config_focus_under_mouse, TRUE);
+                    focus_fallback(FALSE, config_focus_under_mouse,
+                                   TRUE, TRUE);
             }
         }
         else if (!client)
@@ -601,7 +598,7 @@ static void event_process(const XEvent *ec, gpointer data)
                 ob_debug_type(OB_DEBUG_FOCUS,
                               "Focus went to an unmanaged window 0x%x !\n",
                               ce.xfocus.window);
-                focus_fallback(TRUE, config_focus_under_mouse, TRUE);
+                focus_fallback(TRUE, config_focus_under_mouse, TRUE, TRUE);
             }
         }
 
@@ -611,8 +608,7 @@ static void event_process(const XEvent *ec, gpointer data)
                section or by focus_fallback */
             client_calc_layer(client);
         }
-    } else if (timewinclients)
-        event_handle_user_time_window_clients(timewinclients, e);
+    }
     else if (client)
         event_handle_client(client, e);
     else if (dockapp)
@@ -758,7 +754,7 @@ void event_enter_client(ObClient *client)
             data->time = event_curtime;
 
             ob_main_loop_timeout_add(ob_main_loop,
-                                     config_focus_delay,
+                                     config_focus_delay * 1000,
                                      focus_delay_func,
                                      data, focus_delay_cmp, focus_delay_dest);
         } else {
@@ -770,15 +766,6 @@ void event_enter_client(ObClient *client)
     }
 }
 
-static void event_handle_user_time_window_clients(GSList *l, XEvent *e)
-{
-    g_assert(e->type == PropertyNotify);
-    if (e->xproperty.atom == prop_atoms.net_wm_user_time) {
-        for (; l; l = g_slist_next(l))
-            client_update_user_time(l->data);
-    }
-}
-
 static void event_handle_client(ObClient *client, XEvent *e)
 {
     XEvent ce;
@@ -1292,8 +1279,11 @@ static void event_handle_client(ObClient *client, XEvent *e)
                        (e->xclient.data.l[0] == 2 ? "user" : "INVALID"))));
             /* XXX make use of data.l[2] !? */
             if (e->xclient.data.l[0] == 1 || e->xclient.data.l[0] == 2) {
-                event_curtime = e->xclient.data.l[1];
-                if (event_curtime == 0)
+                /* don't use the user's timestamp for client_focus, cuz if it's
+                   an old broken timestamp (happens all the time) then focus
+                   won't move even though we're trying to move it
+                  event_curtime = e->xclient.data.l[1];*/
+                if (e->xclient.data.l[1] == 0)
                     ob_debug_type(OB_DEBUG_APP_BUGS,
                                   "_NET_ACTIVE_WINDOW message for window %s is"
                                   " missing a timestamp\n", client->title);
@@ -1514,10 +1504,15 @@ static void event_handle_client(ObClient *client, XEvent *e)
             client_update_icon_geometry(client);
         }
         else if (msgtype == prop_atoms.net_wm_user_time) {
-            client_update_user_time(client);
-        }
-        else if (msgtype == prop_atoms.net_wm_user_time_window) {
-            client_update_user_time_window(client);
+            guint32 t;
+            if (client == focus_client &&
+                PROP_GET32(client->window, net_wm_user_time, cardinal, &t) &&
+                t && !event_time_after(t, e->xproperty.time) &&
+                (!event_last_user_time ||
+                 event_time_after(t, event_last_user_time)))
+            {
+                event_last_user_time = t;
+            }
         }
 #ifdef SYNC
         else if (msgtype == prop_atoms.net_wm_sync_request_counter) {
@@ -1844,6 +1839,9 @@ static gboolean focus_delay_func(gpointer data)
     ObFocusDelayData *d = data;
     Time old = event_curtime;
 
+    /* don't move focus and kill the menu or the move/resize */
+    if (menu_frame_visible || moveresize_in_progress) return FALSE;
+
     event_curtime = d->time;
     if (focus_client != d->client) {
         if (client_focus(d->client) && config_focus_raise)
@@ -1957,3 +1955,15 @@ gboolean event_time_after(Time t1, Time t2)
         /* t2 is in the first half so t1 has to come after it */
         return t1 >= t2 && t1 < (t2 + TIME_HALF);
 }
+
+Time event_get_server_time()
+{
+    /* Generate a timestamp */
+    XEvent event;
+
+    XChangeProperty(ob_display, screen_support_win,
+                    prop_atoms.wm_class, prop_atoms.string,
+                    8, PropModeAppend, NULL, 0);
+    XWindowEvent(ob_display, screen_support_win, PropertyChangeMask, &event);
+    return event.xproperty.time;
+}
index a1ccfbc603b60edcc8f9bb9631f1701855120633..65ff915bc5f76d4b7c84477ce33746cb9d7f43ec 100644 (file)
 
 struct _ObClient;
 
+/*! The amount of time before a window appears that is checked for user input
+  to determine if the user is working in another window */
+#define OB_EVENT_USER_TIME_DELAY (500) /* 0.5 seconds */
+
 /*! Time at which the last event with a timestamp occured. */
 extern Time event_curtime;
+/*! The last user-interaction time, as given by the clients */
+extern Time event_last_user_time;
 
 void event_startup(gboolean reconfig);
 void event_shutdown(gboolean reconfig);
@@ -50,4 +56,6 @@ void event_halt_focus_delay();
   comes at the same time or later than t2. */
 gboolean event_time_after(Time t1, Time t2);
 
+Time event_get_server_time();
+
 #endif
index 0dafd799b5f2d41e50ca97d295657a9141597966..b056db7e466f3cde9c6b7c7ab4f3db58a011f5ca 100644 (file)
@@ -159,7 +159,7 @@ static ObClient* focus_fallback_target(gboolean allow_refocus,
 }
 
 ObClient* focus_fallback(gboolean allow_refocus, gboolean allow_pointer,
-                         gboolean allow_omnipresent)
+                         gboolean allow_omnipresent, gboolean focus_lost)
 {
     ObClient *new;
     ObClient *old = focus_client;
@@ -167,7 +167,8 @@ ObClient* focus_fallback(gboolean allow_refocus, gboolean allow_pointer,
     /* unfocus any focused clients.. they can be focused by Pointer events
        and such, and then when we try focus them, we won't get a FocusIn
        event at all for them. */
-    focus_nothing();
+    if (focus_lost)
+        focus_nothing();
 
     new = focus_fallback_target(allow_refocus, allow_pointer,
                                 allow_omnipresent, old);
index 93fe6183171e161860545f89c47b1a80bd24d3c0..b8f899940d72047ea1c5fb9c79f4d0f5a369c0a8 100644 (file)
@@ -46,7 +46,8 @@ void focus_nothing();
 /*! Call this when you need to focus something! */
 struct _ObClient* focus_fallback(gboolean allow_refocus,
                                  gboolean allow_pointer,
-                                 gboolean allow_omnipresent);
+                                 gboolean allow_omnipresent,
+                                 gboolean focus_lost);
 
 /*! Add a new client into the focus order */
 void focus_order_add_new(struct _ObClient *c);
index cefa389e50b58d6362ccfb78020313d5cc88b929..b10f793b9de8c7d0d0b4192c832bb15ec51ad9e8 100644 (file)
@@ -130,6 +130,11 @@ ObFrame *frame_new(ObClient *client)
     self->innerright = createWindow(self->window, NULL, mask, &attrib);
     self->innerbottom = createWindow(self->window, NULL, mask, &attrib);
 
+    self->innerblb = createWindow(self->innerbottom, NULL, mask, &attrib);
+    self->innerbrb = createWindow(self->innerbottom, NULL, mask, &attrib);
+    self->innerbll = createWindow(self->innerleft, NULL, mask, &attrib);
+    self->innerbrr = createWindow(self->innerright, NULL, mask, &attrib);
+
     self->title = createWindow(self->window, NULL, mask, &attrib);
     self->titleleft = createWindow(self->window, NULL, mask, &attrib);
     self->titletop = createWindow(self->window, NULL, mask, &attrib);
@@ -388,6 +393,9 @@ void frame_adjust_area(ObFrame *self, gboolean moved,
         /* position/size and map/unmap all the windows */
 
         if (!fake) {
+            gint innercornerheight =
+                ob_rr_theme->grip_width - self->size.bottom;
+
             if (self->cbwidth_l) {
                 XMoveResizeWindow(ob_display, self->innerleft,
                                   self->size.left - self->cbwidth_l,
@@ -398,6 +406,19 @@ void frame_adjust_area(ObFrame *self, gboolean moved,
             } else
                 XUnmapWindow(ob_display, self->innerleft);
 
+            if (self->cbwidth_l && innercornerheight > 0) {
+                XMoveResizeWindow(ob_display, self->innerbll,
+                                  0,
+                                  self->client->area.height - 
+                                  (ob_rr_theme->grip_width -
+                                   self->size.bottom),
+                                  self->cbwidth_l,
+                                  ob_rr_theme->grip_width - self->size.bottom);
+
+                XMapWindow(ob_display, self->innerbll);
+            } else
+                XUnmapWindow(ob_display, self->innerbll);
+
             if (self->cbwidth_r) {
                 XMoveResizeWindow(ob_display, self->innerright,
                                   self->size.left + self->client->area.width,
@@ -408,6 +429,19 @@ void frame_adjust_area(ObFrame *self, gboolean moved,
             } else
                 XUnmapWindow(ob_display, self->innerright);
 
+            if (self->cbwidth_r && innercornerheight > 0) {
+                XMoveResizeWindow(ob_display, self->innerbrr,
+                                  0,
+                                  self->client->area.height - 
+                                  (ob_rr_theme->grip_width -
+                                   self->size.bottom),
+                                  self->cbwidth_r,
+                                  ob_rr_theme->grip_width - self->size.bottom);
+
+                XMapWindow(ob_display, self->innerbrr);
+            } else
+                XUnmapWindow(ob_display, self->innerbrr);
+
             if (self->cbwidth_t) {
                 XMoveResizeWindow(ob_display, self->innertop,
                                   self->size.left - self->cbwidth_l,
@@ -428,9 +462,26 @@ void frame_adjust_area(ObFrame *self, gboolean moved,
                                   self->cbwidth_l + self->cbwidth_r,
                                   self->cbwidth_b);
 
+                XMoveResizeWindow(ob_display, self->innerblb,
+                                  0, 0,
+                                  ob_rr_theme->grip_width + self->bwidth,
+                                  self->cbwidth_b);
+                XMoveResizeWindow(ob_display, self->innerbrb,
+                                  self->client->area.width +
+                                  self->cbwidth_l + self->cbwidth_r -
+                                  (ob_rr_theme->grip_width + self->bwidth),
+                                  0,
+                                  ob_rr_theme->grip_width + self->bwidth,
+                                  self->cbwidth_b);
+
                 XMapWindow(ob_display, self->innerbottom);
-            } else
+                XMapWindow(ob_display, self->innerblb);
+                XMapWindow(ob_display, self->innerbrb);
+            } else {
                 XUnmapWindow(ob_display, self->innerbottom);
+                XUnmapWindow(ob_display, self->innerblb);
+                XUnmapWindow(ob_display, self->innerbrb);
+            }
 
             if (self->bwidth) {
                 gint titlesides;
@@ -598,7 +649,7 @@ void frame_adjust_area(ObFrame *self, gboolean moved,
                                   self->bwidth);
                 XMoveResizeWindow(ob_display, self->rgripbottom,
                                   self->size.left + self->client->area.width +
-                                  self->size.right - self->bwidth - sidebwidth -
+                                  self->size.right - self->bwidth - sidebwidth-
                                   ob_rr_theme->grip_width,
                                   self->size.top + self->client->area.height +
                                   self->size.bottom - self->bwidth,
@@ -876,12 +927,16 @@ static void frame_adjust_cursors(ObFrame *self)
         XChangeWindowAttributes(ob_display, self->lgripleft, CWCursor, &a);
         XChangeWindowAttributes(ob_display, self->lgriptop, CWCursor, &a);
         XChangeWindowAttributes(ob_display, self->lgripbottom, CWCursor, &a);
+        XChangeWindowAttributes(ob_display, self->innerbll, CWCursor, &a);
+        XChangeWindowAttributes(ob_display, self->innerblb, CWCursor, &a);
         a.cursor = ob_cursor(r ? OB_CURSOR_SOUTHEAST : OB_CURSOR_NONE);
         XChangeWindowAttributes(ob_display, self->rgrip, CWCursor, &a);
         XChangeWindowAttributes(ob_display, self->handleright, CWCursor, &a);
         XChangeWindowAttributes(ob_display, self->rgripright, CWCursor, &a);
         XChangeWindowAttributes(ob_display, self->rgriptop, CWCursor, &a);
         XChangeWindowAttributes(ob_display, self->rgripbottom, CWCursor, &a);
+        XChangeWindowAttributes(ob_display, self->innerbrr, CWCursor, &a);
+        XChangeWindowAttributes(ob_display, self->innerbrb, CWCursor, &a);
     }
 }
 
@@ -1539,6 +1594,13 @@ void frame_rect_to_frame(ObFrame *self, Rect *r)
     frame_client_gravity(self, &r->x, &r->y);
 }
 
+void frame_rect_to_client(ObFrame *self, Rect *r)
+{
+    r->width -= self->size.left + self->size.right;
+    r->height -= self->size.top + self->size.bottom;
+    frame_frame_gravity(self, &r->x, &r->y);
+}
+
 static void flash_done(gpointer data)
 {
     ObFrame *self = data;
index edf75b059ffee51033d385505b1e4f88253945e4..3e7b2c619a0a63d67d6d40821e0689472742259e 100644 (file)
@@ -120,6 +120,10 @@ struct _ObFrame
     Window    innertop;     /*!< For drawing the inner client border */
     Window    innerright;   /*!< For drawing the inner client border */
     Window    innerbottom;  /*!< For drawing the inner client border */
+    Window    innerblb;
+    Window    innerbll;
+    Window    innerbrb;
+    Window    innerbrr;
     Window    backback;     /*!< A colored window shown while resizing */
     Window    backfront;    /*!< An undrawn-in window, to prevent flashing on
                                  unmap */
@@ -237,6 +241,10 @@ void frame_frame_gravity(ObFrame *self, gint *x, gint *y);
   for the frame, given its current decorations sizes */
 void frame_rect_to_frame(ObFrame *self, Rect *r);
 
+/*! Convert a rectangle in frame coordinates/sizes to what it would be for the
+  client, given its current decorations sizes */
+void frame_rect_to_client(ObFrame *self, Rect *r);
+
 void frame_flash_start(ObFrame *self);
 void frame_flash_stop(ObFrame *self);
 
index 8cb5910f4f32b083f86ed762da293190e7e53ed0..af6be016565332c88aac3a8f7a424db4321a4a83 100644 (file)
@@ -59,6 +59,14 @@ void framerender_frame(ObFrame *self)
         XClearWindow(ob_display, self->innerright);
         XSetWindowBackground(ob_display, self->innerbottom, px);
         XClearWindow(ob_display, self->innerbottom);
+        XSetWindowBackground(ob_display, self->innerbll, px);
+        XClearWindow(ob_display, self->innerbll);
+        XSetWindowBackground(ob_display, self->innerbrr, px);
+        XClearWindow(ob_display, self->innerbrr);
+        XSetWindowBackground(ob_display, self->innerblb, px);
+        XClearWindow(ob_display, self->innerblb);
+        XSetWindowBackground(ob_display, self->innerbrb, px);
+        XClearWindow(ob_display, self->innerbrb);
 
         px = (self->focused ?
               RrColorPixel(ob_rr_theme->frame_focused_border_color) :
index 9e8da321b2adad407012375fce99e996bdb69428..c993cfc116f9fd85d72f54933d385f7e5fd33c62 100644 (file)
 
 static void set_modkey_mask(guchar mask, KeySym sym);
 
-static XModifierKeymap *modmap;
+/* This is 8 lists of keycodes that are bound to the given mod mask.
+   If contains more than the one given to us by X cuz XKB is weird apparently.
+   We will look up all keycodes for a given keysym that is bound to the mask,
+   and add them all here.
+
+   With XKB, you can have a keycode bound to a modifier that isn't in the
+   modifier map somehow.  So this means that when we try translate from the
+   KeyRelease to a mod mask, we are unable to.  So this array stores *all*
+   the KeyCodes for each KeySym for each KeyCode bound to a mod mask.
+   Confused? Haha...
+
+   ModMask -> n KeyCodes -> n*m KeySyms (up to m for each KeyCode) ->
+     n*m*p KeyCodes (up to p for each KeySym)
+*/
+static GArray *modmap[NUM_MASKS];
 static KeySym *keymap;
 static gint min_keycode, max_keycode, keysyms_per_keycode;
 /* This is a bitmask of the different masks for each modifier key */
@@ -48,14 +62,15 @@ static gboolean hyper_l = FALSE;
 
 void modkeys_startup(gboolean reconfigure)
 {
-    gint i, j, k;
+    static XModifierKeymap *xmodmap;
+    gint i, j, k, l, m;
 
     /* reset the keys to not be bound to any masks */
     for (i = 0; i < OB_MODKEY_NUM_KEYS; ++i)
         modkeys_keys[i] = 0;
 
-    modmap = XGetModifierMapping(ob_display);
-    g_assert(modmap->max_keypermod > 0);
+    xmodmap = XGetModifierMapping(ob_display);
+    g_assert(xmodmap->max_keypermod > 0);
 
     XDisplayKeycodes(ob_display, &min_keycode, &max_keycode);
     keymap = XGetKeyboardMapping(ob_display, min_keycode,
@@ -66,17 +81,31 @@ void modkeys_startup(gboolean reconfigure)
 
     /* go through each of the modifier masks (eg ShiftMask, CapsMask...) */
     for (i = 0; i < NUM_MASKS; ++i) {
+        /* reset the modmap list */
+        modmap[i] = g_array_new(FALSE, FALSE, sizeof(KeyCode));
+
         /* go through each keycode that is bound to the mask */
-        for (j = 0; j < modmap->max_keypermod; ++j) {
+        for (j = 0; j < xmodmap->max_keypermod; ++j) {
             KeySym sym;
             /* get a keycode that is bound to the mask (i) */
-            KeyCode keycode = modmap->modifiermap[i*modmap->max_keypermod + j];
+            KeyCode keycode = xmodmap->modifiermap[i*xmodmap->max_keypermod+j];
             if (keycode) {
                 /* go through each keysym bound to the given keycode */
                 for (k = 0; k < keysyms_per_keycode; ++k) {
                     sym = keymap[(keycode-min_keycode) * keysyms_per_keycode +
                                  k];
                     if (sym != NoSymbol) {
+                        /* find all keycodes for the given keysym */
+                        for (l = min_keycode; l <= max_keycode; ++l)
+                            for (m = 0; m < keysyms_per_keycode; ++m)
+                                if (keymap[(l-min_keycode) *
+                                           keysyms_per_keycode + m] == sym)
+                                {
+                                    /* add all keycodes for the keysym to our
+                                       modmap */
+                                    g_array_append_val(modmap[i], l);
+                                }
+
                         /* bind the key to the mask (e.g. Alt_L => Mod1Mask) */
                         set_modkey_mask(nth_mask(i), sym);
                     }
@@ -89,17 +118,22 @@ void modkeys_startup(gboolean reconfigure)
     modkeys_keys[OB_MODKEY_KEY_CAPSLOCK] = LockMask;
     modkeys_keys[OB_MODKEY_KEY_SHIFT] = ShiftMask;
     modkeys_keys[OB_MODKEY_KEY_CONTROL] = ControlMask;
+
+    XFreeModifiermap(xmodmap);
 }
 
 void modkeys_shutdown(gboolean reconfigure)
 {
-    XFreeModifiermap(modmap);
+    guint i;
+
+    for (i = 0; i < NUM_MASKS; ++i)
+        g_array_free(modmap[i], TRUE);
     XFree(keymap);
 }
 
 guint modkeys_keycode_to_mask(guint keycode)
 {
-    gint i, j;
+    guint i, j;
     guint mask = 0;
 
     if (keycode == NoSymbol) return 0;
@@ -107,9 +141,9 @@ guint modkeys_keycode_to_mask(guint keycode)
     /* go through each of the modifier masks (eg ShiftMask, CapsMask...) */
     for (i = 0; i < NUM_MASKS; ++i) {
         /* go through each keycode that is bound to the mask */
-        for (j = 0; j < modmap->max_keypermod; ++j) {
+        for (j = 0; j < modmap[i]->len; ++j) {
             /* compare with a keycode that is bound to the mask (i) */
-            if (modmap->modifiermap[i*modmap->max_keypermod + j] == keycode)
+            if (g_array_index(modmap[i], KeyCode, j) == keycode)
                 mask |= nth_mask(i);
         }
     }
index dd0605c692a249da7d8443e0e4a7bb4e24d963b4..1a8550a9784d496d29fb36227114a022f1698675 100644 (file)
@@ -55,6 +55,7 @@ static gint cur_x, cur_y, cur_w, cur_h;
 static guint button;
 static guint32 corner;
 static ObDirection edge_warp_dir = -1;
+static gboolean edge_warp_odd = FALSE;
 static ObDirection key_resize_edge = -1;
 #ifdef SYNC
 static gboolean waiting_for_sync;
@@ -120,6 +121,8 @@ void moveresize_start(ObClient *c, gint x, gint y, guint b, guint32 cnr)
     ObCursor cur;
     gboolean mv = (cnr == prop_atoms.net_wm_moveresize_move ||
                    cnr == prop_atoms.net_wm_moveresize_move_keyboard);
+    gint up = 1;
+    gint left = 1;
 
     if (moveresize_in_progress || !c->frame->visible ||
         !(mv ?
@@ -127,23 +130,28 @@ void moveresize_start(ObClient *c, gint x, gint y, guint b, guint32 cnr)
           (c->functions & OB_CLIENT_FUNC_RESIZE)))
         return;
 
-    if (cnr == prop_atoms.net_wm_moveresize_size_topleft)
+    if (cnr == prop_atoms.net_wm_moveresize_size_topleft) {
         cur = OB_CURSOR_NORTHWEST;
-    else if (cnr == prop_atoms.net_wm_moveresize_size_top)
+        up = left = -1;
+    } else if (cnr == prop_atoms.net_wm_moveresize_size_top) {
         cur = OB_CURSOR_NORTH;
-    else if (cnr == prop_atoms.net_wm_moveresize_size_topright)
+        up = -1;
+    } else if (cnr == prop_atoms.net_wm_moveresize_size_topright) {
         cur = OB_CURSOR_NORTHEAST;
-    else if (cnr == prop_atoms.net_wm_moveresize_size_right)
+        up = -1;
+    } else if (cnr == prop_atoms.net_wm_moveresize_size_right)
         cur = OB_CURSOR_EAST;
     else if (cnr == prop_atoms.net_wm_moveresize_size_bottomright)
         cur = OB_CURSOR_SOUTHEAST;
     else if (cnr == prop_atoms.net_wm_moveresize_size_bottom)
         cur = OB_CURSOR_SOUTH;
-    else if (cnr == prop_atoms.net_wm_moveresize_size_bottomleft)
+    else if (cnr == prop_atoms.net_wm_moveresize_size_bottomleft) {
         cur = OB_CURSOR_SOUTHWEST;
-    else if (cnr == prop_atoms.net_wm_moveresize_size_left)
+        left = -1;
+    } else if (cnr == prop_atoms.net_wm_moveresize_size_left) {
         cur = OB_CURSOR_WEST;
-    else if (cnr == prop_atoms.net_wm_moveresize_size_keyboard)
+        left = -1;
+    } else if (cnr == prop_atoms.net_wm_moveresize_size_keyboard)
         cur = OB_CURSOR_SOUTHEAST;
     else if (cnr == prop_atoms.net_wm_moveresize_move)
         cur = OB_CURSOR_MOVE;
@@ -172,8 +180,8 @@ void moveresize_start(ObClient *c, gint x, gint y, guint b, guint32 cnr)
        friendly. you essentially start the resize in the middle of the
        increment instead of at 0, so you have to move half an increment
        either way instead of a full increment one and 1 px the other. */
-    start_x = x - (mv ? 0 : c->size_inc.width / 2);
-    start_y = y - (mv ? 0 : c->size_inc.height / 2);
+    start_x = x - (mv ? 0 : left * c->size_inc.width / 2);
+    start_y = y - (mv ? 0 : up * c->size_inc.height / 2);
     corner = cnr;
     button = b;
     key_resize_edge = -1;
@@ -476,12 +484,15 @@ static gboolean edge_warp_delay_func(gpointer data)
 {
     guint d;
 
-    d = screen_find_desktop(screen_desktop, edge_warp_dir, TRUE, FALSE);
-    if (d != screen_desktop) screen_set_desktop(d, TRUE);
-
-    edge_warp_dir = -1;
+    /* only fire every second time. so it's fast the first time, but slower
+       after that */
+    if (edge_warp_odd) {
+        d = screen_find_desktop(screen_desktop, edge_warp_dir, TRUE, FALSE);
+        if (d != screen_desktop) screen_set_desktop(d, TRUE);
+    }
+    edge_warp_odd = !edge_warp_odd;
 
-    return FALSE; /* don't repeat */
+    return TRUE; /* do repeat ! */
 }
 
 static void do_edge_warp(gint x, gint y)
@@ -515,13 +526,14 @@ static void do_edge_warp(gint x, gint y)
     }
 
     if (dir != edge_warp_dir) {
-        if (dir == (ObDirection)-1)
-            cancel_edge_warp();
-        else
+        cancel_edge_warp();
+        if (dir != (ObDirection)-1) {
+            edge_warp_odd = TRUE; /* switch on the first timeout */
             ob_main_loop_timeout_add(ob_main_loop,
                                      config_mouse_screenedgetime * 1000,
                                      edge_warp_delay_func,
                                      NULL, NULL, NULL);
+        }
         edge_warp_dir = dir;
     }
 }
index 0c758cfdf4bd4c762833522c5c12c89dfb7003ed..06afffc8264cf31b0daa5eb61b07cac5d7ffd5a5 100644 (file)
@@ -42,7 +42,6 @@
 #include "menuframe.h"
 #include "grab.h"
 #include "group.h"
-#include "propwin.h"
 #include "config.h"
 #include "mainloop.h"
 #include "gettext.h"
@@ -301,7 +300,6 @@ gint main(gint argc, gchar **argv)
             sn_startup(reconfigure);
             screen_startup(reconfigure);
             grab_startup(reconfigure);
-            propwin_startup(reconfigure);
             group_startup(reconfigure);
             client_startup(reconfigure);
             dock_startup(reconfigure);
@@ -363,7 +361,6 @@ gint main(gint argc, gchar **argv)
             dock_shutdown(reconfigure);
             client_shutdown(reconfigure);
             group_shutdown(reconfigure);
-            propwin_shutdown(reconfigure);
             grab_shutdown(reconfigure);
             screen_shutdown(reconfigure);
             focus_cycle_popup_shutdown(reconfigure);
index 6a97c36328e50b389a27489a94b1b9f1efda538f..7c20c79f81ef54b2bf47849eb52caaecc2011c34 100644 (file)
@@ -316,9 +316,9 @@ static gboolean place_nooverlap(ObClient *c, gint *x, gint *y)
 
                 if (r->width >= c->frame->area.width &&
                     r->height >= c->frame->area.height &&
-                    r->width > maxsize)
+                    r->width * r->height > maxsize)
                 {
-                    maxsize = r->width;
+                    maxsize = r->width * r->height;
                     maxit = sit;
                 }
             }
index 46d688c828dcea45235459004164c268e724ce2e..40ae6ef299b5d6af4272fe0b85adf7e40c774cbf 100644 (file)
@@ -94,7 +94,7 @@ void prop_startup()
 /*   CREATE(net_wm_pid, "_NET_WM_PID"); */
     CREATE(net_wm_allowed_actions, "_NET_WM_ALLOWED_ACTIONS");
     CREATE(net_wm_user_time, "_NET_WM_USER_TIME");
-    CREATE(net_wm_user_time_window, "_NET_WM_USER_TIME_WINDOW");
+/*    CREATE(net_wm_user_time_window, "_NET_WM_USER_TIME_WINDOW"); */
     CREATE(kde_net_wm_frame_strut, "_KDE_NET_WM_FRAME_STRUT");
     CREATE(net_frame_extents, "_NET_FRAME_EXTENTS");
 
index 914c1f61fc7e6e03c894a47df34de42111c77af9..f0c4f5e98e1ddeff67179a0a10f22049bf408848 100644 (file)
@@ -132,7 +132,7 @@ typedef struct Atoms {
 /*  Atom net_wm_pid; */
     Atom net_wm_allowed_actions;
     Atom net_wm_user_time;
-    Atom net_wm_user_time_window;
+/*  Atom net_wm_user_time_window; */
     Atom net_frame_extents;
 
     /* application protocols */
diff --git a/openbox/propwin.c b/openbox/propwin.c
deleted file mode 100644 (file)
index 774591d..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
-
-   propwin.c for the Openbox window manager
-   Copyright (c) 2006        Mikael Magnusson
-   Copyright (c) 2003-2007   Dana Jansens
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   See the COPYING file for a copy of the GNU General Public License.
-*/
-
-#include "propwin.h"
-#include "openbox.h"
-#include "client.h"
-#include "debug.h"
-
-typedef struct _ObPropWin     ObPropWin;
-typedef struct _ObPropWinData ObPropWinData;
-
-struct _ObPropWinData
-{
-    GSList *clients;
-};
-
-struct _ObPropWin
-{
-    Window win;
-    ObPropWinData data[OB_NUM_PROPWIN_TYPES];
-};
-
-/*! A hash table that maps a window to an ObPropWin */
-static GHashTable *propwin_map;
-
-static guint window_hash(Window *w) { return *w; }
-static gboolean window_comp(Window *w1, Window *w2) { return *w1 == *w2; }
-
-void propwin_startup(gboolean reconfig)
-{
-    if (!reconfig)
-        propwin_map = g_hash_table_new_full((GHashFunc)window_hash,
-                                             (GEqualFunc)window_comp,
-                                             NULL,
-                                             g_free);
-}
-
-void propwin_shutdown(gboolean reconfig)
-{
-    if (!reconfig)
-        g_hash_table_destroy(propwin_map);
-    else
-        g_assert(g_hash_table_size(propwin_map) == 0);
-}
-
-void propwin_add(Window win, ObPropWinType type, ObClient *client)
-{
-    ObPropWin *p;
-
-    if (!win) return;
-
-    g_assert(client);
-    g_assert(type < OB_NUM_PROPWIN_TYPES);
-
-    p = g_hash_table_lookup(propwin_map, &win);
-    if (!p) {
-        p = g_new0(ObPropWin, 1);
-        p->win = win;
-        g_hash_table_insert(propwin_map, &p->win, p);
-        /* get property changes on this window */
-        XSelectInput(ob_display, win, PropertyChangeMask);
-    } else
-        g_assert(g_slist_find(p->data[type].clients, client) == NULL);
-
-    if (p->data[type].clients != NULL)
-        ob_debug("Client %s is using a property window 0x%x that is already "
-                 "in use\n", client->title, win);
-
-    /* add it to the clients list */
-    p->data[type].clients = g_slist_prepend(p->data[type].clients, client);
-}
-
-void propwin_remove(Window win, ObPropWinType type, ObClient *client)
-{
-    ObPropWin *p;
-
-    if (!win) return;
-
-    p = g_hash_table_lookup(propwin_map, &win);
-    g_assert(p);
-
-    /* remove it to the clients list */
-    g_assert(g_slist_find(p->data[type].clients, client) != NULL);
-    p->data[type].clients = g_slist_remove(p->data[type].clients, client);
-
-    /* no more clients left for this type */
-    if (p->data[type].clients == NULL) {
-        guint i;
-        gboolean none = TRUE;
-
-        for (i = 0; i < OB_NUM_PROPWIN_TYPES; ++i)
-            if (p->data[i].clients != NULL)
-                none = FALSE; /* another type still has a client for this
-                                 window */
-
-        if (none) {
-            /* don't get events for this window any more */
-            XSelectInput(ob_display, win, NoEventMask);
-            g_hash_table_remove(propwin_map, &win);
-        }
-    }
-}
-
-GSList* propwin_get_clients(Window win, ObPropWinType type)
-{
-    ObPropWin *p = g_hash_table_lookup(propwin_map, &win);
-    if (p)
-        return p->data[type].clients;
-    else
-        return NULL;
-}
diff --git a/openbox/propwin.h b/openbox/propwin.h
deleted file mode 100644 (file)
index 1e014aa..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
-
-   propwin.h for the Openbox window manager
-   Copyright (c) 2007        Dana Jansens
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   See the COPYING file for a copy of the GNU General Public License.
-*/
-
-#ifndef __propwin_h
-#define __propwin_h
-
-#include <glib.h>
-#include <X11/Xlib.h>
-
-struct _ObClient;
-
-typedef enum {
-    OB_PROPWIN_USER_TIME,
-    OB_NUM_PROPWIN_TYPES
-} ObPropWinType;
-
-void propwin_startup(gboolean reconfig);
-void propwin_shutdown(gboolean reconfig);
-
-void propwin_add(Window win, ObPropWinType type, struct _ObClient *client);
-void propwin_remove(Window win, ObPropWinType type, struct _ObClient *client);
-
-GSList* propwin_get_clients(Window win, ObPropWinType type);
-
-#endif
index b8f24893e8ebd26d8b7d543e47770dd2817b6024..62c2b293f0b9fe1879df403e0c5db067c24c15ca 100644 (file)
 #include "frame.h"
 #include "stacking.h"
 #include "screen.h"
+#include "dock.h"
 #include "config.h"
 #include "parser/parse.h"
 
 #include <glib.h>
 
-void resist_move_windows(ObClient *c, gint resist, gint *x, gint *y)
+static gboolean resist_move_window(Rect window,
+                                   Rect target, gint resist,
+                                   gint *x, gint *y)
 {
-    GList *it;
     gint l, t, r, b; /* requested edges */
     gint cl, ct, cr, cb; /* current edges */
     gint w, h; /* current size */
-    ObClient *snapx = NULL, *snapy = NULL;
-
-    if (!resist) return;
-
-    frame_client_gravity(c->frame, x, y);
+    gint tl, tt, tr, tb; /* 1 past the target's edges on each side */
+    gboolean snapx = 0, snapy = 0;
 
-    w = c->frame->area.width;
-    h = c->frame->area.height;
+    w = window.width;
+    h = window.height;
 
     l = *x;
     t = *y;
     r = l + w - 1;
     b = t + h - 1;
 
-    cl = RECT_LEFT(c->frame->area);
-    ct = RECT_TOP(c->frame->area);
-    cr = RECT_RIGHT(c->frame->area);
-    cb = RECT_BOTTOM(c->frame->area);
+    cl = RECT_LEFT(window);
+    ct = RECT_TOP(window);
+    cr = RECT_RIGHT(window);
+    cb = RECT_BOTTOM(window);
+
+    tl = RECT_LEFT(target) - 1;
+    tt = RECT_TOP(target) - 1;
+    tr = RECT_RIGHT(target) + 1;
+    tb = RECT_BOTTOM(target) + 1;
+
+    /* snapx and snapy ensure that the window snaps to the top-most
+       window edge available, without going all the way from
+       bottom-to-top in the stacking list
+    */
+    if (!snapx) {
+        if (ct < tb && cb > tt) {
+            if (cl >= tr && l < tr && l >= tr - resist)
+                *x = tr, snapx = TRUE;
+            else if (cr <= tl && r > tl &&
+                     r <= tl + resist)
+                *x = tl - w + 1, snapx = TRUE;
+            if (snapx) {
+                /* try to corner snap to the window */
+                if (ct > tt && t <= tt &&
+                    t > tt - resist)
+                    *y = tt + 1, snapy = TRUE;
+                else if (cb < tb && b >= tb &&
+                         b < tb + resist)
+                    *y = tb - h, snapy = TRUE;
+            }
+        }
+    }
+    if (!snapy) {
+        if (cl < tr && cr > tl) {
+            if (ct >= tb && t < tb && t >= tb - resist)
+                *y = tb, snapy = TRUE;
+            else if (cb <= tt && b > tt &&
+                     b <= tt + resist)
+                *y = tt - h + 1, snapy = TRUE;
+            if (snapy) {
+                /* try to corner snap to the window */
+                if (cl > tl && l <= tl &&
+                    l > tl - resist)
+                    *x = tl + 1, snapx = TRUE;
+                else if (cr < tr && r >= tr &&
+                         r < tr + resist)
+                    *x = tr - w, snapx = TRUE;
+            }
+        }
+    }
+
+    return snapx && snapy;
+}
+
+void resist_move_windows(ObClient *c, gint resist, gint *x, gint *y)
+{
+    GList *it;
+    Rect dock_area;
+
+    if (!resist) return;
+
+    frame_client_gravity(c->frame, x, y);
+
 
     for (it = stacking_list; it; it = g_list_next(it)) {
         ObClient *target;
-        gint tl, tt, tr, tb; /* 1 past the target's edges on each side */
 
         if (!WINDOW_IS_CLIENT(it->data))
             continue;
         target = it->data;
 
         /* don't snap to self or non-visibles */
-        if (!target->frame->visible || target == c) continue;
+        if (!target->frame->visible || target == c)
+            continue;
         /* don't snap to windows set to below and skip_taskbar (desklets) */
-        if (target->below && !c->below && target->skip_taskbar) continue;
-
-        tl = RECT_LEFT(target->frame->area) - 1;
-        tt = RECT_TOP(target->frame->area) - 1;
-        tr = RECT_RIGHT(target->frame->area) + 1;
-        tb = RECT_BOTTOM(target->frame->area) + 1;
-
-        /* snapx and snapy ensure that the window snaps to the top-most
-           window edge available, without going all the way from
-           bottom-to-top in the stacking list
-        */
-        if (snapx == NULL) {
-            if (ct < tb && cb > tt) {
-                if (cl >= tr && l < tr && l >= tr - resist)
-                    *x = tr, snapx = target;
-                else if (cr <= tl && r > tl &&
-                         r <= tl + resist)
-                    *x = tl - w + 1, snapx = target;
-                if (snapx != NULL) {
-                    /* try to corner snap to the window */
-                    if (ct > tt && t <= tt &&
-                        t > tt - resist)
-                        *y = tt + 1, snapy = target;
-                    else if (cb < tb && b >= tb &&
-                             b < tb + resist)
-                        *y = tb - h, snapy = target;
-                }
-            }
-        }
-        if (snapy == NULL) {
-            if (cl < tr && cr > tl) {
-                if (ct >= tb && t < tb && t >= tb - resist)
-                    *y = tb, snapy = target;
-                else if (cb <= tt && b > tt &&
-                         b <= tt + resist)
-                    *y = tt - h + 1, snapy = target;
-                if (snapy != NULL) {
-                    /* try to corner snap to the window */
-                    if (cl > tl && l <= tl &&
-                        l > tl - resist)
-                        *x = tl + 1, snapx = target;
-                    else if (cr < tr && r >= tr &&
-                             r < tr + resist)
-                        *x = tr - w, snapx = target;
-                }
-            }
-        }
+        if (target->below && !c->below && target->skip_taskbar)
+            continue;
 
-        if (snapx && snapy) break;
+        if (resist_move_window(c->frame->area, target->frame->area,
+                               resist, x, y))
+            break;
     }
+    dock_get_area(&dock_area);
+    resist_move_window(c->frame->area, dock_area, resist, x, y);
 
     frame_frame_gravity(c->frame, x, y);
 }
@@ -191,101 +208,116 @@ void resist_move_monitors(ObClient *c, gint resist, gint *x, gint *y)
     frame_frame_gravity(c->frame, x, y);
 }
 
+static gboolean resist_size_window(Rect window, Rect target, gint resist,
+                                   gint *w, gint *h, ObDirection dir)
+{
+    gint l, t, r, b; /* my left, top, right and bottom sides */
+    gint tl, tt, tr, tb; /* target's left, top, right and bottom bottom sides*/
+    gint dlt, drb; /* my destination left/top and right/bottom sides */
+    gboolean snapx = 0, snapy = 0;
+    gint orgw, orgh;
+
+    l = RECT_LEFT(window);
+    t = RECT_TOP(window);
+    r = RECT_RIGHT(window);
+    b = RECT_BOTTOM(window);
+
+    orgw = window.width;
+    orgh = window.height;
+
+    tl = RECT_LEFT(target);
+    tt = RECT_TOP(target);
+    tr = RECT_RIGHT(target);
+    tb = RECT_BOTTOM(target);
+
+    if (!snapx) {
+        /* horizontal snapping */
+        if (t < tb && b > tt) {
+            switch (dir) {
+            case OB_DIRECTION_EAST:
+            case OB_DIRECTION_NORTHEAST:
+            case OB_DIRECTION_SOUTHEAST:
+            case OB_DIRECTION_NORTH:
+            case OB_DIRECTION_SOUTH:
+                dlt = l;
+                drb = r + *w - orgw;
+                if (r < tl && drb >= tl &&
+                    drb < tl + resist)
+                    *w = tl - l, snapx = TRUE;
+                break;
+            case OB_DIRECTION_WEST:
+            case OB_DIRECTION_NORTHWEST:
+            case OB_DIRECTION_SOUTHWEST:
+                dlt = l - *w + orgw;
+                drb = r;
+                if (l > tr && dlt <= tr &&
+                    dlt > tr - resist)
+                    *w = r - tr, snapx = TRUE;
+                break;
+            }
+        }
+    }
+
+    if (!snapy) {
+        /* vertical snapping */
+        if (l < tr && r > tl) {
+            switch (dir) {
+            case OB_DIRECTION_SOUTH:
+            case OB_DIRECTION_SOUTHWEST:
+            case OB_DIRECTION_SOUTHEAST:
+            case OB_DIRECTION_EAST:
+            case OB_DIRECTION_WEST:
+                dlt = t;
+                drb = b + *h - orgh;
+                if (b < tt && drb >= tt &&
+                    drb < tt + resist)
+                    *h = tt - t, snapy = TRUE;
+                break;
+            case OB_DIRECTION_NORTH:
+            case OB_DIRECTION_NORTHWEST:
+            case OB_DIRECTION_NORTHEAST:
+                dlt = t - *h + orgh;
+                drb = b;
+                if (t > tb && dlt <= tb &&
+                    dlt > tb - resist)
+                    *h = b - tb, snapy = TRUE;
+                break;
+            }
+        }
+    }
+
+    /* snapped both ways */
+    return snapx && snapy;
+}
+
 void resist_size_windows(ObClient *c, gint resist, gint *w, gint *h,
                          ObDirection dir)
 {
     GList *it;
     ObClient *target; /* target */
-    gint l, t, r, b; /* my left, top, right and bottom sides */
-    gint dlt, drb; /* my destination left/top and right/bottom sides */
-    gint tl, tt, tr, tb; /* target's left, top, right and bottom bottom sides*/
-    gint incw, inch;
-    ObClient *snapx = NULL, *snapy = NULL;
+    Rect dock_area;
 
     if (!resist) return;
 
-    incw = c->size_inc.width;
-    inch = c->size_inc.height;
-
-    l = RECT_LEFT(c->frame->area);
-    r = RECT_RIGHT(c->frame->area);
-    t = RECT_TOP(c->frame->area);
-    b = RECT_BOTTOM(c->frame->area);
-
     for (it = stacking_list; it; it = g_list_next(it)) {
         if (!WINDOW_IS_CLIENT(it->data))
             continue;
         target = it->data;
 
         /* don't snap to invisibles or ourself */
-        if (!target->frame->visible || target == c) continue;
+        if (!target->frame->visible || target == c)
+            continue;
         /* don't snap to windows set to below and skip_taskbar (desklets) */
-        if (target->below && !c->below && target->skip_taskbar) continue;
-
-        tl = RECT_LEFT(target->frame->area);
-        tr = RECT_RIGHT(target->frame->area);
-        tt = RECT_TOP(target->frame->area);
-        tb = RECT_BOTTOM(target->frame->area);
-
-        if (snapx == NULL) {
-            /* horizontal snapping */
-            if (t < tb && b > tt) {
-                switch (dir) {
-                case OB_DIRECTION_EAST:
-                case OB_DIRECTION_NORTHEAST:
-                case OB_DIRECTION_SOUTHEAST:
-                case OB_DIRECTION_NORTH:
-                case OB_DIRECTION_SOUTH:
-                    dlt = l;
-                    drb = r + *w - c->frame->area.width;
-                    if (r < tl && drb >= tl &&
-                        drb < tl + resist)
-                        *w = tl - l, snapx = target;
-                    break;
-                case OB_DIRECTION_WEST:
-                case OB_DIRECTION_NORTHWEST:
-                case OB_DIRECTION_SOUTHWEST:
-                    dlt = l - *w + c->frame->area.width;
-                    drb = r;
-                    if (l > tr && dlt <= tr &&
-                        dlt > tr - resist)
-                        *w = r - tr, snapx = target;
-                    break;
-                }
-            }
-        }
-
-        if (snapy == NULL) {
-            /* vertical snapping */
-            if (l < tr && r > tl) {
-                switch (dir) {
-                case OB_DIRECTION_SOUTH:
-                case OB_DIRECTION_SOUTHWEST:
-                case OB_DIRECTION_SOUTHEAST:
-                case OB_DIRECTION_EAST:
-                case OB_DIRECTION_WEST:
-                    dlt = t;
-                    drb = b + *h - c->frame->area.height;
-                    if (b < tt && drb >= tt &&
-                        drb < tt + resist)
-                        *h = tt - t, snapy = target;
-                    break;
-                case OB_DIRECTION_NORTH:
-                case OB_DIRECTION_NORTHWEST:
-                case OB_DIRECTION_NORTHEAST:
-                    dlt = t - *h + c->frame->area.height;
-                    drb = b;
-                    if (t > tb && dlt <= tb &&
-                        dlt > tb - resist)
-                        *h = b - tb, snapy = target;
-                    break;
-                }
-            }
-        }
+        if (target->below && !c->below && target->skip_taskbar)
+            continue;
 
-        /* snapped both ways */
-        if (snapx && snapy) break;
+        if (resist_size_window(c->frame->area, target->frame->area,
+                               resist, w, h, dir))
+            break;
     }
+    dock_get_area(&dock_area);
+    resist_size_window(c->frame->area, dock_area,
+                       resist, w, h, dir);
 }
 
 void resist_size_monitors(ObClient *c, gint resist, gint *w, gint *h,
index 9bbd13d183181208873b0769fa1957882e28babe..93ec57f53eb406971e950e7559d0fa74b1cf3bc2 100644 (file)
@@ -26,6 +26,7 @@
 #include "startupnotify.h"
 #include "moveresize.h"
 #include "config.h"
+#include "mainloop.h"
 #include "screen.h"
 #include "client.h"
 #include "session.h"
@@ -53,6 +54,7 @@
 static gboolean screen_validate_layout(ObDesktopLayout *l);
 static gboolean replace_wm();
 static void     screen_tell_ksplash();
+static void     screen_fallback_focus();
 
 guint    screen_num_desktops;
 guint    screen_num_monitors;
@@ -73,7 +75,7 @@ static GSList *struts_left = NULL;
 static GSList *struts_right = NULL;
 static GSList *struts_bottom = NULL;
 
-static ObPagerPopup *desktop_cycle_popup;
+static ObPagerPopup *desktop_popup;
 
 static gboolean replace_wm()
 {
@@ -107,22 +109,7 @@ static gboolean replace_wm()
             current_wm_sn_owner = None;
     }
 
-    {
-        /* Generate a timestamp */
-        XEvent event;
-
-        XSelectInput(ob_display, screen_support_win, PropertyChangeMask);
-
-        XChangeProperty(ob_display, screen_support_win,
-                        prop_atoms.wm_class, prop_atoms.string,
-                        8, PropModeAppend, NULL, 0);
-        XWindowEvent(ob_display, screen_support_win,
-                     PropertyChangeMask, &event);
-
-        XSelectInput(ob_display, screen_support_win, NoEventMask);
-
-        timestamp = event.xproperty.time;
-    }
+    timestamp = event_get_server_time();
 
     XSetSelectionOwner(ob_display, wm_sn_atom, screen_support_win,
                        timestamp);
@@ -172,12 +159,14 @@ gboolean screen_annex()
 
     /* create the netwm support window */
     attrib.override_redirect = TRUE;
+    attrib.event_mask = PropertyChangeMask;
     screen_support_win = XCreateWindow(ob_display,
                                        RootWindow(ob_display, ob_screen),
                                        -100, -100, 1, 1, 0,
                                        CopyFromParent, InputOutput,
                                        CopyFromParent,
-                                       CWOverrideRedirect, &attrib);
+                                       CWEventMask | CWOverrideRedirect,
+                                       &attrib);
     XMapWindow(ob_display, screen_support_win);
     XLowerWindow(ob_display, screen_support_win);
 
@@ -283,7 +272,9 @@ gboolean screen_annex()
     supported[i++] = prop_atoms.net_moveresize_window;
     supported[i++] = prop_atoms.net_wm_moveresize;
     supported[i++] = prop_atoms.net_wm_user_time;
+/*
     supported[i++] = prop_atoms.net_wm_user_time_window;
+*/
     supported[i++] = prop_atoms.net_frame_extents;
     supported[i++] = prop_atoms.net_request_frame_extents;
     supported[i++] = prop_atoms.net_restack_window;
@@ -353,12 +344,12 @@ void screen_startup(gboolean reconfig)
     guint32 d;
     gboolean namesexist = FALSE;
 
-    desktop_cycle_popup = pager_popup_new(FALSE);
-    pager_popup_height(desktop_cycle_popup, POPUP_HEIGHT);
+    desktop_popup = pager_popup_new(FALSE);
+    pager_popup_height(desktop_popup, POPUP_HEIGHT);
 
     if (reconfig) {
         /* update the pager popup's width */
-        pager_popup_text_width_to_strings(desktop_cycle_popup,
+        pager_popup_text_width_to_strings(desktop_popup,
                                           screen_desktop_names,
                                           screen_num_desktops);
         return;
@@ -441,7 +432,7 @@ void screen_startup(gboolean reconfig)
 
 void screen_shutdown(gboolean reconfig)
 {
-    pager_popup_free(desktop_cycle_popup);
+    pager_popup_free(desktop_popup);
 
     if (reconfig)
         return;
@@ -545,13 +536,52 @@ void screen_set_num_desktops(guint num)
         screen_set_desktop(num - 1, TRUE);
 }
 
-void screen_set_desktop(guint num, gboolean dofocus)
+static void screen_fallback_focus()
 {
     ObClient *c;
+    gboolean allow_omni;
+
+    /* only allow omnipresent windows to get focus on desktop change if
+       an omnipresent window is already focused (it'll keep focus probably, but
+       maybe not depending on mouse-focus options) */
+    allow_omni = focus_client && (client_normal(focus_client) &&
+                                  focus_client->desktop == DESKTOP_ALL);
+
+    /* the client moved there already so don't move focus. prevent flicker
+       on sendtodesktop + follow */
+    if (focus_client && focus_client->desktop == screen_desktop)
+        return;
+
+    /* have to try focus here because when you leave an empty desktop
+       there is no focus out to watch for. also, we have different rules
+       here. we always allow it to look under the mouse pointer if
+       config_focus_last is FALSE
+
+       do this before hiding the windows so if helper windows are coming
+       with us, they don't get hidden
+    */
+    if ((c = focus_fallback(TRUE, !config_focus_last, allow_omni,
+                            !allow_omni)))
+    {
+        /* only do the flicker reducing stuff ahead of time if we are going
+           to call xsetinputfocus on the window ourselves. otherwise there is
+           no guarantee the window will actually take focus.. */
+        if (c->can_focus) {
+            /* reduce flicker by hiliting now rather than waiting for the
+               server FocusIn event */
+            frame_adjust_focus(c->frame, TRUE);
+            /* do this here so that if you switch desktops to a window with
+               helper windows then the helper windows won't flash */
+            client_bring_helper_windows(c);
+        }
+    }
+}
+
+void screen_set_desktop(guint num, gboolean dofocus)
+{
     GList *it;
     guint old;
     gulong ignore_start;
-    gboolean allow_omni;
 
     g_assert(num < screen_num_desktops);
 
@@ -583,39 +613,7 @@ void screen_set_desktop(guint num, gboolean dofocus)
         }
     }
 
-    /* only allow omnipresent windows to get focus on desktop change if
-       an omnipresent window is already focused (it'll keep focus probably, but
-       maybe not depending on mouse-focus options) */
-    allow_omni = focus_client && (client_normal(focus_client) &&
-                                  focus_client->desktop == DESKTOP_ALL);
-
-    /* the client moved there already so don't move focus. prevent flicker
-       on sendtodesktop + follow */
-    if (focus_client && focus_client->desktop == screen_desktop)
-        dofocus = FALSE;
-
-    /* have to try focus here because when you leave an empty desktop
-       there is no focus out to watch for. also, we have different rules
-       here. we always allow it to look under the mouse pointer if
-       config_focus_last is FALSE
-
-       do this before hiding the windows so if helper windows are coming
-       with us, they don't get hidden
-    */
-    if (dofocus && (c = focus_fallback(TRUE, !config_focus_last, allow_omni)))
-    {
-        /* only do the flicker reducing stuff ahead of time if we are going
-           to call xsetinputfocus on the window ourselves. otherwise there is
-           no guarantee the window will actually take focus.. */
-        if (c->can_focus) {
-            /* reduce flicker by hiliting now rather than waiting for the
-               server FocusIn event */
-            frame_adjust_focus(c->frame, TRUE);
-            /* do this here so that if you switch desktops to a window with
-               helper windows then the helper windows won't flash */
-            client_bring_helper_windows(c);
-        }
-    }
+    if (dofocus) screen_fallback_focus();
 
     /* hide windows from bottom to top */
     for (it = g_list_last(stacking_list); it; it = g_list_previous(it)) {
@@ -629,10 +627,18 @@ void screen_set_desktop(guint num, gboolean dofocus)
 
     if (event_curtime != CurrentTime)
         screen_desktop_user_time = event_curtime;
+
+    if (ob_state() == OB_STATE_RUNNING)
+        screen_show_desktop_popup(screen_desktop);
 }
 
 void screen_add_desktop(gboolean current)
 {
+    gulong ignore_start;
+
+    /* ignore enter events caused by this */
+    ignore_start = event_start_ignore_all_enters();
+
     screen_set_num_desktops(screen_num_desktops+1);
 
     /* move all the clients over */
@@ -651,15 +657,21 @@ void screen_add_desktop(gboolean current)
             }
         }
     }
+
+    event_end_ignore_all_enters(ignore_start);
 }
 
 void screen_remove_desktop(gboolean current)
 {
     guint rmdesktop, movedesktop;
     GList *it, *stacking_copy;
+    gulong ignore_start;
 
     if (screen_num_desktops <= 1) return;
 
+    /* ignore enter events caused by this */
+    ignore_start = event_start_ignore_all_enters();
+
     /* what desktop are we removing and moving to? */
     if (current)
         rmdesktop = screen_desktop;
@@ -696,15 +708,15 @@ void screen_remove_desktop(gboolean current)
         }
     }
 
-    /* act like we're changing desktops */
+    /* fallback focus like we're changing desktops */
     if (screen_desktop < screen_num_desktops - 1) {
-        gint d = screen_desktop;
-        screen_desktop = screen_last_desktop;
-        screen_set_desktop(d, TRUE);
+        screen_fallback_focus();
         ob_debug("fake desktop change\n");
     }
 
     screen_set_num_desktops(screen_num_desktops-1);
+
+    event_end_ignore_all_enters(ignore_start);
 }
 
 static void get_row_col(guint d, guint *r, guint *c)
@@ -815,25 +827,34 @@ static guint translate_row_col(guint r, guint c)
     return 0;
 }
 
-void screen_desktop_popup(guint d, gboolean show)
+static gboolean hide_desktop_popup_func(gpointer data)
+{
+    pager_popup_hide(desktop_popup);
+    return FALSE; /* don't repeat */
+}
+
+void screen_show_desktop_popup(guint d)
 {
     Rect *a;
 
-    if (!show) {
-        pager_popup_hide(desktop_cycle_popup);
-    } else {
-        a = screen_physical_area_active();
-        pager_popup_position(desktop_cycle_popup, CenterGravity,
-                             a->x + a->width / 2, a->y + a->height / 2);
-        pager_popup_icon_size_multiplier(desktop_cycle_popup,
-                                         (screen_desktop_layout.columns /
-                                          screen_desktop_layout.rows) / 2,
-                                         (screen_desktop_layout.rows/
-                                          screen_desktop_layout.columns) / 2);
-        pager_popup_max_width(desktop_cycle_popup,
-                              MAX(a->width/3, POPUP_WIDTH));
-        pager_popup_show(desktop_cycle_popup, screen_desktop_names[d], d);
-    }
+    /* 0 means don't show the popup */
+    if (!config_desktop_popup_time) return;
+
+    a = screen_physical_area_active();
+    pager_popup_position(desktop_popup, CenterGravity,
+                         a->x + a->width / 2, a->y + a->height / 2);
+    pager_popup_icon_size_multiplier(desktop_popup,
+                                     (screen_desktop_layout.columns /
+                                      screen_desktop_layout.rows) / 2,
+                                     (screen_desktop_layout.rows/
+                                      screen_desktop_layout.columns) / 2);
+    pager_popup_max_width(desktop_popup,
+                          MAX(a->width/3, POPUP_WIDTH));
+    pager_popup_show(desktop_popup, screen_desktop_names[d], d);
+
+    ob_main_loop_timeout_remove(ob_main_loop, hide_desktop_popup_func);
+    ob_main_loop_timeout_add(ob_main_loop, config_desktop_popup_time * 1000,
+                             hide_desktop_popup_func, NULL, NULL, NULL);
 }
 
 guint screen_find_desktop(guint from, ObDirection dir,
@@ -942,30 +963,6 @@ guint screen_find_desktop(guint from, ObDirection dir,
     return d;
 }
 
-guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear,
-                           gboolean dialog, gboolean done, gboolean cancel)
-{
-    static guint d = (guint)-1;
-    guint ret;
-
-    if (d == (guint)-1)
-        d = screen_desktop;
-
-    if ((!cancel && !done) || !dialog)
-        d = screen_find_desktop(d, dir, wrap, linear);
-
-    if (dialog && !cancel && !done)
-        screen_desktop_popup(d, TRUE);
-    else
-        screen_desktop_popup(0, FALSE);
-    ret = d;
-
-    if (!dialog || cancel || done)
-        d = (guint)-1;
-
-    return ret;
-}
-
 static gboolean screen_validate_layout(ObDesktopLayout *l)
 {
     if (l->columns == 0 && l->rows == 0) /* both 0's is bad data.. */
@@ -1092,7 +1089,7 @@ void screen_update_desktop_names()
     }
 
     /* resize the pager for these names */
-    pager_popup_text_width_to_strings(desktop_cycle_popup,
+    pager_popup_text_width_to_strings(desktop_popup,
                                       screen_desktop_names,
                                       screen_num_desktops);
 }
@@ -1142,7 +1139,7 @@ void screen_show_desktop(gboolean show, ObClient *show_only)
     else if (!show_only) {
         ObClient *c;
 
-        if ((c = focus_fallback(TRUE, FALSE, TRUE))) {
+        if ((c = focus_fallback(TRUE, FALSE, TRUE, FALSE))) {
             /* only do the flicker reducing stuff ahead of time if we are going
                to call xsetinputfocus on the window ourselves. otherwise there
                is no guarantee the window will actually take focus.. */
@@ -1555,7 +1552,9 @@ Rect* screen_physical_area_active()
     Rect *a;
     gint x, y;
 
-    if (focus_client)
+    if (moveresize_client)
+        a = screen_physical_area_monitor(client_monitor(focus_client));
+    else if (focus_client)
         a = screen_physical_area_monitor(client_monitor(focus_client));
     else {
         Rect mon;
index c2c57f09a8a2e1f00e752f2cb460c9adbd6223c2..68a132517b8ac45e1c134b41c4a35b49f4453683 100644 (file)
@@ -72,15 +72,11 @@ void screen_add_desktop(gboolean current);
 /*! Remove a desktop, either at the end or the current desktop */
 void screen_remove_desktop(gboolean current);
 
-/*! Interactively change desktops */
-guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear,
-                           gboolean dialog, gboolean done, gboolean cancel);
-
 guint screen_find_desktop(guint from, ObDirection dir,
                           gboolean wrap, gboolean linear);
 
-/*! Show/hide the desktop popup (pager) for the given desktop */
-void screen_desktop_popup(guint d, gboolean show);
+/*! Show the desktop popup/notification */
+void screen_show_desktop_popup(guint d);
 
 /*! Shows and focuses the desktop and hides all the client windows, or
   returns to the normal state, showing client windows.
index 47e9348d9e2dc257934ad8f0c5d34680351ee6a8..7bdd184860671a17d806377ca64744caba650070 100644 (file)
--- a/po/no.po
+++ b/po/no.po
@@ -5,7 +5,7 @@
 # Michael Kjelbergvik Thung <postlogic@switch-case.org>, 2007.
 msgid ""
 msgstr ""
-"Project-Id-Version: openbox 3.4.2\n"
+"Project-Id-Version: openbox 3.4.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.icculus.org\n"
 "POT-Creation-Date: 2007-07-22 08:25-0400\n"
 "PO-Revision-Date: 2007-05-20 18:41+0200\n"
@@ -31,15 +31,15 @@ msgstr "Gå dit..."
 
 #: openbox/client_list_combined_menu.c:98
 msgid "Manage desktops"
-msgstr ""
+msgstr "Behandle skrivebord"
 
 #: openbox/client_list_combined_menu.c:99 openbox/client_list_menu.c:152
 msgid "_Add new desktop"
-msgstr ""
+msgstr "_Nytt skrivebord"
 
 #: openbox/client_list_combined_menu.c:100 openbox/client_list_menu.c:153
 msgid "_Remove last desktop"
-msgstr ""
+msgstr "_Fjern siste skrivebord"
 
 #: openbox/client_list_combined_menu.c:146
 msgid "Windows"
index dd3c3dd3948f288cea9ecb576c31d4eb059932cf..48af0304cf63086599df4410f17a721ede6af1be 100644 (file)
@@ -5,10 +5,10 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: openbox 3.4.2\n"
+"Project-Id-Version: openbox 3.4.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.icculus.org\n"
 "POT-Creation-Date: 2007-07-22 08:25-0400\n"
-"PO-Revision-Date: 2007-05-23 16:22+0200\n"
+"PO-Revision-Date: 2007-07-23 23:22+0200\n"
 "Last-Translator: Wei-Lun Chao <chaoweilun@gmail.com>\n"
 "Language-Team: Chinese (traditional) <zh-l10n@linux.org.tw>\n"
 "MIME-Version: 1.0\n"
@@ -19,7 +19,7 @@ msgstr ""
 #: openbox/actions/execute.c:88
 #, c-format
 msgid "Failed to convert the path '%s' from utf8"
-msgstr "從 utf8 轉換路徑「%s」時失敗"
+msgstr "轉換路徑「%s」自 utf8 時失敗"
 
 #: openbox/actions/execute.c:97 openbox/actions/execute.c:115
 #, c-format
@@ -32,15 +32,15 @@ msgstr "到那裏去…"
 
 #: openbox/client_list_combined_menu.c:98
 msgid "Manage desktops"
-msgstr ""
+msgstr "管理桌面"
 
 #: openbox/client_list_combined_menu.c:99 openbox/client_list_menu.c:152
 msgid "_Add new desktop"
-msgstr ""
+msgstr "加入新桌面(_A)"
 
 #: openbox/client_list_combined_menu.c:100 openbox/client_list_menu.c:153
 msgid "_Remove last desktop"
-msgstr ""
+msgstr "移除尾端桌面(_R)"
 
 #: openbox/client_list_combined_menu.c:146
 msgid "Windows"
index a793ced71f6a8021ca296f31c2d955bfbd94adba..0de3dc745d42662ae09599bb761731e6d31ade29 100644 (file)
@@ -186,7 +186,9 @@ RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
     if (!read_int(db, "padding.width", &theme->paddingx) ||
         theme->paddingx < 0 || theme->paddingx > 100)
         theme->paddingx = 3;
-    theme->paddingy = theme->paddingx;
+    if (!read_int(db, "padding.height", &theme->paddingy) ||
+        theme->paddingy < 0 || theme->paddingy > 100)
+        theme->paddingy = theme->paddingx;
     if (!read_int(db, "border.width", &theme->fbwidth) ||
         theme->fbwidth < 0 || theme->fbwidth > 100)
         theme->fbwidth = 1;
This page took 0.105356 seconds and 4 git commands to generate.