add the activate action. it will replace the focus action, as it can just focus without raising now (or without unshading)

This commit is contained in:
Dana Jansens 2007-06-22 04:59:06 +00:00
parent fbc7607fbd
commit 29c4cf4a15
12 changed files with 119 additions and 60 deletions

View file

@ -156,6 +156,7 @@ openbox_openbox_SOURCES = \
gettext.h \
openbox/actions/all.c \
openbox/actions/all.h \
openbox/actions/activate.c \
openbox/actions/cyclewindows.c \
openbox/actions/debug.c \
openbox/actions/execute.c \

View file

@ -498,11 +498,6 @@ ActionString actionstrings[] =
action_directional_focus,
setup_action_directional_focus_northwest
},
{
"activate",
action_activate,
setup_action_focus
},
{
"focus",
action_focus,
@ -965,9 +960,6 @@ ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
if ((n = parse_find_node("dialog", node->xmlChildrenNode)))
act->data.sendtodir.inter.any.interactive =
parse_bool(doc, n);
} else if (act->func == action_activate) {
if ((n = parse_find_node("here", node->xmlChildrenNode)))
act->data.activate.here = parse_bool(doc, n);
} else if (act->func == action_directional_focus) {
if ((n = parse_find_node("dialog", node->xmlChildrenNode)))
act->data.interdiraction.dialog = parse_bool(doc, n);
@ -1118,27 +1110,6 @@ void action_run_string(const gchar *name, struct _ObClient *c, Time time)
action_run(l, c, 0, time);
}
void action_activate(union ActionData *data)
{
if (data->client.any.c) {
if (!data->any.button || client_mouse_focusable(data->client.any.c) ||
(data->any.context != OB_FRAME_CONTEXT_CLIENT &&
data->any.context != OB_FRAME_CONTEXT_FRAME))
{
/* if using focus_delay, stop the timer now so that focus doesn't
go moving on us */
event_halt_focus_delay();
client_activate(data->activate.any.c, data->activate.here, TRUE);
}
} else {
/* focus action on something other than a client, make keybindings
work for this openbox instance, but don't focus any specific client
*/
focus_nothing();
}
}
void action_focus(union ActionData *data)
{
if (data->client.any.c) {

View file

@ -0,0 +1,79 @@
#include "openbox/actions.h"
#include "openbox/event.h"
#include "openbox/client.h"
#include "openbox/focus.h"
typedef struct {
gboolean here;
gboolean raise;
gboolean unshade;
} Options;
static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
static void free_func(gpointer options);
static gboolean run_func(ObActionsData *data, gpointer options);
void action_activate_startup()
{
actions_register("Activate",
setup_func,
free_func,
run_func,
NULL, NULL);
}
static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
{
xmlNodePtr n;
Options *o;
o = g_new0(Options, 1);
o->raise = TRUE;
o->unshade = TRUE;
if ((n = parse_find_node("here", node)))
o->here = parse_bool(doc, n);
if ((n = parse_find_node("raise", node)))
o->raise = parse_bool(doc, n);
if ((n = parse_find_node("unshade", node)))
o->unshade = parse_bool(doc, n);
return o;
}
static void free_func(gpointer options)
{
Options *o = options;
g_free(o);
}
/* Always return FALSE because its not interactive */
static gboolean run_func(ObActionsData *data, gpointer options)
{
Options *o = options;
if (data->client) {
gboolean mouse = (data->uact == OB_USER_ACTION_MOUSE_PRESS ||
data->uact == OB_USER_ACTION_MOUSE_RELEASE ||
data->uact == OB_USER_ACTION_MOUSE_CLICK ||
data->uact == OB_USER_ACTION_MOUSE_DOUBLE_CLICK ||
data->uact == OB_USER_ACTION_MOUSE_MOTION);
if (!mouse || client_mouse_focusable(data->client) ||
data->context != OB_FRAME_CONTEXT_CLIENT ||
data->context != OB_FRAME_CONTEXT_FRAME)
{
/* if using focus_delay, stop the timer now so that focus doesn't
go moving on us */
event_halt_focus_delay();
client_activate(data->client, o->here, o->raise, o->unshade, TRUE);
}
} else {
/* focus action on something other than a client, make keybindings
work for this openbox instance, but don't focus any specific client
*/
focus_nothing();
}
return FALSE;
}

View file

@ -10,4 +10,5 @@ void action_all_startup()
action_exit_startup();
action_restart_startup();
action_cyclewindows_startup();
action_activate_startup();
}

View file

@ -11,5 +11,6 @@ void action_reconfigure_startup();
void action_exit_startup();
void action_restart_startup();
void action_cyclewindows_startup();
void action_activate_startup();
#endif

View file

@ -88,7 +88,8 @@ static void client_update_transient_tree(ObClient *self,
gboolean oldgtran, gboolean newgtran,
ObClient* oldparent,
ObClient *newparent);
static void client_present(ObClient *self, gboolean here, gboolean raise);
static void client_present(ObClient *self, gboolean here, gboolean raise,
gboolean unshade);
static GSList *client_search_all_top_parents_internal(ObClient *self,
gboolean bylayer,
ObStackingLayer layer);
@ -544,7 +545,7 @@ void client_manage(Window window)
if (activate) {
gboolean stacked = client_restore_session_stacking(self);
client_present(self, FALSE, !stacked);
client_present(self, FALSE, !stacked, TRUE);
}
/* add to client list/map */
@ -3561,6 +3562,10 @@ gboolean client_focus(ObClient *self)
"Focusing client \"%s\" (0x%x) at time %u\n",
self->title, self->window, event_curtime);
/* if using focus_delay, stop the timer now so that focus doesn't
go moving on us */
event_halt_focus_delay();
/* if there is a grab going on, then we need to cancel it. if we move
focus during the grab, applications will get NotifyWhileGrabbed events
and ignore them !
@ -3601,17 +3606,9 @@ gboolean client_focus(ObClient *self)
return !xerror_occured;
}
/*! Present the client to the user.
@param raise If the client should be raised or not. You should only set
raise to false if you don't care if the window is completely
hidden.
*/
static void client_present(ObClient *self, gboolean here, gboolean raise)
static void client_present(ObClient *self, gboolean here, gboolean raise,
gboolean unshade)
{
/* if using focus_delay, stop the timer now so that focus doesn't
go moving on us */
event_halt_focus_delay();
if (client_normal(self) && screen_showing_desktop)
screen_show_desktop(FALSE, self);
if (self->iconic)
@ -3627,7 +3624,7 @@ static void client_present(ObClient *self, gboolean here, gboolean raise)
/* if its not visible for other reasons, then don't mess
with it */
return;
if (self->shaded)
if (self->shaded && unshade)
client_shade(self, FALSE);
if (raise)
stacking_raise(CLIENT_AS_WINDOW(self));
@ -3635,7 +3632,8 @@ static void client_present(ObClient *self, gboolean here, gboolean raise)
client_focus(self);
}
void client_activate(ObClient *self, gboolean here, gboolean user)
void client_activate(ObClient *self, gboolean here, gboolean raise,
gboolean unshade, gboolean user)
{
guint32 last_time = focus_client ? focus_client->user_time : CurrentTime;
gboolean allow = FALSE;
@ -3661,7 +3659,7 @@ void client_activate(ObClient *self, gboolean here, gboolean user)
(user ? "user" : "application"), allow);
if (allow)
client_present(self, here, TRUE);
client_present(self, here, raise, unshade);
else
/* don't focus it but tell the user it wants attention */
client_hilite(self, TRUE);

