]> Dogcows Code - chaz/openbox/commitdiff
when a window is fully maxed, make clicking on the titlebar past the edge buttons...
authorDana Jansens <danakj@orodu.net>
Wed, 9 May 2007 22:21:28 +0000 (22:21 +0000)
committerDana Jansens <danakj@orodu.net>
Wed, 9 May 2007 22:21:28 +0000 (22:21 +0000)
openbox/client.c
openbox/event.c
openbox/frame.c
openbox/frame.h
openbox/mouse.c

index 9fbd0b2a4ad63a8aaa061b8542747b31e3a77e96..0c4cce1f50be47e9a6f489790b2cb2b2ef9c6299 100644 (file)
@@ -1664,7 +1664,7 @@ void client_setup_decor_and_functions(ObClient *self)
 
     /* kill the handle on fully maxed windows */
     if (self->max_vert && self->max_horz)
-        self->decorations &= ~OB_FRAME_DECOR_HANDLE;
+        self->decorations &= ~(OB_FRAME_DECOR_HANDLE | OB_FRAME_DECOR_GRIPS);
 
     /* finally, the user can have requested no decorations, which overrides
        everything (but doesnt give it a border if it doesnt have one) */
index fe06935d97898425d4342c4772d79b811c3e0808..ef320afd0ae8c3ee2dc81203cac7864dd64d9757 100644 (file)
@@ -729,9 +729,13 @@ static void event_handle_client(ObClient *client, XEvent *e)
     XEvent ce;
     Atom msgtype;
     ObFrameContext con;
