Merge branch 'backport' into 3.4-working
authorDana Jansens <danakj@orodu.net>
Wed, 16 Dec 2009 20:37:36 +0000 (15:37 -0500)
committerDana Jansens <danakj@orodu.net>
Wed, 16 Dec 2009 20:37:36 +0000 (15:37 -0500)
openbox/focus_cycle_popup.c
openbox/keyboard.c
openbox/menuframe.c
openbox/screen.c
openbox/screen.h
render/image.c

index a544bf1..740d668 100644 (file)
@@ -261,7 +261,7 @@ static void popup_render(ObFocusCyclePopup *p, const ObClient *c)
     const ObFocusCyclePopupTarget *newtarget;
     gint newtargetx, newtargety;
 
-    screen_area = screen_physical_area_primary();
+    screen_area = screen_physical_area_primary(FALSE);
 
     /* get the outside margins */
     RrMargins(p->a_bg, &ml, &mt, &mr, &mb);
@@ -515,7 +515,7 @@ void focus_cycle_popup_single_show(struct _ObClient *c,
         g_assert(popup.targets == NULL);
 
         /* position the popup */
-        a = screen_physical_area_primary();
+        a = screen_physical_area_primary(FALSE);
         icon_popup_position(single_popup, CenterGravity,
                             a->x + a->width / 2, a->y + a->height / 2);
         icon_popup_height(single_popup, POPUP_HEIGHT);
index aebee29..0d23485 100644 (file)
@@ -91,7 +91,7 @@ static void set_curpos(KeyBindingTree *newpos)
             g_free(oldtext);
         }
 
-        a = screen_physical_area_primary();
+        a = screen_physical_area_primary(FALSE);
         popup_position(popup, NorthWestGravity, a->x + 10, a->y + 10);
         /* 1 second delay for the popup to show */
         popup_delay_show(popup, G_USEC_PER_SEC, text);
index ad692d2..8177f51 100644 (file)
@@ -23,6 +23,7 @@
 #include "screen.h"
 #include "prop.h"
 #include "actions.h"
+#include "event.h"
 #include "grab.h"
 #include "openbox.h"
 #include "mainloop.h"
