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); } }
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); }
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); }
/** * 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); }
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); } }