View Single Post
Marcus's Avatar
Posts: 173 | Thanked: 72 times | Joined on Mar 2010 @ Denmark
#6
Perhaps it is possible to take a look at SuperSwitcher (http://code.google.com/p/superswitcher/) and find out how it "simulates" alt+tab.

Unfortunately I do not know wether Maemo 5 works the same way.

I found this by a quick look:
Code:
void
ss_screen_activate_next_window (SSScreen *screen, gboolean backwards, guint32 time)
{
  SSWorkspace *workspace;
  SSWindow *window;
  GList *i;
  GList *j;

  SSWindow *first_sensitive_window;
  SSWindow *previous_sensitive_window;
  gboolean should_activate_last_sensitive_window;
  gboolean should_activate_next_sensitive_window;
  gboolean found_active_window;

  gboolean also_warp_pointer_if_necessary;

  first_sensitive_window    = NULL;
  previous_sensitive_window = NULL;
  should_activate_last_sensitive_window = FALSE;
  should_activate_next_sensitive_window = FALSE;
  found_active_window = FALSE;
  also_warp_pointer_if_necessary = TRUE;

  for (i = screen->workspaces; i; i = i->next) {
    workspace = (SSWorkspace *) i->data;
    if ((screen->active_window == NULL) && (screen->active_workspace == workspace)) {
      if (backwards) {
        if (previous_sensitive_window == NULL) {
          should_activate_last_sensitive_window = TRUE;
        } else {
          ss_window_activate_workspace_and_window (previous_sensitive_window, time,
            also_warp_pointer_if_necessary);
          return;
        }
      } else {
        should_activate_next_sensitive_window = TRUE;
      }
    }
    for (j = workspace->windows; j; j = j->next) {
      window = (SSWindow *) j->data;

      if (screen->active_window != NULL) {
        found_active_window = (window == screen->active_window);
      }

      if (backwards && found_active_window) {
        if (previous_sensitive_window == NULL) {
          should_activate_last_sensitive_window = TRUE;
        } else {
          ss_window_activate_workspace_and_window (previous_sensitive_window, time,
            also_warp_pointer_if_necessary);
          return;
        }
      }

      if (window->sensitive) {
        if (should_activate_next_sensitive_window) {
          ss_window_activate_workspace_and_window (window, time,
            also_warp_pointer_if_necessary);
          return;
        }

        previous_sensitive_window = window;

        if (first_sensitive_window == NULL) {
          first_sensitive_window = window;
        }
      }

      if (!backwards && found_active_window) {
        should_activate_next_sensitive_window = TRUE;
      }
    }
  }

  if (should_activate_next_sensitive_window) {
    ss_window_activate_workspace_and_window (first_sensitive_window, time,
      also_warp_pointer_if_necessary);
    return;
  }

  if (should_activate_last_sensitive_window) {
    ss_window_activate_workspace_and_window (previous_sensitive_window, time,
      also_warp_pointer_if_necessary);
    return;
  }
}

//------------------------------------------------------------------------------

void
ss_screen_activate_next_window_in_stacking_order (SSScreen *screen, gboolean backwards, guint32 time)
{
  WnckWindow *active_wnck_window;
  WnckWindow *wnck_window;
  gboolean ww_is_aww;
  int active_workspace_id;
  int workspace_id;
  GList *i;
  int num_windows;

  WnckWindow *first_eligible_wnck_window;
  WnckWindow *previous_eligible_wnck_window;
  gboolean should_activate_last_eligible_wnck_window;
  gboolean should_activate_next_eligible_wnck_window;
  
  gboolean also_warp_pointer_if_necessary;
  also_warp_pointer_if_necessary = TRUE;

  num_windows = g_list_length (screen->active_workspace->windows);
  if (num_windows == 0) {
    return;
  }

  // TODO - this is probably an ugly hack that's exposed to a potential
  // race condition.  A better way to go about this would be to suppress
  // the window_stacking_change signal, I suppose.
  // For example, if a window gets opened in between setting this flag
  // and in the event handler on_window_stacking_changed, then the
  // window_stacking_order list will be copied at the wrong point,
  // possibly.
  screen->should_ignore_next_window_stacking_change = TRUE;

  first_eligible_wnck_window    = NULL;
  previous_eligible_wnck_window = NULL;
  should_activate_last_eligible_wnck_window = FALSE;
  should_activate_next_eligible_wnck_window = FALSE;

  if (screen->active_window != NULL) {
    active_wnck_window = screen->active_window->wnck_window;
  } else {
    active_wnck_window = NULL;
  }
  active_workspace_id = wnck_workspace_get_number (wnck_screen_get_active_workspace (screen->wnck_screen));

  // Note that wnck_windows_in_stacking_order is in bottom-to-top
  // order, so that if we're searching forwards (just like Alt-Tab)
  // then we want the previous_eligible_wnck_window.  This is the
  // opposite ordering than in ss_screen_activate_next_window.
  for (i = screen->wnck_windows_in_stacking_order; i; i = i->next) {
    wnck_window = (WnckWindow *) i->data;
    workspace_id = wnck_workspace_get_number (wnck_window_get_workspace (wnck_window));

    if (workspace_id != active_workspace_id) {
      continue;
    }

    if (active_wnck_window != NULL) {
      ww_is_aww = (wnck_window_get_xid (wnck_window) ==
        wnck_window_get_xid (active_wnck_window));
    } else {
      ww_is_aww = FALSE;
    }

    // We've found the active window, and we're searching forwards.
    if (!backwards && ww_is_aww) {
      if (previous_eligible_wnck_window == NULL) {
        should_activate_last_eligible_wnck_window = TRUE;
      } else {
        ss_window_activate_window (get_ss_window_from_wnck_window (
          screen, previous_eligible_wnck_window), time,
          also_warp_pointer_if_necessary);
        return;
      }
    }

    if (should_activate_next_eligible_wnck_window) {
      ss_window_activate_window (get_ss_window_from_wnck_window (
        screen, wnck_window), time, also_warp_pointer_if_necessary);
      return;
    }

    previous_eligible_wnck_window = wnck_window;

    if (first_eligible_wnck_window == NULL) {
      first_eligible_wnck_window = wnck_window;
    }

    // We've found the active window, and we're searching backwards.
    if (backwards && ww_is_aww) {
      should_activate_next_eligible_wnck_window = TRUE;
    }
  }

  if (active_wnck_window == NULL) {
    if (backwards) {
      should_activate_next_eligible_wnck_window = TRUE;
    } else {
      should_activate_last_eligible_wnck_window = TRUE;
    }
  }

  if (should_activate_next_eligible_wnck_window) {
    ss_window_activate_window (get_ss_window_from_wnck_window (
      screen, first_eligible_wnck_window), time, also_warp_pointer_if_necessary);
    return;
  }

  if (should_activate_last_eligible_wnck_window) {
    ss_window_activate_window (get_ss_window_from_wnck_window (
      screen, previous_eligible_wnck_window), time, also_warp_pointer_if_necessary);
    return;
  }
}