示例#1
0
static MetaWindow *
test_client_find_window (TestClient *client,
                         const char *window_id,
                         GError    **error)
{
  MetaDisplay *display = meta_get_display ();

  GSList *windows = meta_display_list_windows (display,
                                               META_LIST_INCLUDE_OVERRIDE_REDIRECT);
  MetaWindow *result = NULL;
  char *expected_title = g_strdup_printf ("test/%s/%s",
                                          client->id, window_id);
  GSList *l;

  for (l = windows; l; l = l->next)
    {
      MetaWindow *window = l->data;
      if (g_strcmp0 (window->title, expected_title) == 0)
        {
          result = window;
          break;
        }
    }

  g_slist_free (windows);
  g_free (expected_title);

  if (result == NULL)
    g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_RUNTIME_ERROR,
                 "window %s/%s isn't known to Mutter", client->id, window_id);

  return result;
}
示例#2
0
static void
sync_focus_surface (MetaWaylandPointer *pointer)
{
  MetaDisplay *display = meta_get_display ();

  switch (display->event_route)
    {
    case META_EVENT_ROUTE_WINDOW_OP:
    case META_EVENT_ROUTE_COMPOSITOR_GRAB:
    case META_EVENT_ROUTE_FRAME_BUTTON:
      /* The compositor has a grab, so remove our focus... */
      meta_wayland_pointer_set_focus (pointer, NULL);
      break;

    case META_EVENT_ROUTE_NORMAL:
    case META_EVENT_ROUTE_WAYLAND_POPUP:
      {
        const MetaWaylandPointerGrabInterface *interface = pointer->grab->interface;
        interface->focus (pointer->grab, pointer->current);
      }
      break;

    default:
      g_assert_not_reached ();
    }

}
示例#3
0
void
meta_session_shutdown (void)
{
  /* Change our restart mode to IfRunning */
  
  SmProp prop1;
  SmPropValue prop1val;
  SmProp *props[1];
  char hint = SmRestartIfRunning;

  if (!meta_get_display ())
    {
      meta_verbose ("Cannot close session because there is no display");
      return;
    }

  warn_about_lame_clients_and_finish_interact (FALSE);

  if (session_connection == NULL)
    return;
  
  prop1.name = SmRestartStyleHint;
  prop1.type = SmCARD8;
  prop1.num_vals = 1;
  prop1.vals = &prop1val;
  prop1val.value = &hint;
  prop1val.length = 1;
    
  props[0] = &prop1;
  
  SmcSetProperties (session_connection, 1, props);
}
示例#4
0
static void
create_wl_shell_surface_window (MetaWaylandSurface *surface)
{
  MetaWaylandWlShellSurface *wl_shell_surface =
    META_WAYLAND_WL_SHELL_SURFACE (surface->role);
  MetaWaylandSurface *parent;
  GList *l;

  surface->window = meta_window_wayland_new (meta_get_display (), surface);
  meta_wayland_surface_set_window (surface, surface->window);

  if (wl_shell_surface->title)
    meta_window_set_title (surface->window, wl_shell_surface->title);
  if (wl_shell_surface->wm_class)
    meta_window_set_wm_class (surface->window,
                              wl_shell_surface->wm_class,
                              wl_shell_surface->wm_class);

  parent = wl_shell_surface->parent_surface;
  if (parent && parent->window)
    sync_wl_shell_parent_relationship (surface, parent);

  for (l = wl_shell_surface->children; l; l = l->next)
    {
      MetaWaylandSurface *child = l->data;

      if (child->window)
        sync_wl_shell_parent_relationship (child, surface);
    }
}
示例#5
0
文件: ui.c 项目: darkxst/mtest
static gboolean
is_input_event (XEvent *event)
{
  MetaDisplay *display = meta_get_display ();

  return (event->type == GenericEvent &&
          event->xcookie.extension == display->xinput_opcode);
}
示例#6
0
static void
async_waiter_destroy (AsyncWaiter *waiter)
{
  Display *xdisplay = meta_get_display ()->xdisplay;

  XSyncDestroyAlarm (xdisplay, waiter->alarm);
  XSyncDestroyCounter (xdisplay, waiter->counter);
  g_main_loop_unref (waiter->loop);
}
示例#7
0
文件: main.c 项目: brownsr/muffin
static void
meta_finalize (void)
{
  MetaDisplay *display = meta_get_display ();

  if (display)
    meta_display_close (display,
                        CurrentTime); /* I doubt correct timestamps matter here */
}
示例#8
0
static void
wl_shell_surface_pong (struct wl_client   *client,
                       struct wl_resource *resource,
                       uint32_t serial)
{
  MetaDisplay *display = meta_get_display ();

  meta_display_pong_for_serial (display, serial);
}
示例#9
0
static void
handle_host_xevent (MetaBackend *backend,
                    XEvent      *event)
{
  MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
  MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
  gboolean bypass_clutter = FALSE;

  XGetEventData (priv->xdisplay, &event->xcookie);

  {
    MetaDisplay *display = meta_get_display ();

    if (display)
      {
        MetaCompositor *compositor = display->compositor;
        if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event))
          bypass_clutter = TRUE;
      }
  }

  if (event->type == (priv->xsync_event_base + XSyncAlarmNotify))
    handle_alarm_notify (backend, event);

  if (event->type == priv->xkb_event_base)
    {
      XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event;

      if (xkb_ev->device == META_VIRTUAL_CORE_KEYBOARD_ID)
        {
          switch (xkb_ev->xkb_type)
            {
            case XkbNewKeyboardNotify:
            case XkbMapNotify:
              keymap_changed (backend);
            default:
              break;
            }
        }
    }

  {
    MetaMonitorManager *manager = meta_backend_get_monitor_manager (backend);
    if (META_IS_MONITOR_MANAGER_XRANDR (manager) &&
        meta_monitor_manager_xrandr_handle_xevent (META_MONITOR_MANAGER_XRANDR (manager), event))
      bypass_clutter = TRUE;
  }

  if (!bypass_clutter)
    {
      handle_input_event (x11, event);
      clutter_x11_handle_event (event);
    }

  XFreeEventData (priv->xdisplay, &event->xcookie);
}
示例#10
0
static void
async_waiter_set_and_wait (AsyncWaiter *waiter)
{
  Display *xdisplay = meta_get_display ()->xdisplay;
  int wait_value = async_waiter_next_value (waiter);

  XSyncValue sync_value;
  XSyncIntToValue (&sync_value, wait_value);

  XSyncSetCounter (xdisplay, waiter->counter, sync_value);
  async_waiter_wait (waiter, wait_value);
}
示例#11
0
文件: main.c 项目: kelsieflynn/mutter
static void
meta_finalize (void)
{
  MetaDisplay *display = meta_get_display ();

  if (display)
    meta_display_close (display,
                        CurrentTime); /* I doubt correct timestamps matter here */

  if (meta_is_wayland_compositor ())
    meta_wayland_finalize ();
}
示例#12
0
static gboolean
test_case_check_xserver_stacking (TestCase *test,
                                  GError  **error)
{
  MetaDisplay *display = meta_get_display ();
  GString *local_string = g_string_new (NULL);
  GString *x11_string = g_string_new (NULL);
  int i;

  guint64 *windows;
  int n_windows;
  meta_stack_tracker_get_stack (display->screen->stack_tracker, &windows, &n_windows);

  for (i = 0; i < n_windows; i++)
    {
      if (META_STACK_ID_IS_X11 (windows[i]))
        {
          if (local_string->len > 0)
            g_string_append_c (local_string, ' ');

          g_string_append_printf (local_string, "%#lx", (Window)windows[i]);
        }
    }

  Window root;
  Window parent;
  Window *children;
  unsigned int n_children;
  XQueryTree (display->xdisplay,
              meta_screen_get_xroot (display->screen),
              &root, &parent, &children, &n_children);

  for (i = 0; i < (int)n_children; i++)
    {
      if (x11_string->len > 0)
        g_string_append_c (x11_string, ' ');

      g_string_append_printf (x11_string, "%#lx", (Window)children[i]);
    }

  if (strcmp (x11_string->str, local_string->str) != 0)
    g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_ASSERTION_FAILED,
                 "xserver stacking: x11='%s', local='%s'",
                 x11_string->str, local_string->str);

  XFree (children);

  g_string_free (local_string, TRUE);
  g_string_free (x11_string, TRUE);

  return *error == NULL;
}
示例#13
0
gboolean
alex_windows_loop (gpointer data)
{
  MetaDisplay *alexdisplay;
  GSList *display_windows;

  alexdisplay = meta_get_display ();

  display_windows = meta_display_list_windows (alexdisplay);

  g_slist_foreach (display_windows, alex_window_proc, NULL);

  return (1);
}
示例#14
0
static MetaCursorSprite *
get_displayed_cursor (MetaCursorTracker *tracker)
{
  MetaDisplay *display = meta_get_display ();

  if (!tracker->is_showing)
    return NULL;

  if (meta_display_windows_are_interactable (display))
    {
      if (tracker->has_window_cursor)
        return tracker->window_cursor;
    }

  return tracker->root_cursor;
}
示例#15
0
static gboolean
test_case_destroy (TestCase *test,
                   GError  **error)
{
  /* Failures when cleaning up the test case aren't recoverable, since we'll
   * pollute the subsequent test cases, so we just return the error, and
   * skip the rest of the cleanup.
   */
  GHashTableIter iter;
  gpointer key, value;

  g_hash_table_iter_init (&iter, test->clients);
  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      if (!test_client_do (value, error, "destroy_all", NULL))
        return FALSE;

    }

  if (!test_case_wait (test, error))
    return FALSE;

  if (!test_case_assert_stacking (test, NULL, 0, error))
    return FALSE;

  if (!test_case_check_warnings (test, error))
    return FALSE;

  g_hash_table_iter_init (&iter, test->clients);
  while (g_hash_table_iter_next (&iter, &key, &value))
    test_client_destroy (value);

  async_waiter_destroy (test->waiter);

  meta_display_set_alarm_filter (meta_get_display (), NULL, NULL);

  g_hash_table_destroy (test->clients);
  g_free (test);

  g_log_remove_handler ("mutter", test->log_handler_id);

  return TRUE;
}
示例#16
0
static TestCase *
test_case_new (void)
{
  TestCase *test = g_new0 (TestCase, 1);

  test->log_handler_id = g_log_set_handler ("mutter",
                                            G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING,
                                            test_case_log_func,
                                            test);

  meta_display_set_alarm_filter (meta_get_display (),
                                 test_case_alarm_filter, test);

  test->clients = g_hash_table_new (g_str_hash, g_str_equal);
  test->waiter = async_waiter_new ();
  test->loop = g_main_loop_new (NULL, FALSE);

  return test;
}
示例#17
0
static void
xdg_shell_get_xdg_surface (struct wl_client   *client,
                           struct wl_resource *resource,
                           guint32             id,
                           struct wl_resource *surface_resource)
{
  MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
  MetaWaylandXdgSurface *xdg_surface;
  MetaWindow *window;

