void deepin_workspace_overview_handle_event(DeepinWorkspaceOverview* self,
        XIDeviceEvent* event, KeySym keysym, MetaKeyBindingAction action)
{
    DeepinWorkspaceOverviewPrivate* priv = self->priv;
    if (!priv->ready) return;

    gboolean backward = FALSE;
    if (keysym == XK_Tab
            || action == META_KEYBINDING_ACTION_SWITCH_APPLICATIONS
            || action == META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD) {
        meta_verbose("tabbing inside expose windows\n");
        if (keysym == XK_Tab)
            backward = event->mods.base & ShiftMask;
        else
            backward = action == META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD;
        deepin_workspace_overview_focus_next(self, backward);

    } else if (keysym == XK_Return) {
        MetaDeepinClonedWidget* clone = deepin_workspace_overview_get_focused(self);
        if (!clone) {
            meta_workspace_focus_default_window(priv->workspace, NULL, event->time);
        } else {
            MetaWindow* mw = meta_deepin_cloned_widget_get_window(clone);
            g_assert(mw != NULL);
            if (mw->workspace && mw->workspace != priv->workspace) {
                meta_workspace_activate(mw->workspace, event->time);
            }
            meta_window_activate(mw, event->time);
        }

        g_idle_add((GSourceFunc)on_idle_end_grab, event->time);
    }
}
void
meta_window_delete (MetaWindow  *window,
                    guint32      timestamp)
{
  meta_error_trap_push (window->display);
  if (window->delete_window)
    {
      meta_topic (META_DEBUG_WINDOW_OPS,
                  "Deleting %s with delete_window request\n",
                  window->desc);
      meta_window_send_icccm_message (window,
                                      window->display->atom_WM_DELETE_WINDOW,
                                      timestamp);
    }
  else
    {
      meta_topic (META_DEBUG_WINDOW_OPS,
                  "Deleting %s with explicit kill\n",
                  window->desc);
      XKillClient (window->display->xdisplay, window->xwindow);
    }
  meta_error_trap_pop (window->display, FALSE);

  meta_display_ping_window (window->display,
                            window,
                            timestamp,
                            delete_ping_reply_func,
                            delete_ping_timeout_func,
                            window);
  
  if (window->has_focus)
    {
      /* FIXME Clean this up someday 
       * http://bugzilla.gnome.org/show_bug.cgi?id=108706
       */
#if 0
      /* This is unfortunately going to result in weirdness
       * if the window doesn't respond to the delete event.
       * I don't know how to avoid that though.
       */
      meta_topic (META_DEBUG_FOCUS,
                  "Focusing default window because focus window %s was deleted/killed\n",
                  window->desc);
      meta_workspace_focus_default_window (window->screen->active_workspace,
                                           window);
#else
      meta_topic (META_DEBUG_FOCUS,
                  "Not unfocusing %s on delete/kill\n",
                  window->desc);
#endif
    }
  else
    {
      meta_topic (META_DEBUG_FOCUS,
                  "Window %s was deleted/killed but didn't have focus\n",
                  window->desc);
    }
}
Beispiel #3
0
void
meta_core_user_lower_and_unfocus (Display *xdisplay,
                                  Window   frame_xwindow,
                                  guint32  timestamp)
{
  MetaWindow *window = get_window (xdisplay, frame_xwindow);

  lower_window_and_transients (window, NULL);

 /* Rather than try to figure that out whether we just lowered
  * the focus window, assume that's always the case. (Typically,
  * this will be invoked via keyboard action or by a mouse action;
  * in either case the window or a modal child will have been focused.) */
  meta_workspace_focus_default_window (window->screen->active_workspace,
                                       NULL,
                                       timestamp);
}
Beispiel #4
0
void
meta_core_user_lower_and_unfocus (Display *xdisplay,
                                  Window   frame_xwindow,
                                  guint32  timestamp)
{
  MetaWindow *window = get_window (xdisplay, frame_xwindow);
  
  meta_window_lower (window);

  if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK &&
      meta_prefs_get_raise_on_click ())
    {
      /* Move window to the back of the focusing workspace's MRU list.
       * Do extra sanity checks to avoid possible race conditions.
       * (Borrowed from window.c.)
       */
      if (window->screen->active_workspace &&
          meta_window_located_on_workspace (window, 
                                            window->screen->active_workspace))
        {
          GList* link;
          link = g_list_find (window->screen->active_workspace->mru_list, 
                              window);
          g_assert (link);

          window->screen->active_workspace->mru_list = 
            g_list_remove_link (window->screen->active_workspace->mru_list,
                                link);
          g_list_free (link);

          window->screen->active_workspace->mru_list = 
            g_list_append (window->screen->active_workspace->mru_list, 
                           window);
        }
    }

  /* focus the default window, if needed */
  if (window->has_focus)
    meta_workspace_focus_default_window (window->screen->active_workspace,
                                         NULL,
                                         timestamp);
}
Beispiel #5
0
/**
 * meta_workspace_activate_with_focus:
 * @workspace: a #MetaWorkspace
 * @focus_this: the #MetaWindow to be focused, or %NULL
 * @timestamp: timestamp for @focus_this
 *
 * Switches to @workspace and possibly activates the window @focus_this.
 *
 * The window @focus_this is activated by calling meta_window_activate()
 * which will unminimize it and transient parents, raise it and give it
 * the focus.
 *
 * If a window is currently being moved by the user, it will be
 * moved to @workspace.
 *
 * The advantage of calling this function instead of meta_workspace_activate()
 * followed by meta_window_activate() is that it happens as a unit, so
 * no other window gets focused first before @focus_this.
 */
