add the cyclewindows action
[mikachu/openbox.git] / openbox / event.c
index 6b5ba70..cd66014 100644 (file)
@@ -22,6 +22,7 @@
 #include "window.h"
 #include "openbox.h"
 #include "dock.h"
+#include "actions.h"
 #include "client.h"
 #include "xerror.h"
 #include "prop.h"
@@ -36,7 +37,6 @@
 #include "propwin.h"
 #include "mouse.h"
 #include "mainloop.h"
-#include "framerender.h"
 #include "focus.h"
 #include "focus_cycle.h"
 #include "moveresize.h"
@@ -499,7 +499,7 @@ static void event_process(const XEvent *ec, gpointer data)
 
             focus_left_screen = FALSE;
 
-            focus_fallback(FALSE, FALSE, TRUE);
+            focus_fallback(FALSE, config_focus_under_mouse, TRUE);
 
             /* We don't get a FocusOut for this case, because it's just moving
                from our Inferior up to us. This happens when iconifying a
@@ -551,7 +551,7 @@ static void event_process(const XEvent *ec, gpointer data)
                 */
 
                 if (!focus_left_screen)
-                    focus_fallback(FALSE, FALSE, TRUE);
+                    focus_fallback(FALSE, config_focus_under_mouse, TRUE);
             }
         }
         else if (!client)
@@ -607,7 +607,7 @@ static void event_process(const XEvent *ec, gpointer data)
                 ob_debug_type(OB_DEBUG_FOCUS,
                               "Focus went to an unmanaged window 0x%x !\n",
                               ce.xfocus.window);
-                focus_fallback(TRUE, FALSE, TRUE);
+                focus_fallback(TRUE, config_focus_under_mouse, TRUE);
             }
         }
 
@@ -723,6 +723,7 @@ static void event_handle_root(XEvent *e)
         } else if (msgtype == prop_atoms.net_showing_desktop) {
             screen_show_desktop(e->xclient.data.l[0] != 0, NULL);
         } else if (msgtype == prop_atoms.ob_control) {
+            ob_debug("OB_CONTROL: %d\n", e->xclient.data.l[0]);
             if (e->xclient.data.l[0] == 1)
                 ob_reconfigure();
             else if (e->xclient.data.l[0] == 2)
@@ -730,8 +731,10 @@ static void event_handle_root(XEvent *e)
         }
         break;
     case PropertyNotify:
-        if (e->xproperty.atom == prop_atoms.net_desktop_names)
+        if (e->xproperty.atom == prop_atoms.net_desktop_names) {
+            ob_debug("UPDATE DESKTOP NAMES\n");
             screen_update_desktop_names();
+        }
         else if (e->xproperty.atom == prop_atoms.net_desktop_layout)
             screen_update_layout();
         break;
@@ -806,8 +809,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
            want to deal with them
         */
         if (!(e->xbutton.button == 4 || e->xbutton.button == 5) &&
-            !keyboard_interactively_grabbed() &&
-            !menu_frame_visible)
+            !grab_on_keyboard())
         {
             /* use where the press occured */
             con = frame_context(client, e->xbutton.window, px, py);
@@ -820,23 +822,23 @@ static void event_handle_client(ObClient *client, XEvent *e)
             switch (con) {
             case OB_FRAME_CONTEXT_MAXIMIZE:
                 client->frame->max_press = (e->type == ButtonPress);
-                framerender_frame(client->frame);
+                frame_adjust_state(client->frame);
                 break;
             case OB_FRAME_CONTEXT_CLOSE:
                 client->frame->close_press = (e->type == ButtonPress);
-                framerender_frame(client->frame);
+                frame_adjust_state(client->frame);
                 break;
             case OB_FRAME_CONTEXT_ICONIFY:
                 client->frame->iconify_press = (e->type == ButtonPress);
-                framerender_frame(client->frame);
+                frame_adjust_state(client->frame);
                 break;
             case OB_FRAME_CONTEXT_ALLDESKTOPS:
                 client->frame->desk_press = (e->type == ButtonPress);
-                framerender_frame(client->frame);
+                frame_adjust_state(client->frame);
                 break; 
             case OB_FRAME_CONTEXT_SHADE:
                 client->frame->shade_press = (e->type == ButtonPress);
-                framerender_frame(client->frame);
+                frame_adjust_state(client->frame);
                 break;
             default:
                 /* nothing changes with clicks for any other contexts */
@@ -954,7 +956,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
                           (e->type == EnterNotify ? "Enter" : "Leave"),
                           e->xcrossing.mode,
                           e->xcrossing.detail, (client?client->window:0));
-            if (keyboard_interactively_grabbed())
+            if (grab_on_keyboard())
                 break;
             if (config_focus_follow && config_focus_delay &&
                 /* leave inferior events can happen when the mouse goes onto
@@ -997,7 +999,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
             frame_adjust_state(client->frame);
             break;
         case OB_FRAME_CONTEXT_FRAME:
-            if (keyboard_interactively_grabbed())
+            if (grab_on_keyboard())
                 break;
             if (e->xcrossing.mode == NotifyGrab ||
                 e->xcrossing.mode == NotifyUngrab ||
@@ -1075,12 +1077,10 @@ static void event_handle_client(ObClient *client, XEvent *e)
                     sibling = WINDOW_AS_CLIENT(win);
             }
 
-            /* activate it rather than just focus it */
             if (!config_focus_under_mouse)
                 ignore_start = event_start_ignore_all_enters();
             stacking_restack_request(client, sibling,
-                                     e->xconfigurerequest.detail,
-                                     TRUE);
+                                     e->xconfigurerequest.detail);
             if (!config_focus_under_mouse)
                 event_end_ignore_all_enters(ignore_start);
 
@@ -1155,7 +1155,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
                notify is sent or not */
         }
 