+    static gint px = -1, py = -1;
      
     switch (e->type) {
     case ButtonPress:
+        /* save where the press occured for the first button pressed */
+        if (px == -1) px = e->xbutton.x;
+        if (py == -1) py = e->xbutton.y;
     case ButtonRelease:
         /* Wheel buttons don't draw because they are an instant click, so it
            is a waste of resources to go drawing it.
@@ -743,8 +747,13 @@ static void event_handle_client(ObClient *client, XEvent *e)
             !keyboard_interactively_grabbed() &&
             !menu_frame_visible)
         {
-            con = frame_context(client, e->xbutton.window);
+            /* use where the press occured */
+            con = frame_context(client, e->xbutton.window, px, py);
             con = mouse_button_frame_context(con, e->xbutton.button);
+
+            if (e->type == ButtonRelease)
+                px = py = -1;
+
             switch (con) {
             case OB_FRAME_CONTEXT_MAXIMIZE:
                 client->frame->max_press = (e->type == ButtonPress);
@@ -773,7 +782,8 @@ static void event_handle_client(ObClient *client, XEvent *e)
         }
         break;
     case LeaveNotify:
-        con = frame_context(client, e->xcrossing.window);
+        con = frame_context(client, e->xcrossing.window,
+                            e->xcrossing.x, e->xcrossing.y);
         switch (con) {
         case OB_FRAME_CONTEXT_MAXIMIZE:
             client->frame->max_hover = FALSE;
@@ -833,7 +843,8 @@ static void event_handle_client(ObClient *client, XEvent *e)
             nofocus = TRUE;
         }
 
-        con = frame_context(client, e->xcrossing.window);
+        con = frame_context(client, e->xcrossing.window,
+                            e->xcrossing.x, e->xcrossing.y);
         switch (con) {
         case OB_FRAME_CONTEXT_MAXIMIZE:
             client->frame->max_hover = TRUE;
index dd24f5cac98dea95a568edc312c987fea6049c44..50f0dc61cda6a8465f2c7687d3186996016d60a7 100644 (file)
@@ -683,7 +683,7 @@ static gboolean is_button_present(ObFrame *self, const gchar *lc, gint dir) {
 static void layout_title(ObFrame *self)
 {
     gchar *lc;
-    gint i, x;
+    gint i;
 
     const gint bwidth = ob_rr_theme->button_size + ob_rr_theme->paddingx + 1;
     /* position of the left most button */
@@ -695,6 +695,7 @@ static void layout_title(ObFrame *self)
     self->icon_on = self->desk_on = self->shade_on = self->iconify_on =
         self->max_on = self->close_on = self->label_on = FALSE;
     self->label_width = self->width - (ob_rr_theme->paddingx + 1) * 2;
+    self->leftmost = self->rightmost = OB_FRAME_CONTEXT_NONE;
 
     /* figure out what's being show, find each element's position, and the
        width of the label
@@ -703,16 +704,21 @@ static void layout_title(ObFrame *self)
        i will be +1 the first time through when working to the left,
        and -1 the second time through when working to the right */
     for (i = 1; i >= -1; i-=2) {
+        gint x;
+        ObFrameContext *firstcon;
+
         if (i > 0) {
             x = left;
             lc = config_title_layout;
+            firstcon = &self->leftmost;
         } else {
             x = right;
             lc = config_title_layout + strlen(config_title_layout)-1;
+            firstcon = &self->rightmost;
         }
 
         /* stop at the end of the string (or the label, which calls break) */
-        for (; *lc != '\0' && lc >= config_title_layout; lc+=i)
+        for (; *lc != '\0' && lc >= config_title_layout; lc+=i) {
             if (*lc == 'L') {
                 if (i > 0) {
                     self->label_on = TRUE;
@@ -720,6 +726,7 @@ static void layout_title(ObFrame *self)
                 }
                 break; /* break the for loop, do other side of label */
             } else if (*lc == 'N') {
+                if (firstcon) *firstcon = OB_FRAME_CONTEXT_ICON;
                 if ((self->icon_on = is_button_present(self, lc, i))) {
                     /* icon gets extra padding */
                     self->label_width -= bwidth + 2;
@@ -727,36 +734,44 @@ static void layout_title(ObFrame *self)
                     x += i * (bwidth + 2);
                 }
             } else if (*lc == 'D') {
+                if (firstcon) *firstcon = OB_FRAME_CONTEXT_ALLDESKTOPS;
                 if ((self->desk_on = is_button_present(self, lc, i))) {
                     self->label_width -= bwidth;
                     self->desk_x = x;
                     x += i * bwidth;
                 }
             } else if (*lc == 'S') {
+                if (firstcon) *firstcon = OB_FRAME_CONTEXT_SHADE;
                 if ((self->shade_on = is_button_present(self, lc, i))) {
                     self->label_width -= bwidth;
                     self->shade_x = x;
                     x += i * bwidth;
                 }
             } else if (*lc == 'I') {
+                if (firstcon) *firstcon = OB_FRAME_CONTEXT_ICONIFY;
                 if ((self->iconify_on = is_button_present(self, lc, i))) {
                     self->label_width -= bwidth;
                     self->iconify_x = x;
                     x += i * bwidth;
                 }
             } else if (*lc == 'M') {
+                if (firstcon) *firstcon = OB_FRAME_CONTEXT_MAXIMIZE;
                 if ((self->max_on = is_button_present(self, lc, i))) {
                     self->label_width -= bwidth;
                     self->max_x = x;
                     x += i * bwidth;
                 }
             } else if (*lc == 'C') {
+                if (firstcon) *firstcon = OB_FRAME_CONTEXT_CLOSE;
                 if ((self->close_on = is_button_present(self, lc, i))) {
                     self->label_width -= bwidth;
                     self->close_x = x;
                     x += i * bwidth;
                 }
-            }
+            } else
+                continue; /* don't set firstcon */
+            firstcon = NULL;
+        }
     }
 
     /* position and map the elements */
@@ -848,7 +863,7 @@ ObFrameContext frame_context_from_string(const gchar *name)
     return OB_FRAME_CONTEXT_NONE;
 }
 
-ObFrameContext frame_context(ObClient *client, Window win)
+ObFrameContext frame_context(ObClient *client, Window win, gint x, gint y)
 {
     ObFrame *self;
 
@@ -875,8 +890,30 @@ ObFrameContext frame_context(ObClient *client, Window win)
         return OB_FRAME_CONTEXT_CLIENT;
     }
 
+    if (win == self->title) {
+        /* when the user clicks in the corners of the titlebar and the client
+           is fully maximized, then treat it like they clicked in the
+           button that is there */
+        if (self->client->max_horz && self->client->max_vert &&
+            y < ob_rr_theme->paddingy + 1 + ob_rr_theme->button_size)
+        {
+            if (x < ((ob_rr_theme->paddingx + 1) * 2 +
+                     ob_rr_theme->button_size)) {
+                if (self->leftmost != OB_FRAME_CONTEXT_NONE)
+                    return self->leftmost;
+            }
+            else if (x > (self->width -
+                          (ob_rr_theme->paddingx + 1 +
+                           ob_rr_theme->button_size)))
+            {
+                if (self->rightmost != OB_FRAME_CONTEXT_NONE)
+                    return self->rightmost;
+            }
+        }
+        return OB_FRAME_CONTEXT_TITLEBAR;
+    }
+
     if (win == self->window)    return OB_FRAME_CONTEXT_FRAME;
-    if (win == self->title)     return OB_FRAME_CONTEXT_TITLEBAR;
     if (win == self->label)     return OB_FRAME_CONTEXT_TITLEBAR;
     if (win == self->handle)    return OB_FRAME_CONTEXT_HANDLE;
     if (win == self->lgrip)     return OB_FRAME_CONTEXT_BLCORNER;
index 147f59def0b3ee1e5e7cd37145129c6eb3e2fb9b..ebd8de982457afb76cf27b2f846ae9a4c450eae2 100644 (file)
@@ -136,6 +136,10 @@ struct _ObFrame
     gint      cbwidth_x;     /* client border width */
     gint      cbwidth_y;     /* client border width */
 
+    /* the leftmost and rightmost elements in the titlebar */
+    ObFrameContext leftmost;
+    ObFrameContext rightmost;
+
     gboolean  max_press;
     gboolean  close_press;
     gboolean  desk_press;
@@ -180,7 +184,8 @@ void frame_release_client(ObFrame *self);
 
 ObFrameContext frame_context_from_string(const gchar *name);
 
-ObFrameContext frame_context(struct _ObClient *self, Window win);
+ObFrameContext frame_context(struct _ObClient *self, Window win,
+                             gint x, gint y);
 
 /*! Applies gravity to the client's position to find where the frame should
   be positioned.
index 522eba8cbf9c8ccb27b241ae330c8ad4ab6c4083..9edda8ebf96aa05e7469ebe203feb6ac2f7cd2af 100644 (file)
@@ -179,7 +179,7 @@ void mouse_event(ObClient *client, XEvent *e)
     static Time ltime;
     static guint button = 0, state = 0, lbutton = 0;
     static Window lwindow = None;
-    static gint px, py;
+    static gint px, py, pwx = -1, pwy = -1;
 
     ObFrameContext context;
     gboolean click = FALSE;
@@ -187,11 +187,14 @@ void mouse_event(ObClient *client, XEvent *e)
 
     switch (e->type) {
     case ButtonPress:
-        context = frame_context(client, e->xany.window);
+        context = frame_context(client, e->xbutton.window,
+                                e->xbutton.x, e->xbutton.y);
         context = mouse_button_frame_context(context, e->xbutton.button);
 
         px = e->xbutton.x_root;
         py = e->xbutton.y_root;
+        if (pwx == -1) pwx = e->xbutton.x;
+        if (pwy == -1) pwy = e->xbutton.y;
         button = e->xbutton.button;
         state = e->xbutton.state;
 
@@ -209,9 +212,12 @@ void mouse_event(ObClient *client, XEvent *e)
             break;
 
     case ButtonRelease:
-        context = frame_context(client, e->xany.window);
+        /* use where the press occured in the window */
+        context = frame_context(client, e->xbutton.window, pwx, pwy);
         context = mouse_button_frame_context(context, e->xbutton.button);
 
+        pwx = pwy = -1;
+
         if (e->xbutton.button == button) {
             /* clicks are only valid if its released over the window */
             gint junk1, junk2;
@@ -272,7 +278,7 @@ void mouse_event(ObClient *client, XEvent *e)
 
     case MotionNotify:
         if (button) {
-            context = frame_context(client, e->xany.window);
+            context = frame_context(client, e->xmotion.window, pwx, pwy);
             context = mouse_button_frame_context(context, button);
 
             if (ABS(e->xmotion.x_root - px) >=
This page took 0.040736 seconds and 4 git commands to generate.