@@ -949,7 +950,6 @@ gboolean menu_frame_show_topmenu(ObMenuFrame *self, gint x, gint y,
                                  gboolean mouse)
 {
     gint px, py;
-    guint i;
 
     if (menu_frame_is_visible(self))
         return TRUE;
@@ -1021,6 +1021,7 @@ gboolean menu_frame_show_submenu(ObMenuFrame *self, ObMenuFrame *parent,
 static void menu_frame_hide(ObMenuFrame *self)
 {
     GList *it = g_list_find(menu_frame_visible, self);
+    gulong ignore_start;
 
     if (!it)
         return;
@@ -1046,7 +1047,9 @@ static void menu_frame_hide(ObMenuFrame *self)
         ungrab_keyboard();
     }
 
+    ignore_start = event_start_ignore_all_enters();
     XUnmapWindow(ob_display, self->window);
+    event_end_ignore_all_enters(ignore_start);
 
     menu_frame_free(self);
 }
@@ -1158,6 +1161,8 @@ void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *entry,
     }
 
     if (!entry && self->open_submenu) {
+        /* we moved out of the menu, so move the selection back to the open
+           submenu */
         entry = self->open_submenu;
         oldchild = NULL;
 
@@ -1175,12 +1180,16 @@ void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *entry,
         /* there is an open submenu */
 
         if (config_submenu_show_delay && !immediate) {
-            if (old == self->open_submenu) {
-                /* close the open submenu after a delay if we don't have
-                   it selected */
+            if (entry == self->open_submenu) {
+                /* we moved onto the entry that has an open submenu, so stop
+                   trying to close the submenu */
                 ob_main_loop_timeout_remove
                     (ob_main_loop,
                      menu_entry_frame_submenu_hide_timeout);
+            }
+            else if (old == self->open_submenu) {
+                /* we just moved off the entry with an open submenu, so
+                   close the open submenu after a delay */
                 ob_main_loop_timeout_add(ob_main_loop,
                                          config_submenu_show_delay * 1000,
                                          menu_entry_frame_submenu_hide_timeout,
@@ -1195,7 +1204,7 @@ void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *entry,
     if (self->selected) {
         menu_entry_frame_render(self->selected);
 
-        /* if we've selected a submenu and it wasn't always open, then
+        /* if we've selected a submenu and it wasn't already open, then
            show it */
         if (self->selected->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU &&
             self->selected != self->open_submenu)
index 35c9f54..9b1a772 100644 (file)
@@ -945,7 +945,7 @@ void screen_show_desktop_popup(guint d)
     /* 0 means don't show the popup */
     if (!config_desktop_popup_time) return;
 
-    a = screen_physical_area_primary();
+    a = screen_physical_area_primary(FALSE);
     pager_popup_position(desktop_popup, CenterGravity,
                          a->x + a->width / 2, a->y + a->height / 2);
     pager_popup_icon_size_multiplier(desktop_popup,
@@ -1285,19 +1285,6 @@ void screen_install_colormap(ObClient *client, gboolean install)
     }
 }
 
-#define STRUT_LEFT_ON_MONITOR(s, i) \
-    (RANGES_INTERSECT(s->left_start, s->left_end - s->left_start + 1, \
-                      monitor_area[i].y, monitor_area[i].height))
-#define STRUT_RIGHT_ON_MONITOR(s, i) \
-    (RANGES_INTERSECT(s->right_start, s->right_end - s->right_start + 1, \
-                      monitor_area[i].y, monitor_area[i].height))
-#define STRUT_TOP_ON_MONITOR(s, i) \
-    (RANGES_INTERSECT(s->top_start, s->top_end - s->top_start + 1, \
-                      monitor_area[i].x, monitor_area[i].width))
-#define STRUT_BOTTOM_ON_MONITOR(s, i) \
-    (RANGES_INTERSECT(s->bottom_start, s->bottom_end - s->bottom_start + 1, \
-                      monitor_area[i].x, monitor_area[i].width))
-
 typedef struct {
     guint desktop;
     StrutPartial *strut;
@@ -1325,7 +1312,7 @@ typedef struct {
 
 void screen_update_areas(void)
 {
-    guint i, j;
+    guint j;
     gulong *dims;
     GList *it;
     GSList *sit;
@@ -1343,7 +1330,7 @@ void screen_update_areas(void)
     config_margins.right_start = RECT_TOP(monitor_area[screen_num_monitors]);
     config_margins.right_end = RECT_BOTTOM(monitor_area[screen_num_monitors]);
 
-    dims = g_new(gulong, 4 * screen_num_desktops * screen_num_monitors);
+    dims = g_new(gulong, 4 * screen_num_desktops);
 
     RESET_STRUT_LIST(struts_left);
     RESET_STRUT_LIST(struts_top);
@@ -1389,69 +1376,51 @@ void screen_update_areas(void)
     VALIDATE_STRUTS(struts_bottom, bottom,
                     monitor_area[screen_num_monitors].height / 2);
 
-    /* set up the work areas to be full screen */
-    for (i = 0; i < screen_num_monitors; ++i)
-        for (j = 0; j < screen_num_desktops; ++j) {
-            dims[(i * screen_num_desktops + j) * 4+0] = monitor_area[i].x;
-            dims[(i * screen_num_desktops + j) * 4+1] = monitor_area[i].y;
-            dims[(i * screen_num_desktops + j) * 4+2] = monitor_area[i].width;
-            dims[(i * screen_num_desktops + j) * 4+3] = monitor_area[i].height;
-        }
-
-    /* calculate the work areas from the struts */
-    for (i = 0; i < screen_num_monitors; ++i)
-        for (j = 0; j < screen_num_desktops; ++j) {
-            gint l = 0, r = 0, t = 0, b = 0;
-
-            /* only add the strut to the area if it touches the monitor */
+    /* set up the work area to be full screen across all monitors */
+    for (j = 0; j < screen_num_desktops; ++j) {
+        dims[j*4 + 0] =
+            monitor_area[screen_num_monitors].x;
+        dims[j*4 + 1] =
+            monitor_area[screen_num_monitors].y;
+        dims[j*4 + 2] =
+            monitor_area[screen_num_monitors].width;
+        dims[j*4 + 3] =
+            monitor_area[screen_num_monitors].height;
+    }
 
-            for (sit = struts_left; sit; sit = g_slist_next(sit)) {
-                ObScreenStrut *s = sit->data;
-                if ((s->desktop == j || s->desktop == DESKTOP_ALL) &&
-                    STRUT_LEFT_ON_MONITOR(s->strut, i))
-                    l = MAX(l, s->strut->left);
-            }
-            for (sit = struts_top; sit; sit = g_slist_next(sit)) {
-                ObScreenStrut *s = sit->data;
-                if ((s->desktop == j || s->desktop == DESKTOP_ALL) &&
-                    STRUT_TOP_ON_MONITOR(s->strut, i))
-                    t = MAX(t, s->strut->top);
-            }
-            for (sit = struts_right; sit; sit = g_slist_next(sit)) {
-                ObScreenStrut *s = sit->data;
-                if ((s->desktop == j || s->desktop == DESKTOP_ALL) &&
-                    STRUT_RIGHT_ON_MONITOR(s->strut, i))
-                    r = MAX(r, s->strut->right);
-            }
-            for (sit = struts_bottom; sit; sit = g_slist_next(sit)) {
-                ObScreenStrut *s = sit->data;
-                if ((s->desktop == j || s->desktop == DESKTOP_ALL) &&
-                    STRUT_BOTTOM_ON_MONITOR(s->strut, i))
-                    b = MAX(b, s->strut->bottom);
-            }
+    /* calculate the work area from the struts */
+    for (j = 0; j < screen_num_desktops; ++j) {
+        gint l = 0, r = 0, t = 0, b = 0;
 
-            /* if the monitor is not against the edge of the root window,
-               the struts will include the distance from the root window's edge
-               to the monitor, so add that back into the monitor's work area */
-            if (l) l += RECT_LEFT  (monitor_area[screen_num_monitors])
-                        - RECT_LEFT  (monitor_area[i]);
-            if (t) t += RECT_TOP   (monitor_area[screen_num_monitors])
-                        - RECT_TOP   (monitor_area[i]);
-            if (r) r -= RECT_RIGHT (monitor_area[screen_num_monitors])
-                        - RECT_RIGHT (monitor_area[i]);
-            if (b) b -= RECT_BOTTOM(monitor_area[screen_num_monitors])
-                        - RECT_BOTTOM(monitor_area[i]);
-
-            /* based on these margins, set the work area for the
-               monitor/desktop */
-            dims[(i * screen_num_desktops + j) * 4 + 0] += l;
-            dims[(i * screen_num_desktops + j) * 4 + 1] += t;
-            dims[(i * screen_num_desktops + j) * 4 + 2] -= l + r;
-            dims[(i * screen_num_desktops + j) * 4 + 3] -= t + b;
+        for (sit = struts_left; sit; sit = g_slist_next(sit)) {
+            ObScreenStrut *s = sit->data;
+            if (s->desktop == j || s->desktop == DESKTOP_ALL)
+                l = MAX(l, s->strut->left);
+        }
+        for (sit = struts_top; sit; sit = g_slist_next(sit)) {
+            ObScreenStrut *s = sit->data;
+            if (s->desktop == j || s->desktop == DESKTOP_ALL)
+                t = MAX(t, s->strut->top);
+        }
+        for (sit = struts_right; sit; sit = g_slist_next(sit)) {
+            ObScreenStrut *s = sit->data;
+            if (s->desktop == j || s->desktop == DESKTOP_ALL)
+                r = MAX(r, s->strut->right);
         }
+        for (sit = struts_bottom; sit; sit = g_slist_next(sit)) {
+            ObScreenStrut *s = sit->data;
+            if (s->desktop == j || s->desktop == DESKTOP_ALL)
+                b = MAX(b, s->strut->bottom);
+        }
+
+        /* based on these margins, set the work area for the desktop */
+        dims[j*4 + 0] += l;
+        dims[j*4 + 1] += t;
+        dims[j*4 + 2] -= l + r;
+        dims[j*4 + 3] -= t + b;
+    }
 
-    /* all the work areas are not used here, only the ones for the first
-       monitor are */
+    /* set the legacy workarea hint to the union of all the monitors */
     PROP_SETA32(RootWindow(ob_display, ob_screen), net_workarea, cardinal,
                 dims, 4 * screen_num_desktops);
 
@@ -1690,7 +1659,7 @@ Rect* screen_physical_area_active(void)
     return screen_physical_area_monitor(screen_monitor_active());
 }
 
-guint screen_monitor_primary(void)
+guint screen_monitor_primary(gboolean fixed)
 {
     if (config_primary_monitor_index > 0) {
         if (config_primary_monitor_index-1 < screen_num_monitors)
@@ -1698,15 +1667,17 @@ guint screen_monitor_primary(void)
         else
             return 0;
     }
+    else if (fixed)
+        return 0;
     else if (config_primary_monitor == OB_PLACE_MONITOR_ACTIVE)
         return screen_monitor_active();
     else /* config_primary_monitor == OB_PLACE_MONITOR_MOUSE */
         return screen_monitor_pointer();
 }
 
-Rect *screen_physical_area_primary(void)
+Rect *screen_physical_area_primary(gboolean fixed)
 {
-    return screen_physical_area_monitor(screen_monitor_primary());
+    return screen_physical_area_monitor(screen_monitor_primary(fixed));
 }
 
 void screen_set_root_cursor(void)
index 9584e9c..750de94 100644 (file)
@@ -110,10 +110,18 @@ guint screen_monitor_active(void);
 
 Rect *screen_physical_area_active(void);
 
-/*! Returns the primary monitor, as specified by the config */
-guint screen_monitor_primary(void);
+/*! Returns the primary monitor, as specified by the config.
+  @fixed If TRUE, then this will always return a fixed monitor, otherwise
+         it may change based on where focus is, or other heuristics.
+ */
+guint screen_monitor_primary(gboolean fixed);
 
-Rect *screen_physical_area_primary(void);
+/*! Returns physical area for the primary monitor, as specified by the config.
+  @fixed If TRUE, then this will always use a fixed monitor as primary,
+         otherwise it may change based on where focus is, or other heuristics.
+         See screen_monitor_primary().
+*/
+Rect *screen_physical_area_primary(gboolean fixed);
 
 /* doesn't include struts which the search area is already outside of when
    'search' is not NULL */
index c8e839c..48012d4 100644 (file)
@@ -73,12 +73,14 @@ static void AddPicture(RrImage *self, RrImagePic ***list, gint *len,
     /* add the picture as a key to point to this image in the cache */
     g_hash_table_insert(self->cache->table, (*list)[0], self);
 
+/*
 #ifdef DEBUG
     g_message("Adding %s picture to the cache:\n    "
               "Image 0x%x, w %d h %d Hash %u",
               (*list == self->original ? "ORIGINAL" : "RESIZED"),
               (guint)self, pic->width, pic->height, RrImagePicHash(pic));
 #endif
+*/
 }
 
 /*! Remove a picture from an Image.  This may remove it from the "originals"
@@ -88,6 +90,7 @@ static void RemovePicture(RrImage *self, RrImagePic ***list,
 {
     gint j;
 
+/*
 #ifdef DEBUG
     g_message("Removing %s picture from the cache:\n    "
               "Image 0x%x, w %d h %d Hash %u",
@@ -95,6 +98,7 @@ static void RemovePicture(RrImage *self, RrImagePic ***list,
               (guint)self, (*list)[i]->width, (*list)[i]->height,
               RrImagePicHash((*list)[i]));
 #endif
+*/
 
     /* remove the picture as a key in the cache */
     g_hash_table_remove(self->cache->table, (*list)[i]);
@@ -329,10 +333,12 @@ void RrImageRef(RrImage *self)
 void RrImageUnref(RrImage *self)
 {
     if (self && --self->ref == 0) {
+/*
 #ifdef DEBUG
         g_message("Refcount to 0, removing ALL pictures from the cache:\n    "
                   "Image 0x%x", (guint)self);
 #endif
+*/
         while (self->n_original > 0)
             RemovePicture(self, &self->original, 0, &self->n_original);
         while (self->n_resized > 0)
@@ -352,10 +358,12 @@ void RrImageAddPicture(RrImage *self, RrPixel32 *data, gint w, gint h)
     /* make sure we don't already have this size.. */
     for (i = 0; i < self->n_original; ++i)
         if (self->original[i]->width == w && self->original[i]->height == h) {
+/*
 #ifdef DEBUG
             g_message("Found duplicate ORIGINAL image:\n    "
                       "Image 0x%x, w %d h %d", (guint)self, w, h);
 #endif
+*/
             return;
         }