Exemplo n.º 1
0
/**
 * shell_global_get_focus_monitor:
 * @global: the #ShellGlobal
 *
 * Gets the bounding box of the monitor containing the window that
 * currently contains the keyboard focus.
 *
 * Return value: the bounding box of the focus monitor
 */
GdkRectangle *
shell_global_get_focus_monitor (ShellGlobal  *global)
{
  MetaScreen *screen = shell_global_get_screen (global);
  MetaDisplay *display = meta_screen_get_display (screen);
  MetaWindow *focus = meta_display_get_focus_window (display);
  MetaRectangle rect, wrect;
  int nmonitors, i;

  if (focus)
    {
      meta_window_get_outer_rect (focus, &wrect);
      nmonitors = meta_screen_get_n_monitors (screen);

      /* Find the monitor that the top-left corner of @focus is on. */
      for (i = 0; i < nmonitors; i++)
        {
          meta_screen_get_monitor_geometry (screen, i, &rect);

          if (rect.x <= wrect.x && rect.y <= wrect.y &&
              rect.x + rect.width > wrect.x &&
              rect.y + rect.height > wrect.y)
            return g_boxed_copy (GDK_TYPE_RECTANGLE, &rect);
        }
    }

  meta_screen_get_monitor_geometry (screen, 0, &rect);
  return g_boxed_copy (GDK_TYPE_RECTANGLE, &rect);
}
Exemplo n.º 2
0
static void calculate_places(MosesOverview* self)
{
    MosesOverviewPrivate* priv = self->priv;
    GPtrArray* clones = priv->clones;
    if (priv->clones->len) {
        g_ptr_array_sort(clones, window_compare);

        // get the area used by the expo algorithms together
        MetaScreen* screen = meta_plugin_get_screen(priv->plugin);

        MetaRectangle geom;
        int focused_monitor = meta_screen_get_current_monitor(screen);
        meta_screen_get_monitor_geometry(screen, focused_monitor, &geom);

        int HEAD_SIZE = TOP_GAP;
        g_object_get(priv->ov_head, "height", &HEAD_SIZE, NULL);
        g_debug("%s ov height: %d", __func__, HEAD_SIZE);
        MetaRectangle area = {(int)floorf (geom.x + BORDER),
                              (int)floorf (geom.y + TOP_GAP + HEAD_SIZE),
                              (int)floorf (geom.width - BORDER * 2),
                              (int)floorf (geom.height - BOTTOM_GAP - TOP_GAP - HEAD_SIZE)};

        natural_placement(self, area);

    } else {
        //NOTE: I can not set ready flag here because a conflict of super-e key release
        g_timeout_add(500, (GSourceFunc)on_ready_timeout, self);
    }
    clutter_actor_show(overview_head_get_content(priv->ov_head));
}
Exemplo n.º 3
0
static void overview_animated_destroy(MosesOverview* self, MosesOverviewQuitReason reason, gboolean animate)
{
    MosesOverviewPrivate* priv = self->priv;

    gboolean just_destroy = !animate;
    if (reason == MOSES_OV_REASON_ACTIVATE_WINDOW && !priv->selected_actor) {
        just_destroy = TRUE;
    } else if (reason == MOSES_OV_REASON_ACTIVATE_WORKSPACE && !priv->selected_workspace) {
        just_destroy = TRUE;
    } else if (reason == MOSES_OV_REASON_NORMAL) {
        just_destroy = TRUE;
    }

    if (just_destroy) {
        clutter_actor_destroy(CLUTTER_ACTOR(self));
        return;
    }

    gfloat x, y, w, h;
    ClutterActor* target = NULL;

    if (reason == MOSES_OV_REASON_ACTIVATE_WINDOW) {
        target = self->priv->selected_actor;

        ClutterActor* orig = clutter_clone_get_source(CLUTTER_CLONE(target));
        clutter_actor_get_position(orig, &x, &y);
        clutter_actor_get_size(orig, &w, &h);
        g_signal_handlers_disconnect_by_func(target, on_effect_complete, self);

    } else if (reason == MOSES_OV_REASON_ACTIVATE_WORKSPACE) {
        g_assert(priv->selected_actor == NULL);

        MetaScreen* screen = meta_plugin_get_screen(priv->plugin);
        target = overview_head_get_actor_for_workspace(priv->ov_head, priv->selected_workspace);

        MetaRectangle geom;
        int focused_monitor = meta_screen_get_current_monitor(screen);
        meta_screen_get_monitor_geometry(screen, focused_monitor, &geom);
        x = geom.x, y = geom.y, w = geom.width, h = geom.height;
    }

    if (target) {
        clutter_actor_remove_all_transitions(target);
        clutter_actor_set_child_above_sibling(clutter_actor_get_parent(target), target, NULL);

        clutter_actor_save_easing_state(target);
        clutter_actor_set_easing_mode(target, CLUTTER_LINEAR);
        clutter_actor_set_easing_duration(target, 150);

        clutter_actor_set_position(target, x, y);
        clutter_actor_set_scale(target, w / clutter_actor_get_width(target),
                h / clutter_actor_get_height(target));
        clutter_actor_restore_easing_state(target);
        g_object_connect(target, "signal::transitions-completed",
                G_CALLBACK(on_restore_position_effect_complete), self, NULL);
    }
}
Exemplo n.º 4
0
static void
on_monitors_changed (MetaScreen *screen,
                     MetaPlugin *plugin)
{
  MetaDefaultPlugin *self = META_DEFAULT_PLUGIN (plugin);
  int i, n;
  GRand *rand = g_rand_new_with_seed (123456);

  clutter_actor_destroy_all_children (self->priv->background_group);

  n = meta_screen_get_n_monitors (screen);
  for (i = 0; i < n; i++)
    {
      MetaRectangle rect;
      ClutterActor *background_actor;
      MetaBackground *background;
      ClutterColor color;

      meta_screen_get_monitor_geometry (screen, i, &rect);

      background_actor = meta_background_actor_new (screen, i);

      clutter_actor_set_position (background_actor, rect.x, rect.y);
      clutter_actor_set_size (background_actor, rect.width, rect.height);

      /* Don't use rand() here, mesa calls srand() internally when
         parsing the driconf XML, but it's nice if the colors are
         reproducible.
      */
      clutter_color_init (&color,
                          g_rand_int_range (rand, 0, 255),
                          g_rand_int_range (rand, 0, 255),
                          g_rand_int_range (rand, 0, 255),
                          255);

      background = meta_background_new (screen);
      meta_background_set_color (background, &color);
      meta_background_actor_set_background (META_BACKGROUND_ACTOR (background_actor), background);
      g_object_unref (background);

      clutter_actor_add_child (self->priv->background_group, background_actor);
    }

  g_rand_free (rand);
}
Exemplo n.º 5
0
static void
constrain_tooltip (StTooltip             *tooltip,
                   const ClutterGeometry *geometry,
                   ClutterGeometry       *adjusted_geometry,
                   gpointer               data)
{
  const ClutterGeometry *tip_area = st_tooltip_get_tip_area (tooltip);
  CinnamonGlobal *global = cinnamon_global_get ();
  MetaScreen *screen = cinnamon_global_get_screen (global);
  int n_monitors = meta_screen_get_n_monitors (screen);
  int i;

  *adjusted_geometry = *geometry;

  /* A point that determines what screen we'll constrain to */
  int x = tip_area->x + tip_area->width / 2;
  int y = tip_area->y + tip_area->height / 2;

  for (i = 0; i < n_monitors; i++)
    {
      MetaRectangle rect;
      meta_screen_get_monitor_geometry (screen, i, &rect);
      if (x >= rect.x && x < rect.x + rect.width &&
          y >= rect.y && y < rect.y + rect.height)
        {
          if (adjusted_geometry->x + adjusted_geometry->width > rect.x + rect.width)
            adjusted_geometry->x = rect.x + rect.width - adjusted_geometry->width;
          if (adjusted_geometry->x < rect.x)
            adjusted_geometry->x = rect.x;

          if (adjusted_geometry->y + adjusted_geometry->height > rect.y + rect.height)
            adjusted_geometry->y = rect.y + rect.height - adjusted_geometry->height;
          if (adjusted_geometry->y < rect.y)
            adjusted_geometry->y = rect.y;

          return;
        }
    }
}
Exemplo n.º 6
0
/**
 * shell_global_get_monitors:
 * @global: the #ShellGlobal
 *
 * Gets a list of the bounding boxes of the active screen's monitors.
 *
 * Return value: (transfer full) (element-type GdkRectangle): a list
 * of monitor bounding boxes.
 */
