Exemple #1
0
/* 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);
    }
}
Exemple #2
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);
}
Exemple #3
0
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;
}
Exemple #4
0
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);
        }
    }
}
Exemple #5
0
/**
 * 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);
}
Exemple #6
0
/* 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);
    }
}