View file

@ -550,10 +550,13 @@ gboolean client_focus(ObClient *self);
when the user deliberately selects a window for use.
@param here If true, then the client is brought to the current desktop;
otherwise, the desktop is changed to where the client lives.
@param raise If true, the client is brought to the front.
@param unshade If true, the client is unshaded (if it is shaded)
@param user If true, then a user action is what requested the activation;
otherwise, it means an application requested it on its own
*/
void client_activate(ObClient *self, gboolean here, gboolean user);
void client_activate(ObClient *self, gboolean here, gboolean raise,
gboolean unshade, gboolean user);
/*! Bring all of its helper windows to its desktop. These are the utility and
stuff windows. */

View file

@ -98,7 +98,7 @@ static void menu_execute(ObMenuEntry *self, ObMenuFrame *f,
{
if (self->id == -1) {
if (self->data.normal.data) /* it's set to NULL if its destroyed */
client_activate(self->data.normal.data, FALSE, TRUE);
client_activate(self->data.normal.data, FALSE, TRUE, TRUE, TRUE);
}
else
screen_set_desktop(self->id, TRUE);

View file

@ -98,7 +98,7 @@ static void desk_menu_execute(ObMenuEntry *self, ObMenuFrame *f,
{
if (self->id == -1) {
if (self->data.normal.data) /* it's set to NULL if its destroyed */
client_activate(self->data.normal.data, FALSE, TRUE);
client_activate(self->data.normal.data, FALSE, TRUE, TRUE, TRUE);
}
else
screen_set_desktop(self->id, TRUE);

View file

@ -1219,7 +1219,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
it can happen now when the window is on
another desktop, but we still don't
want it! */
client_activate(client, FALSE, TRUE);
client_activate(client, FALSE, TRUE, TRUE, TRUE);
break;
case ClientMessage:
/* validate cuz we query stuff off the client here */
@ -1297,7 +1297,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
ob_debug_type(OB_DEBUG_APP_BUGS,
"_NET_ACTIVE_WINDOW message for window %s is "
"missing source indication\n");
client_activate(client, FALSE,
client_activate(client, FALSE, TRUE, TRUE,
(e->xclient.data.l[0] == 0 ||
e->xclient.data.l[0] == 2));
} else if (msgtype == prop_atoms.net_wm_moveresize) {

View file

@ -137,7 +137,7 @@ ObClient* focus_cycle(gboolean forward, gboolean all_desktops,
focus_cycle_all_desktops,
focus_cycle_dock_windows,
focus_cycle_desktop_windows);
return;
return NULL;
} else if (ft != focus_cycle_target) {
focus_cycle_target = ft;
done = TRUE;
@ -258,12 +258,15 @@ static ObClient *focus_find_directional(ObClient *c, ObDirection dir,
return best_client;
}
void focus_directional_cycle(ObDirection dir, gboolean dock_windows,
gboolean desktop_windows, gboolean interactive,
gboolean dialog, gboolean done, gboolean cancel)
ObClient* focus_directional_cycle(ObDirection dir, gboolean dock_windows,
gboolean desktop_windows,
gboolean interactive,
gboolean dialog,
gboolean done, gboolean cancel)
{
static ObClient *first = NULL;
ObClient *ft = NULL;
ObClient *ret = NULL;
if (cancel) {
focus_cycle_target = NULL;
@ -313,11 +316,10 @@ void focus_directional_cycle(ObDirection dir, gboolean dock_windows,
focus_cycle_all_desktops,
focus_cycle_dock_windows,
focus_cycle_desktop_windows);
return;
return NULL;
done_cycle:
if (done && focus_cycle_target)
client_activate(focus_cycle_target, FALSE, TRUE);
if (done && !cancel) ret = focus_cycle_target;
first = NULL;
focus_cycle_target = NULL;
@ -325,5 +327,5 @@ done_cycle:
focus_cycle_draw_indicator(NULL);
focus_cycle_popup_single_hide();
return;
return ret;
}

View file

@ -38,9 +38,12 @@ struct _ObClient* focus_cycle(gboolean forward, gboolean all_desktops,
gboolean dock_windows, gboolean desktop_windows,
gboolean linear, gboolean interactive,
gboolean dialog, gboolean done, gboolean cancel);
void focus_directional_cycle(ObDirection dir, gboolean dock_windows,
gboolean desktop_windows, gboolean interactive,
gboolean dialog, gboolean done, gboolean cancel);
struct _ObClient* focus_directional_cycle(ObDirection dir,
gboolean dock_windows,
gboolean desktop_windows,
gboolean interactive,
gboolean dialog,
gboolean done, gboolean cancel);
void focus_cycle_stop(struct _ObClient *ifclient);