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 "screen.h"
|
||||||
#include "prop.h"
|
#include "prop.h"
|
||||||
#include "extensions.h"
|
#include "extensions.h"
|
||||||
|
#include "config.h"
|
||||||
#include "frame.h"
|
#include "frame.h"
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
|
@ -86,6 +87,7 @@ void client_set_list()
|
||||||
|
|
||||||
void client_manage_all()
|
void client_manage_all()
|
||||||
{
|
{
|
||||||
|
ConfigValue focus_new;
|
||||||
unsigned int i, j, nchild;
|
unsigned int i, j, nchild;
|
||||||
Window w, *children;
|
Window w, *children;
|
||||||
XWMHints *wmhints;
|
XWMHints *wmhints;
|
||||||
|
@ -136,6 +138,11 @@ void client_manage_all()
|
||||||
g_free(client_startup_stack_order);
|
g_free(client_startup_stack_order);
|
||||||
client_startup_stack_order = NULL;
|
client_startup_stack_order = NULL;
|
||||||
client_startup_stack_size = 0;
|
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)
|
void client_manage(Window window)
|
||||||
|
@ -146,6 +153,7 @@ void client_manage(Window window)
|
||||||
XSetWindowAttributes attrib_set;
|
XSetWindowAttributes attrib_set;
|
||||||
/* XWMHints *wmhint; */
|
/* XWMHints *wmhint; */
|
||||||
guint i;
|
guint i;
|
||||||
|
ConfigValue focus_new;
|
||||||
|
|
||||||
grab_server(TRUE);
|
grab_server(TRUE);
|
||||||
|
|
||||||
|
@ -232,6 +240,11 @@ void client_manage(Window window)
|
||||||
|
|
||||||
dispatch_client(Event_Client_Mapped, client, 0, 0);
|
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 */
|
/* update the list hints */
|
||||||
client_set_list();
|
client_set_list();
|
||||||
|
|
||||||
|
@ -1934,7 +1947,7 @@ gboolean client_focus(Client *self)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->can_focus)
|
if (self->can_focus)
|
||||||
XSetInputFocus(ob_display, self->window, RevertToNone,
|
XSetInputFocus(ob_display, self->window, RevertToPointerRoot,
|
||||||
event_lasttime);
|
event_lasttime);
|
||||||
|
|
||||||
if (self->focus_notify) {
|
if (self->focus_notify) {
|
||||||
|
@ -1952,14 +1965,19 @@ gboolean client_focus(Client *self)
|
||||||
XSendEvent(ob_display, self->window, FALSE, NoEventMask, &ce);
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_unfocus(Client *self)
|
void client_unfocus(Client *self)
|
||||||
{
|
{
|
||||||
g_assert(focus_client == self);
|
g_assert(focus_client == self);
|
||||||
client_set_focused(self, FALSE);
|
focus_fallback(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean client_focused(Client *self)
|
gboolean client_focused(Client *self)
|
||||||
|
@ -1967,23 +1985,6 @@ gboolean client_focused(Client *self)
|
||||||
return self == focus_client;
|
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)
|
Icon *client_icon(Client *self, int w, int h)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -320,11 +320,6 @@ gboolean client_normal(Client *self);
|
||||||
/* Returns if the window is focused */
|
/* Returns if the window is focused */
|
||||||
gboolean client_focused(Client *self);
|
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.
|
/*! Move and/or resize the window.
|
||||||
This also maintains things like the client's minsize, and size increments.
|
This also maintains things like the client's minsize, and size increments.
|
||||||
@param anchor The corner to keep in the same position when resizing.
|
@param anchor The corner to keep in the same position when resizing.
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "openbox.h"
|
#include "openbox.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
|
#include "config.h"
|
||||||
#include "xerror.h"
|
#include "xerror.h"
|
||||||
#include "prop.h"
|
#include "prop.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
|
@ -24,7 +25,6 @@ static void event_handle_root(XEvent *e);
|
||||||
static void event_handle_client(Client *c, XEvent *e);
|
static void event_handle_client(Client *c, XEvent *e);
|
||||||
|
|
||||||
Time event_lasttime = 0;
|
Time event_lasttime = 0;
|
||||||
Time event_unfocustime = 0;
|
|
||||||
|
|
||||||
/*! The value of the mask for the NumLock modifier */
|
/*! The value of the mask for the NumLock modifier */
|
||||||
unsigned int NumLockMask;
|
unsigned int NumLockMask;
|
||||||
|
@ -221,17 +221,21 @@ void event_process(XEvent *e)
|
||||||
event_lasttime = e->xproperty.time;
|
event_lasttime = e->xproperty.time;
|
||||||
break;
|
break;
|
||||||
case FocusIn:
|
case FocusIn:
|
||||||
if (e->xfocus.mode == NotifyGrab ||
|
g_message("FocusIn on %lx mode %d detail %d", window,
|
||||||
!(e->xfocus.detail == NotifyNonlinearVirtual ||
|
e->xfocus.mode, e->xfocus.detail);
|
||||||
e->xfocus.detail == NotifyNonlinear))
|
if (e->xfocus.detail == NotifyInferior ||
|
||||||
return;
|
e->xfocus.detail == NotifyAncestor ||
|
||||||
|
e->xfocus.detail > NotifyNonlinearVirtual) return;
|
||||||
|
g_message("FocusIn on %lx", window);*/
|
||||||
break;
|
break;
|
||||||
case FocusOut:
|
case FocusOut:
|
||||||
if (e->xfocus.mode == NotifyGrab ||
|
g_message("FocusOut on %lx mode %d detail %d", window,
|
||||||
!(e->xfocus.detail == NotifyNonlinearVirtual ||
|
e->xfocus.mode, e->xfocus.detail);
|
||||||
e->xfocus.detail == NotifyNonlinear))
|
if (e->xfocus.detail == NotifyInferior ||
|
||||||
return;
|
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
|
/* FocusOut events just make us look for FocusIn events. They
|
||||||
are mostly ignored otherwise. */
|
are mostly ignored otherwise. */
|
||||||
{
|
{
|
||||||
|
@ -241,7 +245,8 @@ void event_process(XEvent *e)
|
||||||
|
|
||||||
if (fi.xfocus.window == e->xfocus.window)
|
if (fi.xfocus.window == e->xfocus.window)
|
||||||
return;
|
return;
|
||||||
}
|
} else
|
||||||
|
focus_set_client(NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EnterNotify:
|
case EnterNotify:
|
||||||
|
@ -324,13 +329,33 @@ static void event_handle_client(Client *client, XEvent *e)
|
||||||
{
|
{
|
||||||
XEvent ce;
|
XEvent ce;
|
||||||
Atom msgtype;
|
Atom msgtype;
|
||||||
int i=0;
|
int i=0;
|
||||||
|
ConfigValue focus_follow;
|
||||||
|
|
||||||
switch (e->type) {
|
switch (e->type) {
|
||||||
case FocusIn:
|
case FocusIn:
|
||||||
|
focus_set_client(client);
|
||||||
case FocusOut:
|
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;
|
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:
|
case ConfigureRequest:
|
||||||
/* compress these */
|
/* compress these */
|
||||||
while (XCheckTypedWindowEvent(ob_display, client->window,
|
while (XCheckTypedWindowEvent(ob_display, client->window,
|
||||||
|
|
|
@ -5,9 +5,6 @@
|
||||||
|
|
||||||
/*! Time at which the last event with a timestamp occured. */
|
/*! Time at which the last event with a timestamp occured. */
|
||||||
extern Time event_lasttime;
|
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 */
|
/*! The value of the mask for the NumLock modifier */
|
||||||
extern unsigned int NumLockMask;
|
extern unsigned int NumLockMask;
|
||||||
|
|
Loading…
Reference in a new issue