Clip client rect to monitor bounds while picking a corner for resizing
[mikachu/openbox.git] / openbox / actions / resize.c
index 47f45f5..fc85c0b 100644 (file)
@@ -2,6 +2,7 @@
 #include "openbox/moveresize.h"
 #include "openbox/client.h"
 #include "openbox/frame.h"
+#include "openbox/screen.h"
 #include "obt/prop.h"
 
 typedef struct {
@@ -10,6 +11,7 @@ typedef struct {
 } Options;
 
 static gpointer setup_func(xmlNodePtr node);
+static void free_func(gpointer o);
 static gboolean run_func(ObActionsData *data, gpointer options);
 
 static guint32 pick_corner(gint x, gint y, gint cx, gint cy, gint cw, gint ch,
@@ -17,7 +19,7 @@ static guint32 pick_corner(gint x, gint y, gint cx, gint cy, gint cw, gint ch,
 
 void action_resize_startup(void)
 {
-    actions_register("Resize", setup_func, g_free, run_func, NULL, NULL);
+    actions_register("Resize", setup_func, free_func, run_func);
 }
 
 static gpointer setup_func(xmlNodePtr node)
@@ -25,10 +27,10 @@ static gpointer setup_func(xmlNodePtr node)
     xmlNodePtr n;
     Options *o;
 
-    o = g_new0(Options, 1);
+    o = g_slice_new0(Options);
 
-    if ((n = obt_parse_find_node(node, "edge"))) {
-        gchar *s = obt_parse_node_string(n);
+    if ((n = obt_xml_find_node(node, "edge"))) {
+        gchar *s = obt_xml_node_string(n);
 
         o->corner_specified = TRUE;
         if (!g_ascii_strcasecmp(s, "top"))
@@ -55,6 +57,11 @@ static gpointer setup_func(xmlNodePtr node)
     return o;
 }
 
+static void free_func(gpointer o)
+{
+    g_slice_free(Options, o);
+}
+
 /* Always return FALSE because its not interactive */
 static gboolean run_func(ObActionsData *data, gpointer options)
 {
@@ -89,6 +96,12 @@ static gboolean run_func(ObActionsData *data, gpointer options)
 static guint32 pick_corner(gint x, gint y, gint cx, gint cy, gint cw, gint ch,
                            gboolean shaded)
 {
+    const Rect *full = screen_physical_area_all_monitors();
+    if (cx < full->x) { cw = cw + cx - full->x; cx = full->x; }
+    if (cy < full->y) { ch = ch + cy - full->y; cy = full->y; }
+    if (cx + cw > full->x + full->width) cw = full->x + full->width - cx;
+    if (cy + ch > full->y + full->height) ch = full->y + full->height - cy;
+
     /* let's make x and y client relative instead of screen relative */
     x = x - cx;
     y = ch - (y - cy); /* y is inverted, 0 is at the bottom of the window */