force the resize popup to be on-screen (not negative position)
[mikachu/openbox.git] / openbox / config.c
index dad98a0..e1954a7 100644 (file)
@@ -36,8 +36,9 @@ gboolean config_focus_raise;
 gboolean config_focus_last;
 gboolean config_focus_under_mouse;
 
-ObPlacePolicy config_place_policy;
-gboolean      config_place_center;
+ObPlacePolicy  config_place_policy;
+gboolean       config_place_center;
+ObPlaceMonitor config_place_monitor;
 
 StrutPartial config_margins;
 
@@ -54,14 +55,15 @@ RrFont *config_font_menuitem;
 RrFont *config_font_menutitle;
 RrFont *config_font_osd;
 
-gint    config_desktops_num;
+guint   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;
-gint     config_resize_popup_show;
-gint     config_resize_popup_pos;
+gboolean         config_resize_redraw;
+gint             config_resize_popup_show;
+ObResizePopupPos config_resize_popup_pos;
+GravityPoint     config_resize_popup_fixed;
 
 ObStackingLayer config_dock_layer;
 gboolean        config_dock_floating;
@@ -87,6 +89,7 @@ guint    config_menu_hide_delay;
 gboolean config_menu_middle;
 guint    config_submenu_show_delay;
 gboolean config_menu_client_list_icons;
+gboolean config_menu_manage_desktops;
 
 GSList *config_menu_files;
 
@@ -95,7 +98,7 @@ gint     config_resist_edge;
 
 GSList *config_per_app_settings;
 