  if (META_IS_WAYLAND_XDG_SURFACE (surface->role) &&
      META_WAYLAND_XDG_SURFACE (surface->role)->resource)
    {
      wl_resource_post_error (surface_resource,
                              WL_DISPLAY_ERROR_INVALID_OBJECT,
                              "xdg_shell::get_xdg_surface already requested");
      return;
    }

  if (!meta_wayland_surface_assign_role (surface, META_TYPE_WAYLAND_XDG_SURFACE))
    {
      wl_resource_post_error (resource, XDG_SHELL_ERROR_ROLE,
                              "wl_surface@%d already has a different role",
                              wl_resource_get_id (surface->resource));
      return;
    }

  xdg_surface = META_WAYLAND_XDG_SURFACE (surface->role);
  xdg_surface->resource = wl_resource_create (client,
                                              &xdg_surface_interface,
                                              wl_resource_get_version (resource),
                                              id);
  wl_resource_set_implementation (xdg_surface->resource,
                                  &meta_wayland_xdg_surface_interface,
                                  xdg_surface,
                                  xdg_surface_destructor);

  xdg_surface->xdg_shell_resource = resource;

  window = meta_window_wayland_new (meta_get_display (), surface);
  meta_wayland_surface_set_window (surface, window);
}
示例#18
0
static AsyncWaiter *
async_waiter_new (void)
{
  AsyncWaiter *waiter = g_new0 (AsyncWaiter, 1);

  Display *xdisplay = meta_get_display ()->xdisplay;
  XSyncValue value;
  XSyncAlarmAttributes attr;

  waiter->counter_value = 0;
  XSyncIntToValue (&value, waiter->counter_value);

  waiter->counter = XSyncCreateCounter (xdisplay, value);

  attr.trigger.counter = waiter->counter;
  attr.trigger.test_type = XSyncPositiveComparison;

  /* Initialize to one greater than the current value */
  attr.trigger.value_type = XSyncRelative;
  XSyncIntToValue (&attr.trigger.wait_value, 1);

  /* After triggering, increment test_value by this until
   * until the test condition is false */
  XSyncIntToValue (&attr.delta, 1);

  /* we want events (on by default anyway) */
  attr.events = True;

  waiter->alarm = XSyncCreateAlarm (xdisplay,
                                    XSyncCACounter |
                                    XSyncCAValueType |
                                    XSyncCAValue |
                                    XSyncCATestType |
                                    XSyncCADelta |
                                    XSyncCAEvents,
                                    &attr);

  waiter->loop = g_main_loop_new (NULL, FALSE);

  return waiter;
}
示例#19
0
gboolean
meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
                                   XEvent            *xevent)
{
  MetaDisplay *display = meta_get_display ();
  XFixesCursorNotifyEvent *notify_event;

  if (meta_is_wayland_compositor ())
    return FALSE;

  if (xevent->xany.type != display->xfixes_event_base + XFixesCursorNotify)
    return FALSE;

  notify_event = (XFixesCursorNotifyEvent *)xevent;
  if (notify_event->subtype != XFixesDisplayCursorNotify)
    return FALSE;

  g_clear_pointer (&tracker->xfixes_cursor, meta_cursor_reference_unref);

  return TRUE;
}
示例#20
0
gboolean
meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
                                   XEvent            *xevent)
{
  MetaDisplay *display = meta_get_display ();
  XFixesCursorNotifyEvent *notify_event;

  if (meta_is_wayland_compositor ())
    return FALSE;

  if (xevent->xany.type != display->xfixes_event_base + XFixesCursorNotify)
    return FALSE;

  notify_event = (XFixesCursorNotifyEvent *)xevent;
  if (notify_event->subtype != XFixesDisplayCursorNotify)
    return FALSE;

  g_clear_object (&tracker->xfixes_cursor);
  g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);

  return TRUE;
}
示例#21
0
void
meta_invalidate_default_icons (void)
{
  MetaDisplay *display = meta_get_display ();
  GSList *windows;
  GSList *l;

  if (display == NULL)
    return; /* We can validly be called before the display is opened. */

  windows = meta_display_list_windows (display);
  for (l = windows; l != NULL; l = l->next)
    {
      MetaWindow *window = (MetaWindow*)l->data;

      if (window->icon_cache.origin == USING_FALLBACK_ICON)
        {
          meta_icon_cache_free (&(window->icon_cache));
          meta_window_update_icon_now (window);
        }
    }

  g_slist_free (windows);
}
示例#22
0
static void
ensure_xfixes_cursor (MetaCursorTracker *tracker)
{
  MetaDisplay *display = meta_get_display ();
  XFixesCursorImage *cursor_image;
  CoglTexture2D *sprite;
  guint8 *cursor_data;
  gboolean free_cursor_data;
  CoglContext *ctx;
  CoglError *error = NULL;

  if (tracker->xfixes_cursor)
    return;

  cursor_image = XFixesGetCursorImage (display->xdisplay);
  if (!cursor_image)
    return;

  /* Like all X APIs, XFixesGetCursorImage() returns arrays of 32-bit
   * quantities as arrays of long; we need to convert on 64 bit */
  if (sizeof(long) == 4)
    {
      cursor_data = (guint8 *)cursor_image->pixels;
      free_cursor_data = FALSE;
    }
  else
    {
      int i, j;
      guint32 *cursor_words;
      gulong *p;
      guint32 *q;

      cursor_words = g_new (guint32, cursor_image->width * cursor_image->height);
      cursor_data = (guint8 *)cursor_words;

      p = cursor_image->pixels;
      q = cursor_words;
      for (j = 0; j < cursor_image->height; j++)
        for (i = 0; i < cursor_image->width; i++)
          *(q++) = *(p++);

      free_cursor_data = TRUE;
    }

  ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
  sprite = cogl_texture_2d_new_from_data (ctx,
                                          cursor_image->width,
                                          cursor_image->height,
                                          CLUTTER_CAIRO_FORMAT_ARGB32,
                                          cursor_image->width * 4, /* stride */
                                          cursor_data,
                                          &error);

  if (free_cursor_data)
    g_free (cursor_data);

  if (error != NULL)
    {
      meta_warning ("Failed to allocate cursor sprite texture: %s\n", error->message);
      cogl_error_free (error);
    }

  if (sprite != NULL)
    {
      MetaCursorSprite *cursor_sprite = meta_cursor_sprite_new ();
      meta_cursor_sprite_set_texture (cursor_sprite,
                                      sprite,
                                      cursor_image->xhot,
                                      cursor_image->yhot);
      cogl_object_unref (sprite);
      tracker->xfixes_cursor = cursor_sprite;
    }
  XFree (cursor_image);
}
示例#23
0
static void
handle_host_xevent (MetaBackend *backend,
                    XEvent      *event)
{
  MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
  MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
  gboolean bypass_clutter = FALSE;

  XGetEventData (priv->xdisplay, &event->xcookie);

  {
    MetaDisplay *display = meta_get_display ();

    if (display)
      {
        MetaCompositor *compositor = display->compositor;
        if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event))
          bypass_clutter = TRUE;
      }
  }

  if (priv->mode == META_BACKEND_X11_MODE_NESTED && event->type == FocusIn)
    {
#ifdef HAVE_WAYLAND
      Window xwin = meta_backend_x11_get_xwindow(x11);
      XEvent xev;

      if (event->xfocus.window == xwin)
        {
          /* Since we've selected for KeymapStateMask, every FocusIn is followed immediately
           * by a KeymapNotify event */
          XMaskEvent(priv->xdisplay, KeymapStateMask, &xev);
          MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
          meta_wayland_compositor_update_key_state (compositor, xev.xkeymap.key_vector, 32, 8);
        }
#else
      g_assert_not_reached ();
#endif
    }

  if (event->type == (priv->xsync_event_base + XSyncAlarmNotify))
    handle_alarm_notify (backend, event);

  if (event->type == priv->xkb_event_base)
    {
      XkbEvent *xkb_ev = (XkbEvent *) event;

      if (xkb_ev->any.device == META_VIRTUAL_CORE_KEYBOARD_ID)
        {
          switch (xkb_ev->any.xkb_type)
            {
            case XkbNewKeyboardNotify:
            case XkbMapNotify:
              keymap_changed (backend);
              break;
            case XkbStateNotify:
              if (xkb_ev->state.changed & XkbGroupLockMask)
                {
                  if (priv->locked_group != xkb_ev->state.locked_group)
                    XkbLockGroup (priv->xdisplay, XkbUseCoreKbd, priv->locked_group);
                }
              break;
            default:
              break;
            }
        }
    }

  {
    MetaMonitorManager *manager = meta_backend_get_monitor_manager (backend);
    if (META_IS_MONITOR_MANAGER_XRANDR (manager) &&
        meta_monitor_manager_xrandr_handle_xevent (META_MONITOR_MANAGER_XRANDR (manager), event))
      bypass_clutter = TRUE;
  }

  if (!bypass_clutter)
    {
      handle_input_event (x11, event);
      clutter_x11_handle_event (event);
    }

  XFreeEventData (priv->xdisplay, &event->xcookie);
}
示例#24
0
static void
xdg_shell_get_xdg_popup (struct wl_client   *client,
                         struct wl_resource *resource,
                         uint32_t            id,
                         struct wl_resource *surface_resource,
                         struct wl_resource *parent_resource,
                         struct wl_resource *seat_resource,
                         uint32_t            serial,
                         int32_t             x,
                         int32_t             y)
{
  MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
  MetaWaylandPopupSurface *popup_surface;
  MetaWaylandSurface *parent_surf = wl_resource_get_user_data (parent_resource);
  MetaWaylandSurface *top_popup;
  MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
  MetaWindow *window;
  MetaDisplay *display = meta_get_display ();
  MetaWaylandXdgPopup *xdg_popup;
  MetaWaylandPopup *popup;

  if (META_IS_WAYLAND_XDG_POPUP (surface->role) &&
      META_WAYLAND_XDG_POPUP (surface->role)->resource)
    {
      wl_resource_post_error (surface_resource,
                              WL_DISPLAY_ERROR_INVALID_OBJECT,
                              "xdg_shell::get_xdg_popup already requested");
      return;
    }

  if (!meta_wayland_surface_assign_role (surface, META_TYPE_WAYLAND_XDG_POPUP))
    {
      wl_resource_post_error (resource, XDG_SHELL_ERROR_ROLE,
                              "wl_surface@%d already has a different role",
                              wl_resource_get_id (surface->resource));
      return;
    }

  if (parent_surf == NULL ||
      parent_surf->window == NULL ||
      (!META_IS_WAYLAND_XDG_POPUP (parent_surf->role) &&
       !META_IS_WAYLAND_XDG_SURFACE (parent_surf->role)))
    {
      wl_resource_post_error (resource,
                              XDG_SHELL_ERROR_INVALID_POPUP_PARENT,
                              "invalid parent surface");
      return;
    }

  top_popup = meta_wayland_pointer_get_top_popup (&seat->pointer);
  if ((top_popup == NULL && !META_IS_WAYLAND_XDG_SURFACE (parent_surf->role)) ||
      (top_popup != NULL && parent_surf != top_popup))
    {
      wl_resource_post_error (resource,
                              XDG_SHELL_ERROR_NOT_THE_TOPMOST_POPUP,
                              "parent not top most surface");
      return;
    }

  xdg_popup = META_WAYLAND_XDG_POPUP (surface->role);
  xdg_popup->resource = wl_resource_create (client, &xdg_popup_interface,
                                            wl_resource_get_version (resource), id);
  wl_resource_set_implementation (xdg_popup->resource,
                                  &meta_wayland_xdg_popup_interface,
                                  xdg_popup,
                                  xdg_popup_destructor);

  xdg_popup->xdg_shell_resource = resource;

  if (!meta_wayland_seat_can_popup (seat, serial))
    {
      xdg_popup_send_popup_done (xdg_popup->resource);
      return;
    }

  xdg_popup->parent_surface = parent_surf;
  xdg_popup->parent_destroy_listener.notify = handle_popup_parent_destroyed;
  wl_resource_add_destroy_listener (parent_surf->resource,
                                    &xdg_popup->parent_destroy_listener);

  window = meta_window_wayland_new (display, surface);
  meta_window_wayland_place_relative_to (window, parent_surf->window, x, y);
  window->showing_for_first_time = FALSE;

  meta_wayland_surface_set_window (surface, window);

  meta_window_focus (window, meta_display_get_current_time (display));
  popup_surface = META_WAYLAND_POPUP_SURFACE (surface->role);
  popup = meta_wayland_pointer_start_popup_grab (&seat->pointer,
                                                 popup_surface);
  if (popup == NULL)
    {
      xdg_popup_send_popup_done (xdg_popup->resource);
      meta_wayland_surface_destroy_window (surface);
      return;
    }

  xdg_popup->popup = popup;
}
示例#25
0
static void
warn_about_lame_clients_and_finish_interact (gboolean shutdown)
{
  GSList *lame = NULL;
  GSList *windows;
  GSList *lame_details = NULL;
  GSList *tmp;
  GSList *columns = NULL;
  GPid pid;
  
  windows = meta_display_list_windows (meta_get_display ());
  tmp = windows;
  while (tmp != NULL)
    {
      MetaWindow *window;
          
      window = tmp->data;

      /* only complain about normal windows, the others
       * are kind of dumb to worry about
       */
      if (window->sm_client_id == NULL &&
          window->type == META_WINDOW_NORMAL)
        lame = g_slist_prepend (lame, window);
          
      tmp = tmp->next;
    }
      
  g_slist_free (windows);
  
  if (lame == NULL)
    {
      /* No lame apps. */
      finish_interact (shutdown);
      return;
    }

  columns = g_slist_prepend (columns, "Window");
  columns = g_slist_prepend (columns, "Class");

  lame = g_slist_sort (lame, (GCompareFunc) windows_cmp_by_title);

  tmp = lame;
  while (tmp != NULL)
    {
      MetaWindow *w = tmp->data;

      lame_details = g_slist_prepend (lame_details,
                                      w->res_class ? w->res_class : "");
      lame_details = g_slist_prepend (lame_details,
                                      w->title);

      tmp = tmp->next;
    }
  g_slist_free (lame);

  pid = meta_show_dialog("--list",
                         _("These windows do not support &quot;save current setup&quot; "
                           "and will have to be restarted manually next time "
                           "you log in."),
                         "240",
                         meta_screen_get_screen_number (meta_get_display()->active_screen),
                         NULL, NULL,
                         None,
                         columns,
                         lame_details);

  g_slist_free (lame_details);

  g_child_watch_add (pid, dialog_closed, GINT_TO_POINTER (shutdown));
}
示例#26
0
static void
save_state (void)
{
  char *consortium_dir;
  char *session_dir;
  FILE *outfile;
  GSList *windows;
  GSList *tmp;
  int stack_position;
  
  g_assert (client_id);

  outfile = NULL;
  
  /*
   * g_get_user_config_dir() is guaranteed to return an existing directory.
   * Eventually, if SM stays with the WM, I'd like to make this
   * something like <config>/window_placement in a standard format.
   * Future optimisers should note also that by the time we get here
   * we probably already have full_save_path figured out and therefore
   * can just use the directory name from that.
   */
  consortium_dir = g_strconcat (g_get_user_config_dir (),
                              G_DIR_SEPARATOR_S "consortium",
                              NULL);
  
  session_dir = g_strconcat (consortium_dir,
                             G_DIR_SEPARATOR_S "sessions",
                             NULL);

  if (mkdir (consortium_dir, 0700) < 0 &&
      errno != EEXIST)
    {
      meta_warning (_("Could not create directory '%s': %s\n"),
                    consortium_dir, g_strerror (errno));
    }

  if (mkdir (session_dir, 0700) < 0 &&
      errno != EEXIST)
    {
      meta_warning (_("Could not create directory '%s': %s\n"),
                    session_dir, g_strerror (errno));
    }

  meta_topic (META_DEBUG_SM, "Saving session to '%s'\n", full_save_file ());
  
  outfile = fopen (full_save_file (), "w");

  if (outfile == NULL)
    {
      meta_warning (_("Could not open session file '%s' for writing: %s\n"),
                    full_save_file (), g_strerror (errno));
      goto out;
    }

  /* The file format is:
   * <consortium_session id="foo">
   *   <window id="bar" class="XTerm" name="xterm" title="/foo/bar" role="blah" type="normal" stacking="5">
   *     <workspace index="2"/>
   *     <workspace index="4"/>
   *     <sticky/> <minimized/> <maximized/>
   *     <geometry x="100" y="100" width="200" height="200" gravity="northwest"/>
   *   </window>
   * </consortium_session>
   *
   * Note that attributes on <window> are the match info we use to
   * see if the saved state applies to a restored window, and
   * child elements are the saved state to be applied.
   * 
   */
  
  fprintf (outfile, "<consortium_session id=\"%s\">\n",
           client_id);

  windows = meta_display_list_windows (meta_get_display ());
  stack_position = 0;

  windows = g_slist_sort (windows, meta_display_stack_cmp);
  tmp = windows;
  stack_position = 0;

  while (tmp != NULL)
    {
      MetaWindow *window;

      window = tmp->data;

      if (window->sm_client_id)
        {
          char *sm_client_id;
          char *res_class;
          char *res_name;
          char *role;
          char *title;

          /* client id, class, name, role are not expected to be
           * in UTF-8 (I think they are in XPCS which is Latin-1?
           * in practice they are always ascii though.)
           */
              
          sm_client_id = encode_text_as_utf8_markup (window->sm_client_id);
          res_class = window->res_class ?
            encode_text_as_utf8_markup (window->res_class) : NULL;
          res_name = window->res_name ?
            encode_text_as_utf8_markup (window->res_name) : NULL;
          role = window->role ?
            encode_text_as_utf8_markup (window->role) : NULL;
          if (window->title)
            title = g_markup_escape_text (window->title, -1);
          else
            title = NULL;
              
          meta_topic (META_DEBUG_SM, "Saving session managed window %s, client ID '%s'\n",
                      window->desc, window->sm_client_id);

          fprintf (outfile,
                   "  <window id=\"%s\" class=\"%s\" name=\"%s\" title=\"%s\" role=\"%s\" type=\"%s\" stacking=\"%d\">\n",
                   sm_client_id,
                   res_class ? res_class : "",
                   res_name ? res_name : "",
                   title ? title : "",
                   role ? role : "",
                   window_type_to_string (window->type),
                   stack_position);

          g_free (sm_client_id);
          g_free (res_class);
          g_free (res_name);
          g_free (role);
          g_free (title);
              
          /* Sticky */
          if (window->on_all_workspaces)
            fputs ("    <sticky/>\n", outfile);

          /* Minimized */
          if (window->minimized)
            fputs ("    <minimized/>\n", outfile);

          /* Maximized */
          if (META_WINDOW_MAXIMIZED (window))
            {
              fprintf (outfile,
                       "    <maximized saved_x=\"%d\" saved_y=\"%d\" saved_width=\"%d\" saved_height=\"%d\"/>\n", 
                       window->saved_rect.x,
                       window->saved_rect.y,
                       window->saved_rect.width,
                       window->saved_rect.height);
            }
              
          /* Workspaces we're on */
          {
            int n;
            n = meta_workspace_index (window->workspace);
            fprintf (outfile,
                     "    <workspace index=\"%d\"/>\n", n);
          }

          /* Gravity */
          {
            int x, y, w, h;
            meta_window_get_geometry (window, &x, &y, &w, &h);
            
            fprintf (outfile,
                     "    <geometry x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" gravity=\"%s\"/>\n",
                     x, y, w, h,
                     meta_gravity_to_string (window->size_hints.win_gravity));
          }
              
          fputs ("  </window>\n", outfile);
        }
      else
        {
          meta_topic (META_DEBUG_SM, "Not saving window '%s', not session managed\n",
                      window->desc);
        }
          
      tmp = tmp->next;
      ++stack_position;
    }
      
  g_slist_free (windows);

  fputs ("</consortium_session>\n", outfile);
  
 out:
  if (outfile)
    {
      /* FIXME need a dialog for this */
      if (ferror (outfile))
        {
          meta_warning (_("Error writing session file '%s': %s\n"),
                        full_save_file (), g_strerror (errno));
        }
      if (fclose (outfile))
        {
          meta_warning (_("Error closing session file '%s': %s\n"),
                        full_save_file (), g_strerror (errno));
        }
    }
  
  g_free (consortium_dir);
  g_free (session_dir);
}
示例#27
0
void
meta_retheme_all (void)
{
  if (meta_get_display ())
    meta_display_retheme_all ();
}
示例#28
0
static gboolean
test_case_assert_stacking (TestCase *test,
                           char    **expected_windows,
                           int       n_expected_windows,
                           GError  **error)
{
  MetaDisplay *display = meta_get_display ();
  guint64 *windows;
  int n_windows;
  GString *stack_string = g_string_new (NULL);
  GString *expected_string = g_string_new (NULL);
  int i;

  meta_stack_tracker_get_stack (display->screen->stack_tracker, &windows, &n_windows);
  for (i = 0; i < n_windows; i++)
    {
      MetaWindow *window = meta_display_lookup_stack_id (display, windows[i]);
      if (window != NULL && window->title)
        {
          /* See comment in meta_ui_new() about why the dummy window for GTK+ theming
           * is managed as a MetaWindow.
           */
          if (META_STACK_ID_IS_X11 (windows[i]) &&
              meta_ui_window_is_dummy (display->screen->ui, windows[i]))
            continue;

          if (stack_string->len > 0)
            g_string_append_c (stack_string, ' ');

          if (g_str_has_prefix (window->title, "test/"))
            g_string_append (stack_string, window->title + 5);
          else
            g_string_append_printf (stack_string, "(%s)", window->title);
        }
      else if (windows[i] == display->screen->guard_window)
        {
          if (stack_string->len > 0)
            g_string_append_c (stack_string, ' ');

          g_string_append_c (stack_string, '|');
        }
    }

  for (i = 0; i < n_expected_windows; i++)
    {
      if (expected_string->len > 0)
        g_string_append_c (expected_string, ' ');

      g_string_append (expected_string, expected_windows[i]);
    }

  /* Don't require '| ' as a prefix if there are no hidden windows - we
   * remove the prefix from the actual string instead of adding it to the
   * expected string for clarity of the error message
   */
  if (index (expected_string->str, '|') == NULL && stack_string->str[0] == '|')
    {
      g_string_erase (stack_string,
                      0, stack_string->str[1] == ' ' ? 2 : 1);
    }

  if (strcmp (expected_string->str, stack_string->str) != 0)
    {
      g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_ASSERTION_FAILED,
                   "stacking: expected='%s', actual='%s'",
                   expected_string->str, stack_string->str);
    }

  g_string_free (stack_string, TRUE);
  g_string_free (expected_string, TRUE);

  return *error == NULL;
}
static gboolean on_idle_end_grab(guint timestamp)
{
    meta_verbose ("%s\n", __func__);
    meta_display_end_grab_op(meta_get_display(), timestamp);
    return G_SOURCE_REMOVE;
}