handle focus in the kernel, no more plugin
This commit is contained in:
parent
eee483bb47
commit
bf32b376b5
4 changed files with 58 additions and 40 deletions
|
@ -2,6 +2,7 @@
|
|||
#include "screen.h"
|
||||
#include "prop.h"
|
||||
#include "extensions.h"
|
||||
#include "config.h"
|
||||
#include "frame.h"
|
||||
#include "engine.h"
|
||||
#include "event.h"
|
||||
|
@ -86,6 +87,7 @@ void client_set_list()
|
|||
|
||||
void client_manage_all()
|
||||
{
|
||||
ConfigValue focus_new;
|
||||
unsigned int i, j, nchild;
|
||||
Window w, *children;
|
||||
XWMHints *wmhints;
|
||||
|
@ -136,6 +138,11 @@ void client_manage_all()
|
|||
g_free(client_startup_stack_order);
|
||||
client_startup_stack_order = NULL;
|
||||
client_startup_stack_size = 0;
|
||||
|
||||
if (!config_get("focusNew", Config_Bool, &focus_new))
|
||||
g_assert_not_reached();
|
||||
if (focus_new.bool)
|
||||
focus_fallback(FALSE);
|
||||
}
|
||||
|
||||
void client_manage(Window window)
|
||||
|
@ -146,6 +153,7 @@ void client_manage(Window window)
|
|||
XSetWindowAttributes attrib_set;
|
||||
/* XWMHints *wmhint; */
|
||||
guint i;
|
||||
ConfigValue focus_new;
|
||||
|
||||
grab_server(TRUE);
|
||||
|
||||
|
@ -232,6 +240,11 @@ void client_manage(Window window)
|
|||
|
||||
dispatch_client(Event_Client_Mapped, client, 0, 0);
|
||||
|
||||
if (!config_get("focusNew", Config_Bool, &focus_new))
|
||||
g_assert_not_reached();
|
||||
if (ob_state != State_Starting && focus_new.bool)
|
||||
client_focus(client);
|
||||
|
||||
/* update the list hints */
|
||||
client_set_list();
|
||||
|
||||
|
@ -1934,7 +1947,7 @@ gboolean client_focus(Client *self)
|
|||
}
|
||||
|
||||
if (self->can_focus)
|
||||
XSetInputFocus(ob_display, self->window, RevertToNone,
|
||||
XSetInputFocus(ob_display, self->window, RevertToPointerRoot,
|
||||
event_lasttime);
|
||||
|
||||
if (self->focus_notify) {
|
||||
|
@ -1952,14 +1965,19 @@ gboolean client_focus(Client *self)
|
|||
XSendEvent(ob_display, self->window, FALSE, NoEventMask, &ce);
|
||||
}
|
||||
|
||||
/* XSync(ob_display, FALSE); XXX Why sync? */
|
||||
g_message("focusing %lx", self->window);
|
||||
|
||||
/* Cause the FocusIn to come back to us. Important for desktop switches,
|
||||
since otherwise we'll have no FocusIn on the queue and send it off to
|
||||
the focus_backup. */
|
||||
XSync(ob_display, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void client_unfocus(Client *self)
|
||||
{
|
||||
g_assert(focus_client == self);
|
||||
client_set_focused(self, FALSE);
|
||||
focus_fallback(FALSE);
|
||||
}
|
||||
|
||||
gboolean client_focused(Client *self)
|
||||
|
@ -1967,23 +1985,6 @@ gboolean client_focused(Client *self)
|
|||
return self == focus_client;
|
||||
}
|
||||
|
||||
void client_set_focused(Client *self, gboolean focused)
|
||||
{
|
||||
if (focused) {
|
||||
if (focus_client != self)
|
||||
focus_set_client(self);
|
||||
} else {
|
||||
event_unfocustime = event_lasttime;
|
||||
if (focus_client == self)
|
||||
focus_set_client(NULL);
|
||||
}
|
||||
|
||||
/* focus state can affect the stacking layer */
|
||||
client_calc_layer(self);
|
||||
|
||||
engine_frame_adjust_focus(self->frame);
|
||||
}
|
||||
|
||||
Icon *client_icon(Client *self, int w, int h)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -320,11 +320,6 @@ gboolean client_normal(Client *self);
|
|||
/* Returns if the window is focused */
|
||||
gboolean client_focused(Client *self);
|
||||
|
||||
/*! Sets the client to a focused or unfocused state. This does not actually
|
||||
change the input focus, but rather is used once focus has been moved to tell
|
||||
the client that it is so. */
|
||||
void client_set_focused(Client *self, gboolean focused);
|
||||
|
||||
/*! Move and/or resize the window.
|
||||
This also maintains things like the client's minsize, and size increments.
|
||||
@param anchor The corner to keep in the same position when resizing.
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "openbox.h"
|
||||
#include "client.h"
|
||||
#include "config.h"
|
||||
#include "xerror.h"
|
||||
#include "prop.h"
|
||||
#include "screen.h"
|
||||
|
@ -24,7 +25,6 @@ static void event_handle_root(XEvent *e);
|
|||
static void event_handle_client(Client *c, XEvent *e);
|
||||
|
||||
Time event_lasttime = 0;
|
||||
Time event_unfocustime = 0;
|
||||
|
||||
/*! The value of the mask for the NumLock modifier */
|
||||
unsigned int NumLockMask;
|
||||
|
@ -221,17 +221,21 @@ void event_process(XEvent *e)
|
|||
event_lasttime = e->xproperty.time;
|
||||
break;
|
||||
case FocusIn:
|
||||
if (e->xfocus.mode == NotifyGrab ||
|
||||
!(e->xfocus.detail == NotifyNonlinearVirtual ||
|
||||
e->xfocus.detail == NotifyNonlinear))
|
||||
return;
|
||||
g_message("FocusIn on %lx mode %d detail %d", window,
|
||||
e->xfocus.mode, e->xfocus.detail);
|
||||
if (e->xfocus.detail == NotifyInferior ||
|
||||
e->xfocus.detail == NotifyAncestor ||
|
||||
e->xfocus.detail > NotifyNonlinearVirtual) return;
|
||||
g_message("FocusIn on %lx", window);*/
|
||||
break;
|
||||
case FocusOut:
|
||||
if (e->xfocus.mode == NotifyGrab ||
|
||||
!(e->xfocus.detail == NotifyNonlinearVirtual ||
|
||||
e->xfocus.detail == NotifyNonlinear))
|
||||
return;
|
||||
g_message("FocusOut on %lx mode %d detail %d", window,
|
||||
e->xfocus.mode, e->xfocus.detail);
|
||||
if (e->xfocus.detail == NotifyInferior ||
|
||||
e->xfocus.detail == NotifyAncestor ||
|
||||
e->xfocus.detail > NotifyNonlinearVirtual) return;
|
||||
|
||||
g_message("FocusOut on %lx", window);
|
||||
/* FocusOut events just make us look for FocusIn events. They
|
||||
are mostly ignored otherwise. */
|
||||
{
|
||||
|
@ -241,7 +245,8 @@ void event_process(XEvent *e)
|
|||
|
||||
if (fi.xfocus.window == e->xfocus.window)
|
||||
return;
|
||||
}
|
||||
} else
|
||||
focus_set_client(NULL);
|
||||
}
|
||||
break;
|
||||
case EnterNotify:
|
||||
|
@ -325,11 +330,31 @@ static void event_handle_client(Client *client, XEvent *e)
|
|||
XEvent ce;
|
||||
Atom msgtype;
|
||||
int i=0;
|
||||
ConfigValue focus_follow;
|
||||
|
||||
switch (e->type) {
|
||||
case FocusIn:
|
||||
focus_set_client(client);
|
||||
case FocusOut:
|
||||
client_set_focused(client, e->type == FocusIn);
|
||||
g_message("Focus%s on client for %lx", (e->type==FocusIn?"In":"Out"),
|
||||
client->window);
|
||||
/* focus state can affect the stacking layer */
|
||||
client_calc_layer(client);
|
||||
engine_frame_adjust_focus(client->frame);
|
||||
break;
|
||||
case EnterNotify:
|
||||
if (ob_state == State_Starting) {
|
||||
/* move it to the top of the focus order */
|
||||
guint desktop = client->desktop;
|
||||
if (desktop == DESKTOP_ALL) desktop = screen_desktop;
|
||||
focus_order[desktop] = g_list_remove(focus_order[desktop], client);
|
||||
focus_order[desktop] = g_list_prepend(focus_order[desktop],client);
|
||||
} else {
|
||||
if (!config_get("focusFollowsMouse", Config_Bool, &focus_follow))
|
||||
g_assert_not_reached();
|
||||
if (focus_follow.bool)
|
||||
client_focus(client);
|
||||
}
|
||||
break;
|
||||
case ConfigureRequest:
|
||||
/* compress these */
|
||||
|
|
|
@ -5,9 +5,6 @@
|
|||
|
||||
/*! Time at which the last event with a timestamp occured. */
|
||||
extern Time event_lasttime;
|
||||
/*! Time at which the last event with a timestamp occured before we tried to
|
||||
unfocus a window. */
|
||||
extern Time event_unfocustime;
|
||||
|
||||
/*! The value of the mask for the NumLock modifier */
|
||||
extern unsigned int NumLockMask;
|
||||
|
|
Loading…
Reference in a new issue