-        if (move || resize) {
+        {
             gint lw,lh;
 
             client_try_configure(client, &x, &y, &w, &h, &lw, &lh, FALSE);
@@ -1173,18 +1173,9 @@ static void event_handle_client(ObClient *client, XEvent *e)
 
             client_find_onscreen(client, &x, &y, w, h, FALSE);
 
-            /* if they requested something that moves the window, or if
-               the window is actually being changed then configure it and
-               send a configure notify to them */
-            if (move || !RECT_EQUAL_DIMS(client->area, x, y, w, h)) {
-                gulong ignore_start;
-
-                ob_debug("Granting ConfigureRequest x %d y %d w %d h %d\n",
-                         x, y, w, h);
-                ignore_start = event_start_ignore_all_enters();
-                client_configure(client, x, y, w, h, FALSE, TRUE);
-                event_end_ignore_all_enters(ignore_start);
-            }
+            ob_debug("Granting ConfigureRequest x %d y %d w %d h %d\n",
+                     x, y, w, h);
+            client_configure(client, x, y, w, h, FALSE, TRUE, TRUE);
         }
         break;
     }
@@ -1267,7 +1258,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
             if ((unsigned)e->xclient.data.l[0] < screen_num_desktops ||
                 (unsigned)e->xclient.data.l[0] == DESKTOP_ALL)
                 client_set_desktop(client, (unsigned)e->xclient.data.l[0],
-                                   FALSE);
+                                   FALSE, FALSE);
         } else if (msgtype == prop_atoms.net_wm_state) {
             gulong ignore_start;
 
@@ -1346,7 +1337,6 @@ static void event_handle_client(ObClient *client, XEvent *e)
                 moveresize_end(TRUE);
         } else if (msgtype == prop_atoms.net_moveresize_window) {
             gint ograv, x, y, w, h;
-            gulong ignore_start;
 
             ograv = client->gravity;
 
@@ -1391,10 +1381,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
 
             client_find_onscreen(client, &x, &y, w, h, FALSE);
 
-            /* ignore enter events caused by these like ob actions do */
-            ignore_start = event_start_ignore_all_enters();
-            client_configure(client, x, y, w, h, FALSE, TRUE);
-            event_end_ignore_all_enters(ignore_start);
+            client_configure(client, x, y, w, h, FALSE, TRUE, FALSE);
 
             client->gravity = ograv;
         } else if (msgtype == prop_atoms.net_restack_window) {
@@ -1431,13 +1418,13 @@ static void event_handle_client(ObClient *client, XEvent *e)
                         ignore_start = event_start_ignore_all_enters();
                     /* just raise, don't activate */
                     stacking_restack_request(client, sibling,
-                                             e->xclient.data.l[2], FALSE);
+                                             e->xclient.data.l[2]);
                     if (!config_focus_under_mouse)
                         event_end_ignore_all_enters(ignore_start);
 
                     /* send a synthetic ConfigureNotify, cuz this is supposed
                        to be like a ConfigureRequest. */
