when a window is fully maxed, make clicking on the titlebar past the edge buttons count as clicking on the buttons

This commit is contained in:
Dana Jansens 2007-05-09 22:21:28 +00:00
parent 6042ba5e99
commit 66afa1dceb
5 changed files with 73 additions and 14 deletions

View 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) */

View 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;

View 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;

View 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.

View 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) >=