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:
parent
fbc7607fbd
commit
29c4cf4a15
12 changed files with 119 additions and 60 deletions
|
@ -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 \
|
||||
|
|
|
@ -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) {
|
||||
|
|
79
openbox/actions/activate.c
Normal file
79
openbox/actions/activate.c
Normal 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;
|
||||
}
|
|
@ -10,4 +10,5 @@ void action_all_startup()
|
|||
action_exit_startup();
|
||||
action_restart_startup();
|
||||
action_cyclewindows_startup();
|
||||
action_activate_startup();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue