]> git.sur5r.net Git - i3/i3/commitdiff
Merge branch 'master' into next
authorMichael Stapelberg <michael@stapelberg.de>
Sat, 21 Jan 2012 11:50:22 +0000 (11:50 +0000)
committerMichael Stapelberg <michael@stapelberg.de>
Sat, 21 Jan 2012 11:50:22 +0000 (11:50 +0000)
Conflicts:
src/handlers.c

1  2 
src/handlers.c

diff --combined src/handlers.c
index 00adc0e5ed62dd6a4f768c940835077169cc39b7,e2fa205ca02535098d70c30be82ac970175f30d2..507fffcf96a7ac52d8eb668eea528c81ca7afb86
@@@ -82,7 -82,7 +82,7 @@@ bool event_is_ignored(const int sequenc
   * the bound action to parse_command().
   *
   */
 -static int handle_key_press(xcb_key_press_event_t *event) {
 +static void handle_key_press(xcb_key_press_event_t *event) {
  
      last_timestamp = event->time;
  
          if ((bind = get_binding(state_filtered, event->detail)) == NULL) {
              ELOG("Could not lookup key binding (modifiers %d, keycode %d)\n",
                   state_filtered, event->detail);
 -            return 1;
 +            return;
          }
      }
  
      char *json_result = parse_cmd(bind->command);
      FREE(json_result);
 -    return 1;
 +    return;
  }
  
  /*
@@@ -163,7 -163,7 +163,7 @@@ static void check_crossing_screen_bound
   * When the user moves the mouse pointer onto a window, this callback gets called.
   *
   */
 -static int handle_enter_notify(xcb_enter_notify_event_t *event) {
 +static void handle_enter_notify(xcb_enter_notify_event_t *event) {
      Con *con;
  
      last_timestamp = event->time;
      DLOG("coordinates %d, %d\n", event->event_x, event->event_y);
      if (event->mode != XCB_NOTIFY_MODE_NORMAL) {
          DLOG("This was not a normal notify, ignoring\n");
 -        return 1;
 +        return;
      }
      /* Some events are not interesting, because they were not generated
       * actively by the user, but by reconfiguration of windows */
      if (event_is_ignored(event->sequence, XCB_ENTER_NOTIFY)) {
          DLOG("Event ignored\n");
 -        return 1;
 +        return;
      }
  
      bool enter_child = false;
      if (con == NULL) {
          DLOG("Getting screen at %d x %d\n", event->root_x, event->root_y);
          check_crossing_screen_boundary(event->root_x, event->root_y);
 -        return 1;
 +        return;
      }
  
      if (con->parent->type == CT_DOCKAREA) {
          DLOG("Ignoring, this is a dock client\n");
 -        return 1;
 +        return;
      }
  
      /* see if the user entered the window on a certain window decoration */
  #endif
  
      if (config.disable_focus_follows_mouse)
 -        return 1;
 +        return;
  
      /* Get the currently focused workspace to check if the focus change also
       * involves changing workspaces. If so, we need to call workspace_show() to
      con_focus(con_descend_focused(con));
      tree_render();
  
 -    return 1;
 +    return;
  }
  
  /*
   * and crossing virtual screen boundaries), this callback gets called.
   *
   */
 -static int handle_motion_notify(xcb_motion_notify_event_t *event) {
 +static void handle_motion_notify(xcb_motion_notify_event_t *event) {
  
      last_timestamp = event->time;
  
      /* Skip events where the pointer was over a child window, we are only
       * interested in events on the root window. */
      if (event->child != 0)
 -        return 1;
 +        return;
  
      Con *con;
      if ((con = con_by_frame_id(event->event)) == NULL) {
          check_crossing_screen_boundary(event->root_x, event->root_y);
 -        return 1;
 +        return;
      }
  
      if (config.disable_focus_follows_mouse)
 -        return 1;
 +        return;
  
      if (con->layout != L_DEFAULT)
 -        return 1;
 +        return;
  
      /* see over which rect the user is */
      Con *current;
  
          /* We found the rect, let’s see if this window is focused */
          if (TAILQ_FIRST(&(con->focus_head)) == current)
 -            return 1;
 +            return;
  
          con_focus(current);
          x_push_changes(croot);
 -        return 1;
 +        return;
      }
  
 -    return 1;
 +    return;
  }
  
  /*
   * we need to update our key bindings then (re-translate symbols).
   *
   */
 -static int handle_mapping_notify(xcb_mapping_notify_event_t *event) {
 +static void handle_mapping_notify(xcb_mapping_notify_event_t *event) {
      if (event->request != XCB_MAPPING_KEYBOARD &&
          event->request != XCB_MAPPING_MODIFIER)
 -        return 0;
 +        return;
  
      DLOG("Received mapping_notify for keyboard or modifier mapping, re-grabbing keys\n");
      xcb_refresh_keyboard_mapping(keysyms, event);
      translate_keysyms();
      grab_all_keys(conn, false);
  
 -    return 0;
 +    return;
  }
  
  /*
   * A new window appeared on the screen (=was mapped), so let’s manage it.
   *
   */
 -static int handle_map_request(xcb_map_request_event_t *event) {
 +static void handle_map_request(xcb_map_request_event_t *event) {
      xcb_get_window_attributes_cookie_t cookie;
  
      cookie = xcb_get_window_attributes_unchecked(conn, event->window);
  
      manage_window(event->window, cookie, false);
      x_push_changes(croot);
 -    return 1;
 +    return;
  }
  
  /*
 - * Configure requests are received when the application wants to resize windows on their own.
 + * Configure requests are received when the application wants to resize windows
 + * on their own.
   *
 - * We generate a synthethic configure notify event to signalize the client its "new" position.
 + * We generate a synthethic configure notify event to signalize the client its
 + * "new" position.
   *
   */
 -static int handle_configure_request(xcb_configure_request_event_t *event) {
 +static void handle_configure_request(xcb_configure_request_event_t *event) {
      Con *con;
  
      DLOG("window 0x%08x wants to be at %dx%d with %dx%d\n",
          xcb_configure_window(conn, event->window, mask, values);
          xcb_flush(conn);
  
 -        return 1;
 +        return;
      }
  
      DLOG("Configure request!\n");
  
          DLOG("Container is a floating leaf node, will do that.\n");
          floating_reposition(floatingcon, newrect);
 -        return 1;
 +        return;
      }
  
      /* Dock windows can be reconfigured in their height */
  
      fake_absolute_configure_notify(con);
  
 -    return 1;
 +    return;
  }
  #if 0
  
@@@ -444,14 -442,14 +444,14 @@@ int handle_configure_event(void *prophs
   * changes the screen configuration in any way (mode, position, …)
   *
   */
 -static int handle_screen_change(xcb_generic_event_t *e) {
 +static void handle_screen_change(xcb_generic_event_t *e) {
      DLOG("RandR screen change\n");
  
      randr_query_outputs();
  
      ipc_send_event("output", I3_IPC_EVENT_OUTPUT, "{\"change\":\"unspecified\"}");
  
 -    return 1;
 +    return;
  }
  
  /*
   */
  static void handle_unmap_notify_event(xcb_unmap_notify_event_t *event) {
      DLOG("UnmapNotify for 0x%08x (received from 0x%08x), serial %d\n", event->window, event->event, event->sequence);
+     xcb_get_input_focus_cookie_t cookie;
      Con *con = con_by_window_id(event->window);
      if (con == NULL) {
          /* This could also be an UnmapNotify for the frame. We need to
  
          if (con->ignore_unmap > 0)
              con->ignore_unmap--;
+         /* See the end of this function. */
+         cookie = xcb_get_input_focus(conn);
          DLOG("ignore_unmap = %d for frame of container %p\n", con->ignore_unmap, con);
          goto ignore_end;
      }
  
+     /* See the end of this function. */
+     cookie = xcb_get_input_focus(conn);
      if (con->ignore_unmap > 0) {
          DLOG("ignore_unmap = %d, dec\n", con->ignore_unmap);
          con->ignore_unmap--;
@@@ -502,6 -506,13 +508,13 @@@ ignore_end
       * Therefore, we ignore all EnterNotify events which have the same sequence
       * as an UnmapNotify event. */
      add_ignore_event(event->sequence, XCB_ENTER_NOTIFY);
+     /* Since we just ignored the sequence of this UnmapNotify, we want to make
+      * sure that following events use a different sequence. When putting xterm
+      * into fullscreen and moving the pointer to a different window, without
+      * using GetInputFocus, subsequent (legitimate) EnterNotify events arrived
+      * with the same sequence and thus were ignored (see ticket #609). */
+     free(xcb_get_input_focus_reply(conn, cookie, NULL));
  }
  
  /*
@@@ -595,26 -606,26 +608,26 @@@ static int handle_windowclass_change(vo
   * Expose event means we should redraw our windows (= title bar)
   *
   */
 -static int handle_expose_event(xcb_expose_event_t *event) {
 +static void handle_expose_event(xcb_expose_event_t *event) {
      Con *parent;
  
 -    /* event->count is the number of minimum remaining expose events for this
 -     * window, so we skip all events but the last one */
 -    if (event->count != 0)
 -        return 1;
 -
      DLOG("window = %08x\n", event->window);
  
      if ((parent = con_by_frame_id(event->window)) == NULL) {
          LOG("expose event for unknown window, ignoring\n");
 -        return 1;
 +        return;
      }
  
 -    /* re-render the parent (recursively, if it’s a split con) */
 -    x_deco_recurse(parent);
 +    /* Since we render to our pixmap on every change anyways, expose events
 +     * only tell us that the X server lost (parts of) the window contents. We
 +     * can handle that by copying the appropriate part from our pixmap to the
 +     * window. */
 +    xcb_copy_area(conn, parent->pixmap, parent->frame, parent->pm_gc,
 +                  event->x, event->y, event->x, event->y,
 +                  event->width, event->height);
      xcb_flush(conn);
  
 -    return 1;
 +    return;
  }
  
  /*
@@@ -876,6 -887,14 +889,6 @@@ static bool handle_transient_for(void *
  
      window_update_transient_for(con->window, prop);
  
 -    // TODO: put window in floating mode if con->window->transient_for != XCB_NONE:
 -#if 0
 -    if (client->floating == FLOATING_AUTO_OFF) {
 -        DLOG("This is a popup window, putting into floating\n");
 -        toggle_floating_mode(conn, client, true);
 -    }
 -#endif
 -
      return true;
  }
  
@@@ -908,33 -927,33 +921,33 @@@ static bool handle_clientleader_change(
   * decorations accordingly.
   *
   */
 -static int handle_focus_in(xcb_focus_in_event_t *event) {
 +static void handle_focus_in(xcb_focus_in_event_t *event) {
      DLOG("focus change in, for window 0x%08x\n", event->event);
      Con *con;
      if ((con = con_by_window_id(event->event)) == NULL || con->window == NULL)
 -        return 1;
 +        return;
      DLOG("That is con %p / %s\n", con, con->name);
  
      if (event->mode == XCB_NOTIFY_MODE_GRAB ||
          event->mode == XCB_NOTIFY_MODE_UNGRAB) {
          DLOG("FocusIn event for grab/ungrab, ignoring\n");
 -        return 1;
 +        return;
      }
  
      if (event->detail == XCB_NOTIFY_DETAIL_POINTER) {
          DLOG("notify detail is pointer, ignoring this event\n");
 -        return 1;
 +        return;
      }
  
      if (focused_id == event->event) {
          DLOG("focus matches the currently focused window, not doing anything\n");
 -        return 1;
 +        return;
      }
  
      /* Skip dock clients, they cannot get the i3 focus. */
      if (con->parent->type == CT_DOCKAREA) {
          DLOG("This is a dock client, not focusing.\n");
 -        return 1;
 +        return;
      }
  
      DLOG("focus is different, updating decorations\n");
      /* We update focused_id because we don’t need to set focus again */
      focused_id = event->event;
      x_push_changes(croot);
 -    return 1;
 +    return;
  }
  
  /* Returns false if the event could not be processed (e.g. the window could not