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:
parent
6042ba5e99
commit
66afa1dceb
5 changed files with 73 additions and 14 deletions
|
@ -1664,7 +1664,7 @@ void client_setup_decor_and_functions(ObClient *self)
|
||||||
|
|
||||||
/* kill the handle on fully maxed windows */
|
/* kill the handle on fully maxed windows */
|
||||||
if (self->max_vert && self->max_horz)
|
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
|
/* finally, the user can have requested no decorations, which overrides
|
||||||
everything (but doesnt give it a border if it doesnt have one) */
|
everything (but doesnt give it a border if it doesnt have one) */
|
||||||
|
|
|
@ -729,9 +729,13 @@ static void event_handle_client(ObClient *client, XEvent *e)
|
||||||
XEvent ce;
|
XEvent ce;
|
||||||
Atom msgtype;
|
Atom msgtype;
|
||||||
ObFrameContext con;
|
ObFrameContext con;
|
||||||
|
static gint px = -1, py = -1;
|
||||||
|
|
||||||
switch (e->type) {
|
switch (e->type) {
|
||||||
case ButtonPress:
|
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:
|
case ButtonRelease:
|
||||||
/* Wheel buttons don't draw because they are an instant click, so it
|
/* Wheel buttons don't draw because they are an instant click, so it
|
||||||
is a waste of resources to go drawing 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() &&
|
!keyboard_interactively_grabbed() &&
|
||||||
!menu_frame_visible)
|
!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);
|
con = mouse_button_frame_context(con, e->xbutton.button);
|
||||||
|
|
||||||
|
if (e->type == ButtonRelease)
|
||||||
|
px = py = -1;
|
||||||
|
|
||||||
switch (con) {
|
switch (con) {
|
||||||
case OB_FRAME_CONTEXT_MAXIMIZE:
|
case OB_FRAME_CONTEXT_MAXIMIZE:
|
||||||
client->frame->max_press = (e->type == ButtonPress);
|
client->frame->max_press = (e->type == ButtonPress);
|
||||||
|
@ -773,7 +782,8 @@ static void event_handle_client(ObClient *client, XEvent *e)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LeaveNotify:
|
case LeaveNotify:
|
||||||
con = frame_context(client, e->xcrossing.window);
|
con = frame_context(client, e->xcrossing.window,
|
||||||
|
e->xcrossing.x, e->xcrossing.y);
|
||||||
switch (con) {
|
switch (con) {
|
||||||
case OB_FRAME_CONTEXT_MAXIMIZE:
|
case OB_FRAME_CONTEXT_MAXIMIZE:
|
||||||
client->frame->max_hover = FALSE;
|
client->frame->max_hover = FALSE;
|
||||||
|
@ -833,7 +843,8 @@ static void event_handle_client(ObClient *client, XEvent *e)
|
||||||
nofocus = TRUE;
|
nofocus = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
con = frame_context(client, e->xcrossing.window);
|
con = frame_context(client, e->xcrossing.window,
|
||||||
|
e->xcrossing.x, e->xcrossing.y);
|
||||||
switch (con) {
|
switch (con) {
|
||||||
case OB_FRAME_CONTEXT_MAXIMIZE:
|
case OB_FRAME_CONTEXT_MAXIMIZE:
|
||||||
client->frame->max_hover = TRUE;
|
client->frame->max_hover = TRUE;
|
||||||
|
|
|
@ -683,7 +683,7 @@ static gboolean is_button_present(ObFrame *self, const gchar *lc, gint dir) {
|
||||||
static void layout_title(ObFrame *self)
|
static void layout_title(ObFrame *self)
|
||||||
{
|
{
|
||||||
gchar *lc;
|
gchar *lc;
|
||||||
gint i, x;
|
gint i;
|
||||||
|
|
||||||
const gint bwidth = ob_rr_theme->button_size + ob_rr_theme->paddingx + 1;
|
const gint bwidth = ob_rr_theme->button_size + ob_rr_theme->paddingx + 1;
|
||||||
/* position of the left most button */
|
/* 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->icon_on = self->desk_on = self->shade_on = self->iconify_on =
|
||||||
self->max_on = self->close_on = self->label_on = FALSE;
|
self->max_on = self->close_on = self->label_on = FALSE;
|
||||||
self->label_width = self->width - (ob_rr_theme->paddingx + 1) * 2;
|
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
|
/* figure out what's being show, find each element's position, and the
|
||||||
width of the label
|
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,
|
i will be +1 the first time through when working to the left,
|
||||||
and -1 the second time through when working to the right */
|
and -1 the second time through when working to the right */
|
||||||
for (i = 1; i >= -1; i-=2) {
|
for (i = 1; i >= -1; i-=2) {
|
||||||
|
gint x;
|
||||||
|
ObFrameContext *firstcon;
|
||||||
|
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
x = left;
|
x = left;
|
||||||
lc = config_title_layout;
|
lc = config_title_layout;
|
||||||
|
firstcon = &self->leftmost;
|
||||||
} else {
|
} else {
|
||||||
x = right;
|
x = right;
|
||||||
lc = config_title_layout + strlen(config_title_layout)-1;
|
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) */
|
/* 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 (*lc == 'L') {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
self->label_on = TRUE;
|
self->label_on = TRUE;
|
||||||
|
@ -720,6 +726,7 @@ static void layout_title(ObFrame *self)
|
||||||
}
|
}
|
||||||
break; /* break the for loop, do other side of label */
|
break; /* break the for loop, do other side of label */
|
||||||
} else if (*lc == 'N') {
|
} else if (*lc == 'N') {
|
||||||
|
if (firstcon) *firstcon = OB_FRAME_CONTEXT_ICON;
|
||||||
if ((self->icon_on = is_button_present(self, lc, i))) {
|
if ((self->icon_on = is_button_present(self, lc, i))) {
|
||||||
/* icon gets extra padding */
|
/* icon gets extra padding */
|
||||||
self->label_width -= bwidth + 2;
|
self->label_width -= bwidth + 2;
|
||||||
|
@ -727,35 +734,43 @@ static void layout_title(ObFrame *self)
|
||||||
x += i * (bwidth + 2);
|
x += i * (bwidth + 2);
|
||||||
}
|
}
|
||||||
} else if (*lc == 'D') {
|
} else if (*lc == 'D') {
|
||||||
|
if (firstcon) *firstcon = OB_FRAME_CONTEXT_ALLDESKTOPS;
|
||||||
if ((self->desk_on = is_button_present(self, lc, i))) {
|
if ((self->desk_on = is_button_present(self, lc, i))) {
|
||||||
self->label_width -= bwidth;
|
self->label_width -= bwidth;
|
||||||
self->desk_x = x;
|
self->desk_x = x;
|
||||||
x += i * bwidth;
|
x += i * bwidth;
|
||||||
}
|
}
|
||||||
} else if (*lc == 'S') {
|
} else if (*lc == 'S') {
|
||||||
|
if (firstcon) *firstcon = OB_FRAME_CONTEXT_SHADE;
|
||||||
if ((self->shade_on = is_button_present(self, lc, i))) {
|
if ((self->shade_on = is_button_present(self, lc, i))) {
|
||||||
self->label_width -= bwidth;
|
self->label_width -= bwidth;
|
||||||
self->shade_x = x;
|
self->shade_x = x;
|
||||||
x += i * bwidth;
|
x += i * bwidth;
|
||||||
}
|
}
|
||||||
} else if (*lc == 'I') {
|
} else if (*lc == 'I') {
|
||||||
|
if (firstcon) *firstcon = OB_FRAME_CONTEXT_ICONIFY;
|
||||||
if ((self->iconify_on = is_button_present(self, lc, i))) {
|
if ((self->iconify_on = is_button_present(self, lc, i))) {
|
||||||
self->label_width -= bwidth;
|
self->label_width -= bwidth;
|
||||||
self->iconify_x = x;
|
self->iconify_x = x;
|
||||||
x += i * bwidth;
|
x += i * bwidth;
|
||||||
}
|
}
|
||||||
} else if (*lc == 'M') {
|
} else if (*lc == 'M') {
|
||||||
|
if (firstcon) *firstcon = OB_FRAME_CONTEXT_MAXIMIZE;
|
||||||
if ((self->max_on = is_button_present(self, lc, i))) {
|
if ((self->max_on = is_button_present(self, lc, i))) {
|
||||||
self->label_width -= bwidth;
|
self->label_width -= bwidth;
|
||||||
self->max_x = x;
|
self->max_x = x;
|
||||||
x += i * bwidth;
|
x += i * bwidth;
|
||||||
}
|
}
|
||||||
} else if (*lc == 'C') {
|
} else if (*lc == 'C') {
|
||||||
|
if (firstcon) *firstcon = OB_FRAME_CONTEXT_CLOSE;
|
||||||
if ((self->close_on = is_button_present(self, lc, i))) {
|
if ((self->close_on = is_button_present(self, lc, i))) {
|
||||||
self->label_width -= bwidth;
|
self->label_width -= bwidth;
|
||||||
self->close_x = x;
|
self->close_x = x;
|
||||||
x += i * bwidth;
|
x += i * bwidth;
|
||||||
}
|
}
|
||||||
|
} else
|
||||||
|
continue; /* don't set firstcon */
|
||||||
|
firstcon = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -848,7 +863,7 @@ ObFrameContext frame_context_from_string(const gchar *name)
|
||||||
return OB_FRAME_CONTEXT_NONE;
|
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;
|
ObFrame *self;
|
||||||
|
|
||||||
|
@ -875,8 +890,30 @@ ObFrameContext frame_context(ObClient *client, Window win)
|
||||||
return OB_FRAME_CONTEXT_CLIENT;
|
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->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->label) return OB_FRAME_CONTEXT_TITLEBAR;
|
||||||
if (win == self->handle) return OB_FRAME_CONTEXT_HANDLE;
|
if (win == self->handle) return OB_FRAME_CONTEXT_HANDLE;
|
||||||
if (win == self->lgrip) return OB_FRAME_CONTEXT_BLCORNER;
|
if (win == self->lgrip) return OB_FRAME_CONTEXT_BLCORNER;
|
||||||
|
|
|
@ -136,6 +136,10 @@ struct _ObFrame
|
||||||
gint cbwidth_x; /* client border width */
|
gint cbwidth_x; /* client border width */
|
||||||
gint cbwidth_y; /* 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 max_press;
|
||||||
gboolean close_press;
|
gboolean close_press;
|
||||||
gboolean desk_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_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
|
/*! Applies gravity to the client's position to find where the frame should
|
||||||
be positioned.
|
be positioned.
|
||||||
|
|
|
@ -179,7 +179,7 @@ void mouse_event(ObClient *client, XEvent *e)
|
||||||
static Time ltime;
|
static Time ltime;
|
||||||
static guint button = 0, state = 0, lbutton = 0;
|
static guint button = 0, state = 0, lbutton = 0;
|
||||||
static Window lwindow = None;
|
static Window lwindow = None;
|
||||||
static gint px, py;
|
static gint px, py, pwx = -1, pwy = -1;
|
||||||
|
|
||||||
ObFrameContext context;
|
ObFrameContext context;
|
||||||
gboolean click = FALSE;
|
gboolean click = FALSE;
|
||||||
|
@ -187,11 +187,14 @@ void mouse_event(ObClient *client, XEvent *e)
|
||||||
|
|
||||||
switch (e->type) {
|
switch (e->type) {
|
||||||
case ButtonPress:
|
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);
|
context = mouse_button_frame_context(context, e->xbutton.button);
|
||||||
|
|
||||||
px = e->xbutton.x_root;
|
px = e->xbutton.x_root;
|
||||||
py = e->xbutton.y_root;
|
py = e->xbutton.y_root;
|
||||||
|
if (pwx == -1) pwx = e->xbutton.x;
|
||||||
|
if (pwy == -1) pwy = e->xbutton.y;
|
||||||
button = e->xbutton.button;
|
button = e->xbutton.button;
|
||||||
state = e->xbutton.state;
|
state = e->xbutton.state;
|
||||||
|
|
||||||
|
@ -209,9 +212,12 @@ void mouse_event(ObClient *client, XEvent *e)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ButtonRelease:
|
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);
|
context = mouse_button_frame_context(context, e->xbutton.button);
|
||||||
|
|
||||||
|
pwx = pwy = -1;
|
||||||
|
|
||||||
if (e->xbutton.button == button) {
|
if (e->xbutton.button == button) {
|
||||||
/* clicks are only valid if its released over the window */
|
/* clicks are only valid if its released over the window */
|
||||||
gint junk1, junk2;
|
gint junk1, junk2;
|
||||||
|
@ -272,7 +278,7 @@ void mouse_event(ObClient *client, XEvent *e)
|
||||||
|
|
||||||
case MotionNotify:
|
case MotionNotify:
|
||||||
if (button) {
|
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);
|
context = mouse_button_frame_context(context, button);
|
||||||
|
|
||||||
if (ABS(e->xmotion.x_root - px) >=
|
if (ABS(e->xmotion.x_root - px) >=
|
||||||
|
|
Loading…
Reference in a new issue