add the activate action. it will replace the focus action, as it can just focus witho...
authorDana Jansens <danakj@orodu.net>
Fri, 22 Jun 2007 04:59:06 +0000 (04:59 +0000)
committerDana Jansens <danakj@orodu.net>
Fri, 22 Jun 2007 04:59:06 +0000 (04:59 +0000)
12 files changed:
Makefile.am
openbox/action.c
openbox/actions/activate.c [new file with mode: 0644]
openbox/actions/all.c
openbox/actions/all.h
openbox/client.c
openbox/client.h
openbox/client_list_combined_menu.c
openbox/client_list_menu.c
openbox/event.c
openbox/focus_cycle.c
openbox/focus_cycle.h

index 70b6fc7..1276a7a 100644 (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 \
index 7f0cca1..de2bcdc 100644 (file)
@@ -499,11 +499,6 @@ ActionString actionstrings[] =
         setup_action_directional_focus_northwest
     },
     {
-        "activate",
-        action_activate,
-        setup_action_focus
-    },
-    {
         "focus",
         action_focus,
         setup_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) {
diff --git a/openbox/actions/activate.c b/openbox/actions/activate.c
new file mode 100644 (file)
index 0000000..6692362
--- /dev/null
@@ -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;
+}
index d60693b..a8cf305 100644 (file)
@@ -10,4 +10,5 @@ void action_all_startup()
     action_exit_startup();
     action_restart_startup();
     action_cyclewindows_startup();
+    action_activate_startup();
 }
index c3ab3a8..1f9a7f3 100644 (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
index 771294a..d65ce4a 100644 (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);
index b30db19..bb78345 100644 (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. */
index 60d6e68..998fd0a 100644 (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);
index 512cb3e..8f8beed 100644 (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);
index cd66014..ab4e8f9 100644 (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) {
index 971f116..2239885 100644 (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;
 }
index 3fecc9e..68b8d92 100644 (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);