void
meta_workspace_activate_with_focus (MetaWorkspace *workspace,
                                    MetaWindow    *focus_this,
                                    guint32        timestamp)
{
  MetaWorkspace  *old;
  MetaWindow     *move_window;
  MetaScreen     *screen;
  MetaDisplay    *display;
  MetaCompositor *comp;
  MetaWorkspaceLayout layout1, layout2;
  gint num_workspaces, current_space, new_space;
  MetaMotionDirection direction;
  
  meta_verbose ("Activating workspace %d\n",
                meta_workspace_index (workspace));
  
  if (workspace->screen->active_workspace == workspace)
    return;

  /* Free any cached pointers to the workspaces's edges from
   * a current resize or move operation */
  meta_display_cleanup_edges (workspace->screen->display);

  if (workspace->screen->active_workspace)
    workspace_switch_sound (workspace->screen->active_workspace, workspace);

  /* Note that old can be NULL; e.g. when starting up */
  old = workspace->screen->active_workspace;

  workspace->screen->active_workspace = workspace;

  meta_screen_set_active_workspace_hint (workspace->screen);

  /* If the "show desktop" mode is active for either the old workspace
   * or the new one *but not both*, then update the
   * _net_showing_desktop hint
   */
  if (old && (old->showing_desktop ^ workspace->showing_desktop))
    meta_screen_update_showing_desktop_hint (workspace->screen);

  if (old == NULL)
    return;

  move_window = NULL;
  if (workspace->screen->display->grab_op == META_GRAB_OP_MOVING ||
      workspace->screen->display->grab_op == META_GRAB_OP_KEYBOARD_MOVING)
    move_window = workspace->screen->display->grab_window;
      
  if (move_window != NULL)
    {
      if (move_window->on_all_workspaces)
        move_window = NULL; /* don't move it after all */

      /* We put the window on the new workspace, flip spaces,
       * then remove from old workspace, so the window
       * never gets unmapped and we maintain the button grab
       * on it.
       *
       * \bug  This comment appears to be the reverse of what happens
       */
      if (move_window && (move_window->workspace != workspace))
        {
          meta_workspace_remove_window (old, move_window);
          meta_workspace_add_window (workspace, move_window);
        }
    }

  meta_workspace_queue_calc_showing (old);
  meta_workspace_queue_calc_showing (workspace);

  /* FIXME: Why do we need this?!?  Isn't it handled in the lines above? */
  if (move_window)
      /* Removes window from other spaces */
      meta_window_change_workspace (move_window, workspace);

   /*
    * Notify the compositor that the active workspace is changing.
    */
   screen = workspace->screen;
   display = meta_screen_get_display (screen);
   comp = meta_display_get_compositor (display);
   direction = 0;

   current_space = meta_workspace_index (old);
   new_space     = meta_workspace_index (workspace);
   num_workspaces = meta_screen_get_n_workspaces (workspace->screen);
   meta_screen_calc_workspace_layout (workspace->screen, num_workspaces,
                                      current_space, &layout1);

   meta_screen_calc_workspace_layout (workspace->screen, num_workspaces,
                                      new_space, &layout2);

   if (meta_ui_get_direction() == META_UI_DIRECTION_RTL)
     {
       if (layout1.current_col > layout2.current_col)
         direction = META_MOTION_RIGHT;
       else if (layout1.current_col < layout2.current_col)
         direction = META_MOTION_LEFT;
     }
   else
    {
       if (layout1.current_col < layout2.current_col)
         direction = META_MOTION_RIGHT;
       else if (layout1.current_col > layout2.current_col)
         direction = META_MOTION_LEFT;
    }

   if (layout1.current_row < layout2.current_row)
     {
       if (!direction)
         direction = META_MOTION_DOWN;
       else if (direction == META_MOTION_RIGHT)
         direction = META_MOTION_DOWN_RIGHT;
       else
         direction = META_MOTION_DOWN_LEFT;
     }

   if (layout1.current_row > layout2.current_row)
     {
       if (!direction)
         direction = META_MOTION_UP;
       else if (direction == META_MOTION_RIGHT)
         direction = META_MOTION_UP_RIGHT;
       else
         direction = META_MOTION_UP_LEFT;
     }

   meta_screen_free_workspace_layout (&layout1);
   meta_screen_free_workspace_layout (&layout2);

   meta_compositor_switch_workspace (comp, screen, old, workspace, direction);

  /* This needs to be done after telling the compositor we are switching
   * workspaces since focusing a window will cause it to be immediately
   * shown and that would confuse the compositor if it didn't know we
   * were in a workspace switch.
   */
  if (focus_this)
    {
      meta_window_activate (focus_this, timestamp);
    }
  else if (move_window)
    {
      meta_window_raise (move_window);
    }
  else
    {
      meta_topic (META_DEBUG_FOCUS, "Focusing default window on new workspace\n");
      meta_workspace_focus_default_window (workspace, NULL, timestamp);
    }

   /* Emit switched signal from screen.c */
   meta_screen_workspace_switched (screen, current_space, new_space, direction);
}
Beispiel #6
0
void
meta_workspace_activate_with_focus (MetaWorkspace *workspace,
                                    MetaWindow    *focus_this,
                                    guint32        timestamp)
{
  MetaWorkspace *old;
  MetaWindow *move_window;
  
  meta_verbose ("Activating workspace %d\n",
                meta_workspace_index (workspace));
  
  if (workspace->screen->active_workspace == workspace)
    return;

  if (workspace->screen->active_workspace)
    workspace_switch_sound(workspace->screen->active_workspace, workspace);

  /* Note that old can be NULL; e.g. when starting up */
  old = workspace->screen->active_workspace;
  
  workspace->screen->active_workspace = workspace;

  set_active_space_hint (workspace->screen);

  /* If the "show desktop" mode is active for either the old workspace
   * or the new one *but not both*, then update the
   * _net_showing_desktop hint
   */
  if (old && (old->showing_desktop ^ workspace->showing_desktop))
    meta_screen_update_showing_desktop_hint (workspace->screen);

  if (old == NULL)
    return;

  move_window = NULL;
  if (workspace->screen->display->grab_op == META_GRAB_OP_MOVING ||
      workspace->screen->display->grab_op == META_GRAB_OP_KEYBOARD_MOVING)
    move_window = workspace->screen->display->grab_window;
      
  if (move_window != NULL)
    {
      if (move_window->on_all_workspaces)
        move_window = NULL; /* don't move it after all */

      /* We put the window on the new workspace, flip spaces,
       * then remove from old workspace, so the window
       * never gets unmapped and we maintain the button grab
       * on it.
       *
       * \bug  This comment appears to be the reverse of what happens
       */
      if (move_window && (move_window->workspace != workspace))
        {
          meta_workspace_remove_window (old, move_window);
          meta_workspace_add_window (workspace, move_window);
        }
    }

  meta_workspace_queue_calc_showing (old);
  meta_workspace_queue_calc_showing (workspace);

  /* FIXME: Why do we need this?!?  Isn't it handled in the lines above? */
  if (move_window)
      /* Removes window from other spaces */
      meta_window_change_workspace (move_window, workspace);

  if (focus_this)
    {
      meta_window_focus (focus_this, timestamp);
      meta_window_raise (focus_this);
    }
  else if (move_window)
    {
      meta_window_raise (move_window);
    }
  else
    {
      meta_topic (META_DEBUG_FOCUS, "Focusing default window on new workspace\n");
      meta_workspace_focus_default_window (workspace, NULL, timestamp);
    }
}