GSList *
shell_global_get_monitors (ShellGlobal *global)
{
  MetaScreen *screen = shell_global_get_screen (global);
  GSList *monitors = NULL;
  MetaRectangle rect;
  int i;

  g_assert (sizeof (MetaRectangle) == sizeof (GdkRectangle) &&
            G_STRUCT_OFFSET (MetaRectangle, x) == G_STRUCT_OFFSET (GdkRectangle, x) &&
            G_STRUCT_OFFSET (MetaRectangle, y) == G_STRUCT_OFFSET (GdkRectangle, y) &&
            G_STRUCT_OFFSET (MetaRectangle, width) == G_STRUCT_OFFSET (GdkRectangle, width) &&
            G_STRUCT_OFFSET (MetaRectangle, height) == G_STRUCT_OFFSET (GdkRectangle, height));

  for (i = meta_screen_get_n_monitors (screen) - 1; i >= 0; i--)
    {
      meta_screen_get_monitor_geometry (screen, i, &rect);
      monitors = g_slist_prepend (monitors,
                                  g_boxed_copy (GDK_TYPE_RECTANGLE, &rect));
    }
  return monitors;
}
Exemplo n.º 7
0
void moses_overview_show(MosesOverview* self, gboolean all_windows)
{
    MosesOverviewPrivate* priv = self->priv;

    MetaRectangle geom;
    MetaScreen* screen = meta_plugin_get_screen(priv->plugin);
    int focused_monitor = meta_screen_get_current_monitor(screen);
    meta_screen_get_monitor_geometry(screen, focused_monitor, &geom);

    // FIXME: overview is as big as the current monitor,
    // need to take care multiple monitors
    ClutterActor* stage = meta_get_stage_for_screen(screen);
    ClutterActor* top = CLUTTER_ACTOR(self);
    clutter_actor_set_size(top, geom.width, geom.height);
    clutter_actor_insert_child_above(stage, top, NULL);

    moses_overview_setup(self);
    priv->previous_focused = clutter_stage_get_key_focus(CLUTTER_STAGE(stage));

    if (!meta_plugin_begin_modal(priv->plugin, 0, clutter_get_current_event_time())) {
        g_warning("can not be modal");
        goto _end;
    }

    meta_disable_unredirect_for_screen(screen);

    clutter_actor_show(top);
    clutter_stage_set_key_focus(CLUTTER_STAGE(stage), top);
    clutter_actor_grab_key_focus(top);

    priv->modaled = TRUE;
    g_idle_add((GSourceFunc)on_idle, self);

    return;

_end:
    clutter_actor_destroy(CLUTTER_ACTOR(self));
}
Exemplo n.º 8
0
static void
on_monitors_changed (MetaScreen *screen,
                     MetaPlugin *plugin)
{
  MetaDefaultPlugin *self = META_DEFAULT_PLUGIN (plugin);
  __attribute__ ((unused)) ClutterAnimation *animation;
  int i, n;
  gchar *wallpaper = NULL;
  GFile *wallpaper_file = NULL;
  gchar *filename = NULL;
  GDesktopBackgroundStyle style;
  GDesktopBackgroundShading  shading_direction;
  ClutterColor primary_color;
  ClutterColor secondary_color;
  gboolean random_colour = FALSE;

  clutter_actor_destroy_all_children (self->priv->background_group);

  wallpaper = g_settings_get_string (self->priv->settings, PICTURE_URI_KEY);
  /* We don't currently support slideshows */
  if (!wallpaper || g_str_has_suffix(wallpaper, ".xml"))
    random_colour = TRUE;
  else {
    gchar *color_str;

    /* Shading direction*/
    shading_direction = g_settings_get_enum (self->priv->settings, COLOR_SHADING_TYPE_KEY);

    /* Primary color */
    color_str = g_settings_get_string (self->priv->settings, PRIMARY_COLOR_KEY);
    if (color_str)
    {
      clutter_color_from_string (&primary_color, color_str);
      g_free (color_str);
      color_str = NULL;
    }
      
    /* Secondary color */
    color_str = g_settings_get_string (self->priv->settings, SECONDARY_COLOR_KEY);
    if (color_str)
    {
      clutter_color_from_string (&secondary_color, color_str);
      g_free (color_str);
      color_str = NULL;
    }

    /* Picture options: "none", "wallpaper", "centered", "scaled", "stretched", "zoom", "spanned" */
    style = g_settings_get_enum (self->priv->settings, BACKGROUND_STYLE_KEY);

    wallpaper_file = g_file_new_for_uri(wallpaper);
    filename = g_file_get_path(wallpaper_file);
  }

  n = meta_screen_get_n_monitors (screen);

  for (i = 0; i < n; i++)
    {
      MetaBackground *content;
      MetaRectangle rect;
      ClutterActor *background;

      background = meta_background_actor_new ();

      content = meta_background_new (screen, 
                                     i, 
                                     META_BACKGROUND_EFFECTS_NONE);
      // Don't use rand() here, mesa calls srand() internally when
      // parsing the driconf XML, but it's nice if the colors are
      // reproducible.
      if (random_colour)
      {
        clutter_color_init (&primary_color,
          g_random_int () % 255,
          g_random_int () % 255,
          g_random_int () % 255,
          255);

        meta_background_load_color (content, &primary_color);
      } else {
        if (style == G_DESKTOP_BACKGROUND_STYLE_NONE ||
            g_str_has_suffix (filename, GNOME_COLOR_HACK))
        {
          if (shading_direction == G_DESKTOP_BACKGROUND_SHADING_SOLID)
            meta_background_load_color (content, &primary_color);
          else
            meta_background_load_gradient (content,
                                           shading_direction,
                                           &primary_color,
                                           &secondary_color);
        } else {
          /* Set the background */
          meta_background_load_file_async (content,
                                           filename,
                                           style,
                                           NULL, /*TODO use cancellable*/
                                           background_load_file_cb,
                                           self);
        }
      }

      clutter_actor_set_content (background, CLUTTER_CONTENT (content));
      g_object_unref (content);

      meta_screen_get_monitor_geometry (screen, i, &rect);

      clutter_actor_set_position (background, rect.x, rect.y);
      clutter_actor_set_size (background, rect.width, rect.height);
      clutter_actor_add_child (self->priv->background_group, background);
      clutter_actor_set_scale (background, 0.0, 0.0);
      clutter_actor_show (background);
      clutter_actor_set_pivot_point (background, 0.5, 0.5);

      /* Ease in the background using a scale effect */
      animation = clutter_actor_animate (background, CLUTTER_EASE_IN_SINE,
                                         BACKGROUND_TIMEOUT,
                                         "scale-x", 1.0,
                                         "scale-y", 1.0,
                                         NULL);
    }
    if (wallpaper_file)
      g_object_unref(wallpaper_file);
    g_free(wallpaper);
    g_free(filename);
}
Exemplo n.º 9
0
static void
grab_screenshot (ClutterActor *stage,
                 _screenshot_data *screenshot_data)
{
  MetaScreen *screen = shell_global_get_screen (screenshot_data->screenshot->global);
  MetaCursorTracker *tracker;
  int width, height;
  GSimpleAsyncResult *result;
  GSettings *settings;

  meta_screen_get_size (screen, &width, &height);

  do_grab_screenshot (screenshot_data, 0, 0, width, height);

  if (meta_screen_get_n_monitors (screen) > 1)
    {
      cairo_region_t *screen_region = cairo_region_create ();
      cairo_region_t *stage_region;
      MetaRectangle monitor_rect;
      cairo_rectangle_int_t stage_rect;
      int i;
      cairo_t *cr;

      for (i = meta_screen_get_n_monitors (screen) - 1; i >= 0; i--)
        {
          meta_screen_get_monitor_geometry (screen, i, &monitor_rect);
          cairo_region_union_rectangle (screen_region, (const cairo_rectangle_int_t *) &monitor_rect);
        }

      stage_rect.x = 0;
      stage_rect.y = 0;
      stage_rect.width = width;
      stage_rect.height = height;

      stage_region = cairo_region_create_rectangle ((const cairo_rectangle_int_t *) &stage_rect);
      cairo_region_xor (stage_region, screen_region);
      cairo_region_destroy (screen_region);

      cr = cairo_create (screenshot_data->image);

      for (i = 0; i < cairo_region_num_rectangles (stage_region); i++)
        {
          cairo_rectangle_int_t rect;
          cairo_region_get_rectangle (stage_region, i, &rect);
          cairo_rectangle (cr, (double) rect.x, (double) rect.y, (double) rect.width, (double) rect.height);
          cairo_fill (cr);
        }

      cairo_destroy (cr);
      cairo_region_destroy (stage_region);
    }

  screenshot_data->screenshot_area.x = 0;
  screenshot_data->screenshot_area.y = 0;
  screenshot_data->screenshot_area.width = width;
  screenshot_data->screenshot_area.height = height;

  settings = g_settings_new (A11Y_APPS_SCHEMA);
  if (screenshot_data->include_cursor &&
      !g_settings_get_boolean (settings, MAGNIFIER_ACTIVE_KEY))
    {
      tracker = meta_cursor_tracker_get_for_screen (screen);
      _draw_cursor_image (tracker, screenshot_data->image, screenshot_data->screenshot_area);
    }
  g_object_unref (settings);

  g_signal_handlers_disconnect_by_func (stage, (void *)grab_screenshot, (gpointer)screenshot_data);

  result = g_simple_async_result_new (NULL, on_screenshot_written, (gpointer)screenshot_data, grab_screenshot);
  g_simple_async_result_run_in_thread (result, write_screenshot_thread, G_PRIORITY_DEFAULT, NULL);
  g_object_unref (result);
}
Exemplo n.º 10
0
static void
on_monitors_changed (MetaScreen *screen,
                     MetaPlugin *plugin)
{
  MetaDefaultPlugin *self = META_DEFAULT_PLUGIN (plugin);
  __attribute__ ((unused)) ClutterAnimation *animation;
  int i, n;
  gchar *wallpaper = NULL;
  GFile *wallpaper_file = NULL;
  gchar *filename = NULL;
  gboolean random_colour = FALSE;

  clutter_actor_destroy_all_children (self->priv->background_group);

  wallpaper = g_settings_get_string(self->priv->settings, PICTURE_KEY);
  if (!wallpaper)
      random_colour = TRUE;
  else {
      wallpaper_file = g_file_new_for_uri(wallpaper);
      filename = g_file_get_path(wallpaper_file);
  }
      

  n = meta_screen_get_n_monitors (screen);
  for (i = 0; i < n; i++)
    {
      MetaRectangle rect;
      ClutterActor *background;
      ClutterColor color;

      meta_screen_get_monitor_geometry (screen, i, &rect);

      /* Don't use rand() here, mesa calls srand() internally when
         parsing the driconf XML, but it's nice if the colors are
         reproducible.
      */
      if (random_colour) {
            background = meta_background_actor_new ();
            clutter_color_init (&color,
                          g_random_int () % 255,
                          g_random_int () % 255,
                          g_random_int () % 255,
                          255);
            clutter_actor_set_background_color (background, &color);
      } else {
            /* Set the background */
            background = clutter_texture_new_from_file(filename, NULL);
      }

      clutter_actor_set_position (background, rect.x, rect.y);
      clutter_actor_set_size (background, rect.width, rect.height);
      clutter_actor_add_child (self->priv->background_group, background);
      clutter_actor_set_scale (background, 0.0, 0.0);
      clutter_actor_show (background);
      clutter_actor_move_anchor_point_from_gravity (background,
                                                    CLUTTER_GRAVITY_CENTER);
      /* Ease in the background using a scale effect */
      animation = clutter_actor_animate (background, CLUTTER_EASE_IN_SINE,
                                         BACKGROUND_TIMEOUT,
                                         "scale-x", 1.0,
                                         "scale-y", 1.0,
                                         NULL);
    }
    if (wallpaper_file)
      g_object_unref(wallpaper_file);
    g_free(wallpaper);
    g_free(filename);
}