-ObAppSettings* config_create_app_settings()
+ObAppSettings* config_create_app_settings(void)
 {
     ObAppSettings *settings = g_new0(ObAppSettings, 1);
     settings->decor = -1;
@@ -135,16 +138,29 @@ void config_app_settings_copy_non_defaults(const ObAppSettings *src,
 
     if (src->pos_given) {
         dst->pos_given = TRUE;
-        dst->center_x = src->center_x;
-        dst->center_y = src->center_y;
-        dst->opposite_x = src->opposite_x;
-        dst->opposite_y = src->opposite_y;
-        dst->position.x = src->position.x;
-        dst->position.y = src->position.y;
+        dst->pos_force = src->pos_force;
+        dst->position = src->position;
         dst->monitor = src->monitor;
     }
 }
 
+static void config_parse_gravity_coord(xmlDocPtr doc, xmlNodePtr node,
+                                       GravityCoord *c)
+{
+    gchar *s = parse_string(doc, node);
+    if (!g_ascii_strcasecmp(s, "center"))
+        c->center = TRUE;
+    else {
+        if (s[0] == '-')
+            c->opposite = TRUE;
+        if (s[0] == '-' || s[0] == '+')
+            c->pos = atoi(s+1);
+        else
+            c->pos = atoi(s);
+    }
+    g_free(s);
+}
+
 /*
   <applications>
     <application name="aterm">
@@ -173,8 +189,8 @@ void config_app_settings_copy_non_defaults(const ObAppSettings *src,
    the monitor, so <position><x>center</x></position><monitor>2</monitor>
    will center the window on the second monitor.
 */
-static void parse_per_app_settings(ObParseInst *i, xmlDocPtr doc,
-                                   xmlNodePtr node, gpointer d)
+static void parse_per_app_settings(ObParseInst *inst, xmlDocPtr doc,
+                                   xmlNodePtr node, gpointer data)
 {
     xmlNodePtr app = parse_find_node("application", node->children);
     gchar *name = NULL, *class = NULL, *role = NULL;
@@ -189,7 +205,7 @@ static void parse_per_app_settings(ObParseInst *i, xmlDocPtr doc,
         if (class_set || name_set) {
             xmlNodePtr n, c;
             ObAppSettings *settings = config_create_app_settings();;
-            
+
             if (name_set)
                 settings->name = g_pattern_spec_new(name);
 
@@ -210,50 +226,30 @@ static void parse_per_app_settings(ObParseInst *i, xmlDocPtr doc,
             if ((n = parse_find_node("position", app->children))) {
                 if ((c = parse_find_node("x", n->children)))
                     if (!parse_contains("default", doc, c)) {
-                        gchar *s = parse_string(doc, c);
-                        if (!strcmp(s, "center")) {
-                            settings->center_x = TRUE;
-                            x_pos_given = TRUE;
-                        } else {
-                            if (s[0] == '-')
-                                settings->opposite_x = TRUE;
-                            if (s[0] == '-' || s[0] == '+')
-                                settings->position.x = atoi(s+1);
-                            else
-                                settings->position.x = atoi(s);
-                            x_pos_given = TRUE;
-                        }
-                        g_free(s);
+                        config_parse_gravity_coord(doc, c,
+                                                   &settings->position.x);
+                        x_pos_given = TRUE;
                     }
 
                 if (x_pos_given && (c = parse_find_node("y", n->children)))
                     if (!parse_contains("default", doc, c)) {
-                        gchar *s = parse_string(doc, c);
-                        if (!strcmp(s, "center")) {
-                            settings->center_y = TRUE;
-                            settings->pos_given = TRUE;
-                        } else {
-                            if (s[0] == '-')
-                                settings->opposite_y = TRUE;
-                            if (s[0] == '-' || s[0] == '+')
-                                settings->position.y = atoi(s+1);
-                            else
-                                settings->position.y = atoi(s);
-                            settings->pos_given = TRUE;
-                        }
-                        g_free(s);
+                        config_parse_gravity_coord(doc, c,
+                                                   &settings->position.y);
+                        settings->pos_given = TRUE;
                     }
 
                 if (settings->pos_given &&
                     (c = parse_find_node("monitor", n->children)))
                     if (!parse_contains("default", doc, c)) {
                         gchar *s = parse_string(doc, c);
-                        if (!strcmp(s, "mouse"))
+                        if (!g_ascii_strcasecmp(s, "mouse"))
                             settings->monitor = 0;
                         else
                             settings->monitor = parse_int(doc, c) + 1;
                         g_free(s);
                     }
+
+                parse_attr_bool("force", n, &settings->pos_force);
             }
 
             if ((n = parse_find_node("focus", app->children)))
@@ -263,7 +259,7 @@ static void parse_per_app_settings(ObParseInst *i, xmlDocPtr doc,
             if ((n = parse_find_node("desktop", app->children))) {
                 if (!parse_contains("default", doc, n)) {
                     gchar *s = parse_string(doc, n);
-                    if (!strcmp(s, "all"))
+                    if (!g_ascii_strcasecmp(s, "all"))
                         settings->desktop = DESKTOP_ALL;
                     else {
                         gint i = parse_int(doc, n);
@@ -277,9 +273,9 @@ static void parse_per_app_settings(ObParseInst *i, xmlDocPtr doc,
             if ((n = parse_find_node("layer", app->children)))
                 if (!parse_contains("default", doc, n)) {
                     gchar *s = parse_string(doc, n);
-                    if (!strcmp(s, "above"))
+                    if (!g_ascii_strcasecmp(s, "above"))
                         settings->layer = 1;
-                    else if (!strcmp(s, "below"))
+                    else if (!g_ascii_strcasecmp(s, "below"))
                         settings->layer = -1;
                     else
                         settings->layer = 0;
@@ -305,10 +301,10 @@ static void parse_per_app_settings(ObParseInst *i, xmlDocPtr doc,
             if ((n = parse_find_node("maximized", app->children)))
                 if (!parse_contains("default", doc, n)) {
                     gchar *s = parse_string(doc, n);
-                    if (!strcmp(s, "horizontal")) {
+                    if (!g_ascii_strcasecmp(s, "horizontal")) {
                         settings->max_horz = TRUE;
                         settings->max_vert = FALSE;
-                    } else if (!strcmp(s, "vertical")) {
+                    } else if (!g_ascii_strcasecmp(s, "vertical")) {
                         settings->max_horz = FALSE;
                         settings->max_vert = TRUE;
                     } else
@@ -319,14 +315,14 @@ static void parse_per_app_settings(ObParseInst *i, xmlDocPtr doc,
 
             config_per_app_settings = g_slist_append(config_per_app_settings,
                                               (gpointer) settings);
+            g_free(name);
+            g_free(class);
+            g_free(role);
+            name = class = role = NULL;
         }
-        
+
         app = parse_find_node("application", app->next);
     }
-
-    g_free(name);
-    g_free(class);
-    g_free(role);
 }
 
 /*
@@ -362,7 +358,7 @@ static void parse_key(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
     else if ((n = parse_find_node("action", node->children))) {
         while (n) {
             ObActionsAct *action;
-            
+
             action = actions_parse(i, doc, n);
             if (action)
                 keyboard_bind(keylist, action);
@@ -378,7 +374,7 @@ static void parse_key(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 }
 
 static void parse_keyboard(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                           gpointer d)
+                           gpointer data)
 {
     xmlNodePtr n;
     gchar *key;
@@ -401,7 +397,7 @@ static void parse_keyboard(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 
 /*
 
-<context name="Titlebar"> 
+<context name="Titlebar">
   <mousebind button="Left" action="Press">
     <action name="Raise"></action>
   </mousebind>
@@ -410,7 +406,7 @@ static void parse_keyboard(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 */
 
 static void parse_mouse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                        gpointer d)
+                        gpointer data)
 {
     xmlNodePtr n, nbut, nact;
     gchar *buttonstr;
@@ -420,7 +416,7 @@ static void parse_mouse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
     mouse_unbind_all();
 
     node = node->children;
-    
+
     if ((n = parse_find_node("dragThreshold", node)))
         config_mouse_threshold = parse_int(doc, n);
     if ((n = parse_find_node("doubleClickTime", node)))
@@ -467,18 +463,18 @@ static void parse_mouse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 }
 
 static void parse_focus(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                        gpointer d)
+                        gpointer data)
 {
     xmlNodePtr n;
 
     node = node->children;
-    
+
     if ((n = parse_find_node("focusNew", node)))
         config_focus_new = parse_bool(doc, n);
     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)))
@@ -488,26 +484,32 @@ static void parse_focus(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 }
 
 static void parse_placement(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                            gpointer d)
+                            gpointer data)
 {
     xmlNodePtr n;
 
     node = node->children;
-    
+
     if ((n = parse_find_node("policy", node)))
         if (parse_contains("UnderMouse", doc, n))
             config_place_policy = OB_PLACE_POLICY_MOUSE;
     if ((n = parse_find_node("center", node)))
         config_place_center = parse_bool(doc, n);
+    if ((n = parse_find_node("monitor", node))) {
+        if (parse_contains("active", doc, n))
+            config_place_monitor = OB_PLACE_MONITOR_ACTIVE;
+        else if (parse_contains("mouse", doc, n))
+            config_place_monitor = OB_PLACE_MONITOR_MOUSE;
+    }
 }
 
 static void parse_margins(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                          gpointer d)
+                          gpointer data)
 {
     xmlNodePtr n;
 
     node = node->children;
-    
+
     if ((n = parse_find_node("top", node)))
         config_margins.top = MAX(0, parse_int(doc, n));
     if ((n = parse_find_node("left", node)))
@@ -519,7 +521,7 @@ static void parse_margins(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 }
 
 static void parse_theme(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                        gpointer d)
+                        gpointer data)
 {
     xmlNodePtr n;
 
@@ -602,16 +604,16 @@ static void parse_theme(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 }
 
 static void parse_desktops(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                           gpointer d)
+                           gpointer data)
 {
     xmlNodePtr n;
 
     node = node->children;
-    
+
     if ((n = parse_find_node("number", node))) {
         gint d = parse_int(doc, n);
         if (d > 0)
-            config_desktops_num = d;
+            config_desktops_num = (unsigned) d;
     }
     if ((n = parse_find_node("firstdesk", node))) {
         gint d = parse_int(doc, n);
@@ -634,15 +636,17 @@ 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,
-                         gpointer d)
+                         gpointer data)
 {
     xmlNodePtr n;
 
     node = node->children;
-    
+
     if ((n = parse_find_node("drawContents", node)))
         config_resize_redraw = parse_bool(doc, n);
     if ((n = parse_find_node("popupShow", node))) {
@@ -655,16 +659,34 @@ static void parse_resize(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
             config_resize_popup_show = 1;
     }
     if ((n = parse_find_node("popupPosition", node))) {
-        config_resize_popup_pos = parse_int(doc, n);
         if (parse_contains("Top", doc, n))
-            config_resize_popup_pos = 1;
+            config_resize_popup_pos = OB_RESIZE_POS_TOP;
         else if (parse_contains("Center", doc, n))
-            config_resize_popup_pos = 0;
+            config_resize_popup_pos = OB_RESIZE_POS_CENTER;
+        else if (parse_contains("Fixed", doc, n)) {
+            config_resize_popup_pos = OB_RESIZE_POS_FIXED;
+
+            if ((n = parse_find_node("popupFixedPosition", node))) {
+                xmlNodePtr n2;
+
+                if ((n2 = parse_find_node("x", n->children)))
+                    config_parse_gravity_coord(doc, n2,
+                                               &config_resize_popup_fixed.x);
+                if ((n2 = parse_find_node("y", n->children)))
+                    config_parse_gravity_coord(doc, n2,
+                                               &config_resize_popup_fixed.y);
+
+                config_resize_popup_fixed.x.pos =
+                    MAX(config_resize_popup_fixed.x.pos, 0);
+                config_resize_popup_fixed.y.pos =
+                    MAX(config_resize_popup_fixed.y.pos, 0);
+            }
+        }
     }
 }
 
 static void parse_dock(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                       gpointer d)
+                       gpointer data)
 {
     xmlNodePtr n;
 
@@ -724,9 +746,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;
@@ -741,7 +763,7 @@ static void parse_dock(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 }
 
 static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                       gpointer d)
+                       gpointer data)
 {
     xmlNodePtr n;
     for (node = node->children; node; node = node->next) {
@@ -761,11 +783,13 @@ static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
             config_submenu_show_delay = parse_int(doc, n);
         if ((n = parse_find_node("applicationIcons", node)))
             config_menu_client_list_icons = parse_bool(doc, n);
+        if ((n = parse_find_node("manageDesktops", node)))
+            config_menu_manage_desktops = parse_bool(doc, n);
     }
 }
-   
-static void parse_resistance(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node, 
-                             gpointer d)
+
+static void parse_resistance(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
+                             gpointer data)
 {
     xmlNodePtr n;
 
@@ -782,7 +806,7 @@ typedef struct
     const gchar *actname;
 } ObDefKeyBind;
 
-static void bind_default_keyboard()
+static void bind_default_keyboard(void)
 {
     ObDefKeyBind *it;
     ObDefKeyBind binds[] = {
@@ -805,7 +829,7 @@ typedef struct
     const gchar *actname;
 } ObDefMouseBind;
 
-static void bind_default_mouse()
+static void bind_default_mouse(void)
 {
     ObDefMouseBind *it;
     ObDefMouseBind binds[] = {
@@ -877,6 +901,7 @@ void config_startup(ObParseInst *i)
 
     config_place_policy = OB_PLACE_POLICY_SMART;
     config_place_center = TRUE;
+    config_place_monitor = OB_PLACE_MONITOR_ANY;
 
     parse_register(i, "placement", parse_placement, NULL);
 
@@ -900,13 +925,15 @@ 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);
 
     config_resize_redraw = TRUE;
-    config_resize_four_corners = FALSE;
     config_resize_popup_show = 1; /* nonpixel increments */
-    config_resize_popup_pos = 0;  /* center of client */
+    config_resize_popup_pos = OB_RESIZE_POS_CENTER;
+    GRAVITY_COORD_SET(config_resize_popup_fixed.x, 0, FALSE, FALSE);
+    GRAVITY_COORD_SET(config_resize_popup_fixed.y, 0, FALSE, FALSE);
 
     parse_register(i, "resize", parse_resize, NULL);
 
@@ -949,6 +976,7 @@ void config_startup(ObParseInst *i)
     config_menu_middle = FALSE;
     config_submenu_show_delay = 0;
     config_menu_client_list_icons = TRUE;
+    config_menu_manage_desktops = TRUE;
     config_menu_files = NULL;
 
     parse_register(i, "menu", parse_menu, NULL);
@@ -958,7 +986,7 @@ void config_startup(ObParseInst *i)
     parse_register(i, "applications", parse_per_app_settings, NULL);
 }
 
-void config_shutdown()
+void config_shutdown(void)
 {
     GSList *it;
 
@@ -970,6 +998,7 @@ void config_shutdown()
     RrFontClose(config_font_inactivewindow);
     RrFontClose(config_font_menuitem);
     RrFontClose(config_font_menutitle);
+    RrFontClose(config_font_osd);
 
     for (it = config_desktops_names; it; it = g_slist_next(it))
         g_free(it->data);