/* Focus ancestor of not_this_one if there is one */ static void focus_ancestor_or_top_window (MetaWorkspace *workspace, MetaWindow *not_this_one, guint32 timestamp) { MetaWindow *window = NULL; if (not_this_one) meta_topic (META_DEBUG_FOCUS, "Focusing MRU window excluding %s\n", not_this_one->desc); else meta_topic (META_DEBUG_FOCUS, "Focusing MRU window\n"); /* First, check to see if we need to focus an ancestor of a window */ if (not_this_one) { MetaWindow *ancestor; ancestor = NULL; meta_window_foreach_ancestor (not_this_one, record_ancestor, &ancestor); if (ancestor != NULL) { meta_topic (META_DEBUG_FOCUS, "Focusing %s, ancestor of %s\n", ancestor->desc, not_this_one->desc); meta_window_focus (ancestor, timestamp); /* Also raise the window if in click-to-focus */ if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK) meta_window_raise (ancestor); return; } } window = meta_stack_get_default_focus_window (workspace->screen->stack, workspace, not_this_one); if (window) { meta_topic (META_DEBUG_FOCUS, "Focusing workspace MRU window %s\n", window->desc); meta_window_focus (window, timestamp); /* Also raise the window if in click-to-focus */ if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK) meta_window_raise (window); } else { meta_topic (META_DEBUG_FOCUS, "No MRU window to focus found; focusing no_focus_window.\n"); meta_display_focus_the_no_focus_window (workspace->screen->display, workspace->screen, 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); }
static gboolean lower_window_and_transients (MetaWindow *window, gpointer data) { meta_window_lower (window); meta_window_foreach_transient (window, lower_window_and_transients, NULL); 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); } } return FALSE; }
void meta_workspace_focus_default_window (MetaWorkspace *workspace, MetaWindow *not_this_one, guint32 timestamp) { if (timestamp == CurrentTime) { meta_warning ("CurrentTime used to choose focus window; " "focus window may not be correct.\n"); } if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK || !workspace->screen->display->mouse_mode) focus_ancestor_or_top_window (workspace, not_this_one, timestamp); else { MetaWindow * window; window = meta_screen_get_mouse_window (workspace->screen, not_this_one); if (window && window->type != META_WINDOW_DOCK && window->type != META_WINDOW_DESKTOP) { if (timestamp == CurrentTime) { /* We would like for this to never happen. However, if * it does happen then we kludge since using CurrentTime * can mean ugly race conditions--and we can avoid these * by allowing EnterNotify events (which come with * timestamps) to handle focus. */ meta_topic (META_DEBUG_FOCUS, "Not focusing mouse window %s because EnterNotify events should handle that\n", window->desc); } else { meta_topic (META_DEBUG_FOCUS, "Focusing mouse window %s\n", window->desc); meta_window_focus (window, timestamp); } if (workspace->screen->display->autoraise_window != window && meta_prefs_get_auto_raise ()) { meta_display_queue_autoraise_callback (workspace->screen->display, window); } } else if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_SLOPPY) focus_ancestor_or_top_window (workspace, not_this_one, timestamp); else if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_MOUSE) { meta_topic (META_DEBUG_FOCUS, "Setting focus to no_focus_window, since no valid " "window to focus found.\n"); meta_display_focus_the_no_focus_window (workspace->screen->display, workspace->screen, timestamp); } } }
/** * Flashes one entire screen. This is done by making a window the size of the * whole screen (or reusing the old one, if it's still around), mapping it, * painting it white and then black, and then unmapping it. We set saveunder so * that all the windows behind it come back immediately. * * Unlike frame flashes, we don't do fullscreen flashes with a timeout; rather, * we do them in one go, because we don't have to rely on the theme code * redrawing the frame for us in order to do the flash. * * \param display The display which owns the screen (rather redundant) * \param screen The screen to flash * * \bug The way I read it, this appears not to do the flash * the first time we flash a particular display. Am I wrong? * * \bug This appears to destroy our current XSync status. */ static void bell_flash_screen (MetaDisplay *display, MetaScreen *screen) { Window root = screen->xroot; int width = screen->rect.width; int height = screen->rect.height; if (screen->flash_window == None) { Visual *visual = (Visual *)CopyFromParent; XSetWindowAttributes xswa; int depth = CopyFromParent; xswa.save_under = True; xswa.override_redirect = True; /* * TODO: use XGetVisualInfo and determine which is an * overlay, if one is present, and use the Overlay visual * for this window (for performance reasons). * Not sure how to tell this yet... */ screen->flash_window = XCreateWindow (display->xdisplay, root, 0, 0, width, height, 0, depth, InputOutput, visual, /* note: XSun doesn't like SaveUnder here */ CWSaveUnder | CWOverrideRedirect, &xswa); XSelectInput (display->xdisplay, screen->flash_window, ExposureMask); XMapWindow (display->xdisplay, screen->flash_window); XSync (display->xdisplay, False); XFlush (display->xdisplay); XUnmapWindow (display->xdisplay, screen->flash_window); } else { /* just draw something in the window */ GC gc = XCreateGC (display->xdisplay, screen->flash_window, 0, NULL); XMapWindow (display->xdisplay, screen->flash_window); XSetForeground (display->xdisplay, gc, WhitePixel (display->xdisplay, XScreenNumberOfScreen (screen->xscreen))); XFillRectangle (display->xdisplay, screen->flash_window, gc, 0, 0, width, height); XSetForeground (display->xdisplay, gc, BlackPixel (display->xdisplay, XScreenNumberOfScreen (screen->xscreen))); XFillRectangle (display->xdisplay, screen->flash_window, gc, 0, 0, width, height); XFlush (display->xdisplay); XSync (display->xdisplay, False); XUnmapWindow (display->xdisplay, screen->flash_window); XFreeGC (display->xdisplay, gc); } if (meta_prefs_get_focus_mode () != META_FOCUS_MODE_CLICK && !display->mouse_mode) meta_display_increment_focus_sentinel (display); XFlush (display->xdisplay); }
/* Focus ancestor of not_this_one if there is one, otherwise focus the MRU * window on active workspace */ static void focus_ancestor_or_mru_window (MetaWorkspace *workspace, MetaWindow *not_this_one, guint32 timestamp) { MetaWindow *window = NULL; MetaWindow *desktop_window = NULL; GList *tmp; if (not_this_one) meta_topic (META_DEBUG_FOCUS, "Focusing MRU window excluding %s\n", not_this_one->desc); else meta_topic (META_DEBUG_FOCUS, "Focusing MRU window\n"); /* First, check to see if we need to focus an ancestor of a window */ if (not_this_one) { MetaWindow *ancestor; ancestor = NULL; meta_window_foreach_ancestor (not_this_one, record_ancestor, &ancestor); if (ancestor != NULL) { meta_topic (META_DEBUG_FOCUS, "Focusing %s, ancestor of %s\n", ancestor->desc, not_this_one->desc); meta_window_focus (ancestor, timestamp); /* Also raise the window if in click-to-focus */ if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK) meta_window_raise (ancestor); return; } } /* No ancestor, look for the MRU window */ tmp = workspace->mru_list; while (tmp) { MetaWindow* tmp_window; tmp_window = ((MetaWindow*) tmp->data); if (tmp_window != not_this_one && meta_window_showing_on_its_workspace (tmp_window) && tmp_window->type != META_WINDOW_DOCK && tmp_window->type != META_WINDOW_DESKTOP) { window = tmp->data; break; } else if (tmp_window != not_this_one && desktop_window == NULL && meta_window_showing_on_its_workspace (tmp_window) && tmp_window->type == META_WINDOW_DESKTOP) { /* Found the most recently used desktop window */ desktop_window = tmp_window; } tmp = tmp->next; } /* If no window was found, default to the MRU desktop-window */ if (window == NULL) window = desktop_window; if (window) { meta_topic (META_DEBUG_FOCUS, "Focusing workspace MRU window %s\n", window->desc); meta_window_focus (window, timestamp); /* Also raise the window if in click-to-focus */ if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK) meta_window_raise (window); } else { meta_topic (META_DEBUG_FOCUS, "No MRU window to focus found; focusing no_focus_window.\n"); meta_display_focus_the_no_focus_window (workspace->screen->display, workspace->screen, timestamp); } }