-                    client_reconfigure(client);
+                    client_reconfigure(client, TRUE);
                 } else
                     ob_debug_type(OB_DEBUG_APP_BUGS,
                                   "_NET_RESTACK_WINDOW sent for window %s "
@@ -1484,9 +1471,15 @@ static void event_handle_client(ObClient *client, XEvent *e)
 
         msgtype = e->xproperty.atom;
         if (msgtype == XA_WM_NORMAL_HINTS) {
+            ob_debug("Update NORMAL hints\n");
             client_update_normal_hints(client);
             /* normal hints can make a window non-resizable */
-            client_setup_decor_and_functions(client, TRUE);
+            client_setup_decor_and_functions(client, FALSE);
+
+            /* make sure the client's sizes are within its bounds, but only
+               reconfigure the window if it needs to. emacs will update its
+               normal hints every time it receives a conigurenotify */
+            client_reconfigure(client, FALSE);
         } else if (msgtype == XA_WM_HINTS) {
             client_update_wmhints(client);
         } else if (msgtype == XA_WM_TRANSIENT_FOR) {
@@ -1536,7 +1529,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
 #ifdef SHAPE
         if (extensions_shape && e->type == extensions_shape_event_basep) {
             client->shaped = ((XShapeEvent*)e)->shaped;
-            frame_adjust_shape(client->frame);
+            frame_adjust_area(client->frame, FALSE, TRUE, FALSE);
         }
 #endif
     }
@@ -1637,7 +1630,7 @@ static gboolean event_handle_menu_keyboard(XEvent *ev)
         if (frame->child)
             menu_frame_select_next(frame->child);
         else if (frame->selected)
-            menu_entry_frame_execute(frame->selected, state, ev->xkey.time);
+            menu_entry_frame_execute(frame->selected, state);
     }
 
     else if (keycode == ob_keycode(OB_KEY_LEFT) && ev->xkey.state == 0) {
@@ -1707,7 +1700,7 @@ static gboolean event_handle_menu_keyboard(XEvent *ev)
                 menu_frame_select(frame, found, TRUE);
                 usleep(50000); /* highlight the item for a short bit so the
                                   user can see what happened */
-                menu_entry_frame_execute(found, state, ev->xkey.time);
+                menu_entry_frame_execute(found, state);
             } else {
                 menu_frame_select(frame, found, TRUE);
                 if (num_found == 1)
@@ -1737,8 +1730,7 @@ static gboolean event_handle_menu(XEvent *ev)
                                             ev->xbutton.y_root)))
             {
                 menu_frame_select(e->frame, e, TRUE);
-                menu_entry_frame_execute(e, ev->xbutton.state,
-                                         ev->xbutton.time);
+                menu_entry_frame_execute(e, ev->xbutton.state);
             }
             else
                 menu_frame_hide_all();
@@ -1799,9 +1791,7 @@ static void event_handle_user_input(ObClient *client, XEvent *e)
 
     /* if the keyboard interactive action uses the event then dont
        use it for bindings. likewise is moveresize uses the event. */
-    if (!keyboard_process_interactive_grab(e, &client) &&
-        !(moveresize_in_progress && moveresize_event(e)))
-    {
+    if (!actions_interactive_input_event(e) && !moveresize_event(e)) {
         if (moveresize_in_progress)
             /* make further actions work on the client being
                moved/resized */
@@ -1815,10 +1805,9 @@ static void event_handle_user_input(ObClient *client, XEvent *e)
                in the case where it is animating before disappearing */
             if (!client || !frame_iconify_animating(client->frame))
                 mouse_event(client, e);
-        } else if (e->type == KeyPress) {
+        } else
             keyboard_event((focus_cycle_target ? focus_cycle_target :
                             (client ? client : focus_client)), e);
-        }
     }
 }
 
@@ -1907,21 +1896,20 @@ static gboolean is_enter_focus_event_ignored(XEvent *e)
 
 void event_cancel_all_key_grabs()
 {
-    if (keyboard_interactively_grabbed())
-        keyboard_interactive_cancel();
-    else if (menu_frame_visible)
+    if (actions_interactive_act_running()) {
+        actions_interactive_cancel_act();
+        ob_debug("KILLED interactive action\n");
+    }
+    else if (menu_frame_visible) {
         menu_frame_hide_all();
-    else if (grab_on_keyboard())
+        ob_debug("KILLED open menus\n");
+    }
+    else if (grab_on_keyboard()) {
         ungrab_keyboard();
+        ob_debug("KILLED active grab on keyboard\n");
+    }
     else
-        /* If we don't have the keyboard grabbed, then ungrab it with
-           XUngrabKeyboard, so that there is not a passive grab left
-           on from the KeyPress. If the grab is left on, and focus
-           moves during that time, it will be NotifyWhileGrabbed, and
-           applications like to ignore those! */
-        if (!keyboard_interactively_grabbed())
-            XUngrabKeyboard(ob_display, CurrentTime);
-
+        ungrab_passive_key();
 }
 
 gboolean event_time_after(Time t1, Time t2)