Пример #1
0
void
meta_window_ensure_frame (MetaWindow *window)
{
  MetaFrame *frame;
  MetaScreen *screen;
  XSetWindowAttributes attrs;
  XVisualInfo visual_info;
  Visual *visual;
  int status;

  if (window->frame)
    return;

  /* See comment below for why this is required. */
  meta_display_grab (window->display);

  frame = g_new (MetaFrame, 1);

  frame->window = window;
  frame->xwindow = None;

  frame->rect = window->rect;
  frame->child_x = 0;
  frame->child_y = 0;
  frame->bottom_height = 0;
  frame->right_width = 0;
  frame->current_cursor = 0;

  frame->mapped = TRUE;
  frame->need_reapply_frame_shape = TRUE;
  frame->is_flashing = FALSE;

  meta_verbose ("Framing window %s: visual %s default, depth %d default depth %d\n",
                window->desc,
                XVisualIDFromVisual (window->xvisual) ==
                XVisualIDFromVisual (window->screen->default_xvisual) ?
                "is" : "is not",
                window->depth, window->screen->default_depth);
  meta_verbose ("Frame geometry %d,%d  %dx%d\n",
                frame->rect.x, frame->rect.y,
                frame->rect.width, frame->rect.height);

  /* Default depth/visual handles clients with weird visuals; they can
   * always be children of the root depth/visual obviously, but
   * e.g. DRI games can't be children of a parent that has the same
   * visual as the client. NULL means default visual.
   *
   * We look for an ARGB visual if we can find one, otherwise use
   * the default of NULL.
   */

  screen = meta_window_get_screen (window);
  status = XMatchVisualInfo (window->display->xdisplay,
                             XScreenNumberOfScreen (screen->xscreen),
                             32, TrueColor,
                             &visual_info);

  if (!status)
    {
      /* Special case for depth 32 windows (assumed to be ARGB),
       * we use the window's visual. Otherwise we just use the system visual.
       */
      if (window->depth == 32)
        visual = window->xvisual;
      else
        visual = NULL;
    }
  else
    visual = visual_info.visual;

  frame->xwindow = meta_ui_create_frame_window (window->screen->ui,
                                                window->display->xdisplay,
                                                visual,
                                                frame->rect.x,
                                                frame->rect.y,
						frame->rect.width,
						frame->rect.height,
						frame->window->screen->number);

  meta_verbose ("Frame for %s is 0x%lx\n", frame->window->desc, frame->xwindow);
  attrs.event_mask = EVENT_MASK;
  XChangeWindowAttributes (window->display->xdisplay,
			   frame->xwindow, CWEventMask, &attrs);

  meta_display_register_x_window (window->display, &frame->xwindow, window);

  /* Reparent the client window; it may be destroyed,
   * thus the error trap. We'll get a destroy notify later
   * and free everything. Comment in FVWM source code says
   * we need a server grab or the child can get its MapNotify
   * before we've finished reparenting and getting the decoration
   * window onscreen, so ensure_frame must be called with
   * a grab.
   */
  meta_error_trap_push (window->display);
  if (window->mapped)
    {
      window->mapped = FALSE; /* the reparent will unmap the window,
                               * we don't want to take that as a withdraw
                               */
      meta_topic (META_DEBUG_WINDOW_STATE,
                  "Incrementing unmaps_pending on %s for reparent\n", window->desc);
      window->unmaps_pending += 1;
    }
  /* window was reparented to this position */
  window->rect.x = 0;
  window->rect.y = 0;

  XReparentWindow (window->display->xdisplay,
                   window->xwindow,
                   frame->xwindow,
                   window->rect.x,
                   window->rect.y);
  /* FIXME handle this error */
  meta_error_trap_pop (window->display, FALSE);

  /* stick frame to the window */
  window->frame = frame;

  meta_ui_map_frame (window->screen->ui, window->frame->xwindow);

  /* Now that frame->xwindow is registered with window, we can set its
   * style and background.
   */
  meta_ui_update_frame_style (window->screen->ui, frame->xwindow);

  if (window->title)
    meta_ui_set_frame_title (window->screen->ui,
                             window->frame->xwindow,
                             window->title);

  /* Move keybindings to frame instead of window */
  meta_window_grab_keys (window);

  /* Shape mask */
  meta_ui_apply_frame_shape (frame->window->screen->ui,
                             frame->xwindow,
                             frame->rect.width,
                             frame->rect.height,
                             frame->window->has_shape);
  frame->need_reapply_frame_shape = FALSE;

  meta_display_ungrab (window->display);

  {
      Display* xdisplay = window->display->xdisplay;

      unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
      XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };

      XISetMask (mask.mask, XI_ButtonPress);
      XISetMask (mask.mask, XI_ButtonRelease);
      XISetMask (mask.mask, XI_Motion);
      XISetMask (mask.mask, XI_Enter);
      XISetMask (mask.mask, XI_Leave);

      XISelectEvents (xdisplay, frame->xwindow, &mask, 1);
  }

  meta_prefs_add_listener (prefs_changed_callback, frame);
}
Пример #2
0
void
meta_window_ensure_frame (MetaWindow *window)
{
  MetaFrame *frame;
  XSetWindowAttributes attrs;
  gulong create_serial;

  if (window->frame)
    return;

  frame = g_new (MetaFrame, 1);

  frame->window = window;
  frame->xwindow = None;

  frame->rect = window->rect;
  frame->child_x = 0;
  frame->child_y = 0;
  frame->bottom_height = 0;
  frame->right_width = 0;
  frame->current_cursor = 0;

  frame->is_flashing = FALSE;
  frame->borders_cached = FALSE;

  meta_verbose ("Frame geometry %d,%d  %dx%d\n",
                frame->rect.x, frame->rect.y,
                frame->rect.width, frame->rect.height);

  frame->ui_frame = meta_ui_create_frame (window->screen->ui,
                                          window->display->xdisplay,
                                          frame->window,
                                          window->xvisual,
                                          frame->rect.x,
                                          frame->rect.y,
                                          frame->rect.width,
                                          frame->rect.height,
                                          &create_serial);
  frame->xwindow = frame->ui_frame->xwindow;

  meta_stack_tracker_record_add (window->screen->stack_tracker,
                                 frame->xwindow,
                                 create_serial);

  meta_verbose ("Frame for %s is 0x%lx\n", frame->window->desc, frame->xwindow);
  attrs.event_mask = EVENT_MASK;
  XChangeWindowAttributes (window->display->xdisplay,
			   frame->xwindow, CWEventMask, &attrs);

  meta_display_register_x_window (window->display, &frame->xwindow, window);

  meta_error_trap_push (window->display);
  if (window->mapped)
    {
      window->mapped = FALSE; /* the reparent will unmap the window,
                               * we don't want to take that as a withdraw
                               */
      meta_topic (META_DEBUG_WINDOW_STATE,
                  "Incrementing unmaps_pending on %s for reparent\n", window->desc);
      window->unmaps_pending += 1;
    }

  meta_stack_tracker_record_remove (window->screen->stack_tracker,
                                    window->xwindow,
                                    XNextRequest (window->display->xdisplay));
  XReparentWindow (window->display->xdisplay,
                   window->xwindow,
                   frame->xwindow,
                   frame->child_x,
                   frame->child_y);
  /* FIXME handle this error */
  meta_error_trap_pop (window->display);

  /* stick frame to the window */
  window->frame = frame;

  /* Now that frame->xwindow is registered with window, we can set its
   * style and background.
   */
  meta_frame_update_style (frame);
  meta_frame_update_title (frame);

  meta_ui_map_frame (frame->window->screen->ui, frame->xwindow);

  {
    MetaBackend *backend = meta_get_backend ();
    if (META_IS_BACKEND_X11 (backend))
      {
        Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));

        /* Since the backend selects for events on another connection,
         * make sure to sync the GTK+ connection to ensure that the
         * frame window has been created on the server at this point. */
        XSync (window->display->xdisplay, False);

        unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
        XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };

        XISelectEvents (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
                        frame->xwindow, &mask, 1);

        XISetMask (mask.mask, XI_ButtonPress);
        XISetMask (mask.mask, XI_ButtonRelease);
        XISetMask (mask.mask, XI_Motion);
        XISetMask (mask.mask, XI_Enter);
        XISetMask (mask.mask, XI_Leave);

        XISelectEvents (xdisplay, frame->xwindow, &mask, 1);
      }
  }

  /* Move keybindings to frame instead of window */
  meta_window_grab_keys (window);
}
Пример #3
0
LOCAL_SYMBOL void
meta_window_ensure_frame (MetaWindow *window)
{
    MetaFrame *frame;
    XSetWindowAttributes attrs;
    Visual *visual;
    gulong create_serial;

    if (window->frame)
        return;

    /* See comment below for why this is required. */
    meta_display_grab (window->display);

    frame = g_new (MetaFrame, 1);

    frame->window = window;
    frame->xwindow = None;

    frame->rect = window->rect;
    frame->child_x = 0;
    frame->child_y = 0;
    frame->bottom_height = 0;
    frame->right_width = 0;
    frame->current_cursor = 0;

    frame->is_flashing = FALSE;

    meta_verbose ("Framing window %s: visual %s default, depth %d default depth %d\n",
                  window->desc,
                  XVisualIDFromVisual (window->xvisual) ==
                  XVisualIDFromVisual (window->screen->default_xvisual) ?
                  "is" : "is not",
                  window->depth, window->screen->default_depth);
    meta_verbose ("Frame geometry %d,%d  %dx%d\n",
                  frame->rect.x, frame->rect.y,
                  frame->rect.width, frame->rect.height);

    /* Default depth/visual handles clients with weird visuals; they can
     * always be children of the root depth/visual obviously, but
     * e.g. DRI games can't be children of a parent that has the same
     * visual as the client. NULL means default visual.
     *
     * We look for an ARGB visual if we can find one, otherwise use
     * the default of NULL.
     */

    /* Special case for depth 32 windows (assumed to be ARGB),
     * we use the window's visual. Otherwise we just use the system visual.
     */
    if (window->depth == 32)
        visual = window->xvisual;
    else
        visual = NULL;

    frame->xwindow = meta_ui_create_frame_window (window->screen->ui,
                     window->display->xdisplay,
                     visual,
                     frame->rect.x,
                     frame->rect.y,
                     frame->rect.width,
                     frame->rect.height,
                     frame->window->screen->number,
                     &create_serial);
    meta_stack_tracker_record_add (window->screen->stack_tracker,
                                   frame->xwindow,
                                   create_serial);

    meta_verbose ("Frame for %s is 0x%lx\n", frame->window->desc, frame->xwindow);
    attrs.event_mask = EVENT_MASK;
    XChangeWindowAttributes (window->display->xdisplay,
                             frame->xwindow, CWEventMask, &attrs);

    meta_display_register_x_window (window->display, &frame->xwindow, window);

    /* Reparent the client window; it may be destroyed,
     * thus the error trap. We'll get a destroy notify later
     * and free everything. Comment in FVWM source code says
     * we need a server grab or the child can get its MapNotify
     * before we've finished reparenting and getting the decoration
     * window onscreen, so ensure_frame must be called with
     * a grab.
     */
    meta_error_trap_push (window->display);
    if (window->mapped)
    {
        window->mapped = FALSE; /* the reparent will unmap the window,
                               * we don't want to take that as a withdraw
                               */
        meta_topic (META_DEBUG_WINDOW_STATE,
                    "Incrementing unmaps_pending on %s for reparent\n", window->desc);
        window->unmaps_pending += 1;
    }
    /* window was reparented to this position */
    window->rect.x = 0;
    window->rect.y = 0;

    meta_stack_tracker_record_remove (window->screen->stack_tracker,
                                      window->xwindow,
                                      XNextRequest (window->display->xdisplay));
    XReparentWindow (window->display->xdisplay,
                     window->xwindow,
                     frame->xwindow,
                     window->rect.x,
                     window->rect.y);
    /* FIXME handle this error */
    meta_error_trap_pop (window->display);

    /* stick frame to the window */
    window->frame = frame;

    /* Now that frame->xwindow is registered with window, we can set its
     * style and background.
     */
    meta_ui_update_frame_style (window->screen->ui, frame->xwindow);
    meta_ui_reset_frame_bg (window->screen->ui, frame->xwindow);

    if (window->title)
        meta_ui_set_frame_title (window->screen->ui,
                                 window->frame->xwindow,
                                 window->title);

    /* Move keybindings to frame instead of window */
    meta_window_grab_keys (window);

    meta_ui_map_frame (frame->window->screen->ui, frame->xwindow);

    meta_display_ungrab (window->display);
}