inline void client_action_start(union ActionData *data)
{
- if (config_focus_follow)
- if (data->any.context != OB_FRAME_CONTEXT_CLIENT && !data->any.button)
- grab_pointer(FALSE, FALSE, OB_CURSOR_NONE);
}
inline void client_action_end(union ActionData *data)
if (config_focus_follow)
if (data->any.context != OB_FRAME_CONTEXT_CLIENT) {
if (!data->any.button) {
- ungrab_pointer();
+ event_ignore_queued_enters();
} else {
ObClient *c;
OB_CLIENT_FUNC_SHADE |
OB_CLIENT_FUNC_CLOSE |
OB_CLIENT_FUNC_BELOW |
- OB_CLIENT_FUNC_ABOVE);
+ OB_CLIENT_FUNC_ABOVE |
+ OB_CLIENT_FUNC_UNDECORATE);
if (!(self->min_size.width < self->max_size.width ||
self->min_size.height < self->max_size.height))
if (self->max_vert && self->max_horz)
self->decorations &= ~(OB_FRAME_DECOR_HANDLE | OB_FRAME_DECOR_GRIPS);
+ /* If there are no decorations to remove, don't allow the user to try
+ toggle the state */
+ if (self->decorations == 0)
+ self->functions &= ~OB_CLIENT_FUNC_UNDECORATE;
+
/* finally, the user can have requested no decorations, which overrides
everything (but doesnt give it a border if it doesnt have one) */
if (self->undecorated) {
}
}
- /* Grab pointer across these, so it is the same as actions. Enter events
- won't be generated by the windows moving around */
- grab_pointer(FALSE, FALSE, OB_CURSOR_NONE);
-
if (max_horz != self->max_horz || max_vert != self->max_vert) {
if (max_horz != self->max_horz && max_vert != self->max_vert) {
/* toggling both */
transients needs to change */
stacking_raise(CLIENT_AS_WINDOW(self));
- /* These things below can change focus so we can't grab pointer for
- them. Note how we have two ungrab_pointers.. */
- ungrab_pointer();
-
/* it also may get focused. if something is focused that shouldn't
be focused anymore, then move the focus */
if (focus_client && client_focus_target(focus_client) != focus_client)
client_focus(focus_client);
}
- else
- /* These things below can change focus so we can't grab pointer for
- them. Note how we have two ungrab_pointers.. */
- ungrab_pointer();
if (iconic != self->iconic)
client_iconify(self, iconic, FALSE, FALSE);
void client_set_undecorated(ObClient *self, gboolean undecorated)
{
- if (self->undecorated != undecorated) {
+ if (self->undecorated != undecorated &&
+ /* don't let it undecorate if the function is missing, but let
+ it redecorate */
+ (self->functions & OB_CLIENT_FUNC_UNDECORATE || !undecorated))
+ {
self->undecorated = undecorated;
client_setup_decor_and_functions(self);
client_change_state(self); /* reflect this in the state hints */
OB_CLIENT_FUNC_FULLSCREEN = 1 << 5, /*!< Allow to be made fullscreen */
OB_CLIENT_FUNC_CLOSE = 1 << 6, /*!< Allow to be closed */
OB_CLIENT_FUNC_ABOVE = 1 << 7, /*!< Allow to be put in lower layer */
- OB_CLIENT_FUNC_BELOW = 1 << 8 /*!< Allow to be put in higher layer */
+ OB_CLIENT_FUNC_BELOW = 1 << 8, /*!< Allow to be put in higher layer */
+ OB_CLIENT_FUNC_UNDECORATE = 1 << 9 /*!< Allow to be undecorated */
} ObFunctions;
struct _ObClient
#include "openbox.h"
#include "frame.h"
#include "moveresize.h"
+#include "event.h"
#include "prop.h"
#include "gettext.h"
*en = c->functions & OB_CLIENT_FUNC_CLOSE;
break;
case CLIENT_DECORATE:
- *en = client_normal(c);
+ *en = c->functions & OB_CLIENT_FUNC_UNDECORATE;
break;
default:
*en = TRUE;
break;
case CLIENT_RESTORE:
client_maximize(c, FALSE, 0);
+ event_ignore_queued_enters();
break;
case CLIENT_MAXIMIZE:
client_maximize(c, TRUE, 0);
+ event_ignore_queued_enters();
break;
case CLIENT_SHADE:
client_shade(c, !c->shaded);
+ event_ignore_queued_enters();
break;
case CLIENT_DECORATE:
client_set_undecorated(c, !c->undecorated);
+ event_ignore_queued_enters();
break;
case CLIENT_MOVE:
/* this needs to grab the keyboard so hide the menu */
g_assert_not_reached();
}
+ event_ignore_queued_enters();
+
/* update the menu cuz stuff can have changed */
if (f) {
layer_menu_update(f, NULL);
if (config) {
client_find_onscreen(client, &x, &y, w, h, FALSE);
-
- /* don't create enter events from clients moving themselves */
- grab_pointer(FALSE, FALSE, OB_CURSOR_NONE);
client_configure(client, x, y, w, h, FALSE, TRUE);
- ungrab_pointer();
+
+ /* ignore enter events caused by these like ob actions do */
+ event_ignore_queued_enters();
}
break;
}
client->window);
client_set_state(client, e->xclient.data.l[0],
e->xclient.data.l[1], e->xclient.data.l[2]);
+
+ /* ignore enter events caused by these like ob actions do */
+ event_ignore_queued_enters();
} else if (msgtype == prop_atoms.net_close_window) {
ob_debug("net_close_window for 0x%lx\n", client->window);
client_close(client);
client_convert_gravity(client, grav, &x, &y, w, h);
client_find_onscreen(client, &x, &y, w, h, FALSE);
- /* don't create enter events from clients moving themselves */
- grab_pointer(FALSE, FALSE, OB_CURSOR_NONE);
client_configure(client, x, y, w, h, FALSE, TRUE);
- ungrab_pointer();
+
+ /* ignore enter events caused by these like ob actions do */
+ event_ignore_queued_enters();
} else if (msgtype == prop_atoms.net_restack_window) {
if (e->xclient.data.l[0] != 2) {
ob_debug_type(OB_DEBUG_APP_BUGS,
comes at the same time or later than t2. */
gboolean event_time_after(Time t1, Time t2);
-/*! Used with XCheckIfEvent to find a focusin event on a client window */
-Bool event_look_for_focusin_client(Display *d, XEvent *e, XPointer arg);
-
#endif