Compare commits
	
		
			2 Commits
		
	
	
		
			3.22.0
			...
			wip/no-rep
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					2ff2a27229 | ||
| 
						 | 
					9c362f7fe4 | 
@@ -94,8 +94,6 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	core/display.c				\
 | 
			
		||||
	core/display-private.h			\
 | 
			
		||||
	meta/display.h				\
 | 
			
		||||
	ui/draw-workspace.c			\
 | 
			
		||||
	ui/draw-workspace.h			\
 | 
			
		||||
	core/edge-resistance.c			\
 | 
			
		||||
	core/edge-resistance.h			\
 | 
			
		||||
	core/edid-parse.c			\
 | 
			
		||||
@@ -104,8 +102,6 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	meta/errors.h				\
 | 
			
		||||
	core/frame.c				\
 | 
			
		||||
	core/frame.h				\
 | 
			
		||||
	ui/gradient.c				\
 | 
			
		||||
	meta/gradient.h				\
 | 
			
		||||
	core/group-private.h			\
 | 
			
		||||
	core/group-props.c			\
 | 
			
		||||
	core/group-props.h			\
 | 
			
		||||
@@ -154,22 +150,12 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	core/xprops.h				\
 | 
			
		||||
	meta/common.h				\
 | 
			
		||||
	core/core.h				\
 | 
			
		||||
	ui/ui.c					\
 | 
			
		||||
	ui/ui.h					\
 | 
			
		||||
	ui/frames.c				\
 | 
			
		||||
	ui/frames.h				\
 | 
			
		||||
	ui/menu.c				\
 | 
			
		||||
	ui/menu.h				\
 | 
			
		||||
	ui/metaaccellabel.c			\
 | 
			
		||||
	ui/metaaccellabel.h			\
 | 
			
		||||
	ui/resizepopup.c			\
 | 
			
		||||
	ui/resizepopup.h			\
 | 
			
		||||
	ui/tabpopup.c				\
 | 
			
		||||
	ui/tabpopup.h				\
 | 
			
		||||
	ui/theme-parser.c			\
 | 
			
		||||
	ui/theme.c				\
 | 
			
		||||
	meta/theme.h				\
 | 
			
		||||
	ui/theme-private.h			\
 | 
			
		||||
	ui/ui.c
 | 
			
		||||
	ui/resizepopup.h
 | 
			
		||||
 | 
			
		||||
nodist_libmutter_la_SOURCES =			\
 | 
			
		||||
	$(mutter_built_sources)
 | 
			
		||||
@@ -187,7 +173,6 @@ libmutterinclude_base_headers =		\
 | 
			
		||||
	meta/compositor.h			\
 | 
			
		||||
	meta/display.h				\
 | 
			
		||||
	meta/errors.h				\
 | 
			
		||||
	meta/gradient.h				\
 | 
			
		||||
	meta/group.h				\
 | 
			
		||||
	meta/keybindings.h			\
 | 
			
		||||
	meta/main.h				\
 | 
			
		||||
@@ -202,7 +187,6 @@ libmutterinclude_base_headers =		\
 | 
			
		||||
	meta/meta-window-actor.h		\
 | 
			
		||||
	meta/prefs.h				\
 | 
			
		||||
	meta/screen.h				\
 | 
			
		||||
	meta/theme.h				\
 | 
			
		||||
	meta/types.h				\
 | 
			
		||||
	meta/util.h				\
 | 
			
		||||
	meta/window.h				\
 | 
			
		||||
@@ -258,13 +242,11 @@ Meta-$(api_version).gir: libmutter.la
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
testboxes_SOURCES = core/testboxes.c
 | 
			
		||||
testgradient_SOURCES = ui/testgradient.c
 | 
			
		||||
testasyncgetprop_SOURCES = core/testasyncgetprop.c
 | 
			
		||||
 | 
			
		||||
noinst_PROGRAMS=testboxes testgradient testasyncgetprop
 | 
			
		||||
noinst_PROGRAMS=testboxes testasyncgetprop
 | 
			
		||||
 | 
			
		||||
testboxes_LDADD = $(MUTTER_LIBS) libmutter.la
 | 
			
		||||
testgradient_LDADD = $(MUTTER_LIBS) libmutter.la
 | 
			
		||||
testasyncgetprop_LDADD = $(MUTTER_LIBS) libmutter.la
 | 
			
		||||
 | 
			
		||||
@INTLTOOL_DESKTOP_RULE@
 | 
			
		||||
 
 | 
			
		||||
@@ -361,6 +361,7 @@ meta_window_actor_dispose (GObject *object)
 | 
			
		||||
  xdisplay = meta_display_get_xdisplay (display);
 | 
			
		||||
  info     = meta_screen_get_compositor_data (screen);
 | 
			
		||||
 | 
			
		||||
  meta_window_actor_set_redirected (self, FALSE);
 | 
			
		||||
  meta_window_actor_detach (self);
 | 
			
		||||
 | 
			
		||||
  if (priv->send_frame_messages_timer != 0)
 | 
			
		||||
@@ -484,6 +485,36 @@ meta_window_actor_get_property (GObject      *object,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char*
 | 
			
		||||
meta_frame_type_to_string (MetaFrameType type)
 | 
			
		||||
{
 | 
			
		||||
  switch (type)
 | 
			
		||||
    {
 | 
			
		||||
    case META_FRAME_TYPE_NORMAL:
 | 
			
		||||
      return "normal";
 | 
			
		||||
    case META_FRAME_TYPE_DIALOG:
 | 
			
		||||
      return "dialog";
 | 
			
		||||
    case META_FRAME_TYPE_MODAL_DIALOG:
 | 
			
		||||
      return "modal_dialog";
 | 
			
		||||
    case META_FRAME_TYPE_UTILITY:
 | 
			
		||||
      return "utility";
 | 
			
		||||
    case META_FRAME_TYPE_MENU:
 | 
			
		||||
      return "menu";
 | 
			
		||||
    case META_FRAME_TYPE_BORDER:
 | 
			
		||||
      return "border";
 | 
			
		||||
    case META_FRAME_TYPE_ATTACHED:
 | 
			
		||||
      return "attached";
 | 
			
		||||
#if 0
 | 
			
		||||
    case META_FRAME_TYPE_TOOLBAR:
 | 
			
		||||
      return "toolbar";
 | 
			
		||||
#endif
 | 
			
		||||
    case  META_FRAME_TYPE_LAST:
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return "<unknown>";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char *
 | 
			
		||||
meta_window_actor_get_shadow_class (MetaWindowActor *self)
 | 
			
		||||
{
 | 
			
		||||
@@ -1842,43 +1873,6 @@ meta_window_actor_sync_visibility (MetaWindowActor *self)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static cairo_region_t *
 | 
			
		||||
scan_visible_region (guchar         *mask_data,
 | 
			
		||||
                     int             stride,
 | 
			
		||||
                     cairo_region_t *scan_area)
 | 
			
		||||
{
 | 
			
		||||
  int i, n_rects = cairo_region_num_rectangles (scan_area);
 | 
			
		||||
  MetaRegionBuilder builder;
 | 
			
		||||
 | 
			
		||||
  meta_region_builder_init (&builder);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_rects; i++)
 | 
			
		||||
    {
 | 
			
		||||
      int x, y;
 | 
			
		||||
      cairo_rectangle_int_t rect;
 | 
			
		||||
 | 
			
		||||
      cairo_region_get_rectangle (scan_area, i, &rect);
 | 
			
		||||
 | 
			
		||||
      for (y = rect.y; y < (rect.y + rect.height); y++)
 | 
			
		||||
        {
 | 
			
		||||
          for (x = rect.x; x < (rect.x + rect.width); x++)
 | 
			
		||||
            {
 | 
			
		||||
              int x2 = x;
 | 
			
		||||
              while (mask_data[y * stride + x2] == 255 && x2 < (rect.x + rect.width))
 | 
			
		||||
                x2++;
 | 
			
		||||
 | 
			
		||||
              if (x2 > x)
 | 
			
		||||
                {
 | 
			
		||||
                  meta_region_builder_add_rectangle (&builder, x, y, x2 - x, 1);
 | 
			
		||||
                  x = x2;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return meta_region_builder_finish (&builder);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
build_and_scan_frame_mask (MetaWindowActor       *self,
 | 
			
		||||
                           cairo_rectangle_int_t *client_area,
 | 
			
		||||
@@ -1914,27 +1908,6 @@ build_and_scan_frame_mask (MetaWindowActor       *self,
 | 
			
		||||
  gdk_cairo_region (cr, shape_region);
 | 
			
		||||
  cairo_fill (cr);
 | 
			
		||||
 | 
			
		||||
  if (priv->window->frame != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_region_t *frame_paint_region, *scanned_region;
 | 
			
		||||
      cairo_rectangle_int_t rect = { 0, 0, tex_width, tex_height };
 | 
			
		||||
 | 
			
		||||
      /* Make sure we don't paint the frame over the client window. */
 | 
			
		||||
      frame_paint_region = cairo_region_create_rectangle (&rect);
 | 
			
		||||
      cairo_region_subtract_rectangle (frame_paint_region, client_area);
 | 
			
		||||
 | 
			
		||||
      gdk_cairo_region (cr, frame_paint_region);
 | 
			
		||||
      cairo_clip (cr);
 | 
			
		||||
 | 
			
		||||
      meta_frame_get_mask (priv->window->frame, cr);
 | 
			
		||||
 | 
			
		||||
      cairo_surface_flush (surface);
 | 
			
		||||
      scanned_region = scan_visible_region (mask_data, stride, frame_paint_region);
 | 
			
		||||
      cairo_region_union (shape_region, scanned_region);
 | 
			
		||||
      cairo_region_destroy (scanned_region);
 | 
			
		||||
      cairo_region_destroy (frame_paint_region);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  cairo_destroy (cr);
 | 
			
		||||
  cairo_surface_destroy (surface);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4175,20 +4175,6 @@ meta_display_end_grab_op (MetaDisplay *display,
 | 
			
		||||
      if (!display->grab_threshold_movement_reached)
 | 
			
		||||
        meta_window_raise (display->grab_window);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op) ||
 | 
			
		||||
      display->grab_op == META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING)
 | 
			
		||||
    {
 | 
			
		||||
      if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op))
 | 
			
		||||
        meta_screen_tab_popup_destroy (display->grab_screen);
 | 
			
		||||
      else
 | 
			
		||||
        meta_screen_workspace_popup_destroy (display->grab_screen);
 | 
			
		||||
 | 
			
		||||
      /* If the ungrab here causes an EnterNotify, ignore it for
 | 
			
		||||
       * sloppy focus
 | 
			
		||||
       */
 | 
			
		||||
      display->ungrab_should_not_cause_focus_window = display->grab_xwindow;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  /* If this was a move or resize clear out the edge cache */
 | 
			
		||||
  if (meta_grab_op_is_resizing (display->grab_op) || 
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										159
									
								
								src/core/frame.c
									
									
									
									
									
								
							
							
						
						
									
										159
									
								
								src/core/frame.c
									
									
									
									
									
								
							@@ -43,7 +43,6 @@ meta_window_ensure_frame (MetaWindow *window)
 | 
			
		||||
{
 | 
			
		||||
  MetaFrame *frame;
 | 
			
		||||
  XSetWindowAttributes attrs;
 | 
			
		||||
  Visual *visual;
 | 
			
		||||
  gulong create_serial;
 | 
			
		||||
  
 | 
			
		||||
  if (window->frame)
 | 
			
		||||
@@ -62,53 +61,34 @@ meta_window_ensure_frame (MetaWindow *window)
 | 
			
		||||
  frame->current_cursor = 0;
 | 
			
		||||
 | 
			
		||||
  frame->is_flashing = FALSE;
 | 
			
		||||
  frame->borders_cached = 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);
 | 
			
		||||
 | 
			
		||||
  attrs.event_mask = EVENT_MASK;
 | 
			
		||||
  XChangeWindowAttributes (window->display->xdisplay,
 | 
			
		||||
			   frame->xwindow, CWEventMask, &attrs);
 | 
			
		||||
 | 
			
		||||
  create_serial = XNextRequest (window->display->xdisplay);
 | 
			
		||||
 | 
			
		||||
  frame->xwindow = XCreateWindow (window->display->xdisplay,
 | 
			
		||||
                                  DefaultRootWindow (window->display->xdisplay),
 | 
			
		||||
                                  frame->rect.x, frame->rect.y,
 | 
			
		||||
                                  frame->rect.width, frame->rect.height,
 | 
			
		||||
                                  0,
 | 
			
		||||
                                  CopyFromParent,
 | 
			
		||||
                                  InputOnly,
 | 
			
		||||
                                  CopyFromParent,
 | 
			
		||||
                                  CWEventMask,
 | 
			
		||||
                                  &attrs);
 | 
			
		||||
 | 
			
		||||
  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);
 | 
			
		||||
@@ -128,28 +108,12 @@ meta_window_ensure_frame (MetaWindow *window)
 | 
			
		||||
  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);
 | 
			
		||||
 | 
			
		||||
@@ -190,18 +154,9 @@ meta_window_destroy_frame (MetaWindow *window)
 | 
			
		||||
  meta_stack_tracker_record_add (window->screen->stack_tracker,
 | 
			
		||||
                                 window->xwindow,
 | 
			
		||||
                                 XNextRequest (window->display->xdisplay));
 | 
			
		||||
  XReparentWindow (window->display->xdisplay,
 | 
			
		||||
                   window->xwindow,
 | 
			
		||||
                   window->screen->xroot,
 | 
			
		||||
                   /* Using anything other than meta_window_get_position()
 | 
			
		||||
                    * coordinates here means we'll need to ensure a configure
 | 
			
		||||
                    * notify event is sent; see bug 399552.
 | 
			
		||||
                    */
 | 
			
		||||
                   window->frame->rect.x + borders.invisible.left,
 | 
			
		||||
                   window->frame->rect.y + borders.invisible.top);
 | 
			
		||||
  meta_error_trap_pop (window->display);
 | 
			
		||||
 | 
			
		||||
  meta_ui_destroy_frame_window (window->screen->ui, frame->xwindow);
 | 
			
		||||
  XDestroyWindow (window->display->xdisplay, frame->xwindow);
 | 
			
		||||
 | 
			
		||||
  meta_display_unregister_x_window (window->display,
 | 
			
		||||
                                    frame->xwindow);
 | 
			
		||||
@@ -309,22 +264,7 @@ void
 | 
			
		||||
meta_frame_calc_borders (MetaFrame        *frame,
 | 
			
		||||
                         MetaFrameBorders *borders)
 | 
			
		||||
{
 | 
			
		||||
  /* Save on if statements and potential uninitialized values
 | 
			
		||||
   * in callers -- if there's no frame, then zero the borders. */
 | 
			
		||||
  if (frame == NULL)
 | 
			
		||||
    meta_frame_borders_clear (borders);
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      if (!frame->borders_cached)
 | 
			
		||||
        {
 | 
			
		||||
          meta_ui_get_frame_borders (frame->window->screen->ui,
 | 
			
		||||
                                     frame->xwindow,
 | 
			
		||||
                                     &frame->cached_borders);
 | 
			
		||||
          frame->borders_cached = TRUE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      *borders = frame->cached_borders;
 | 
			
		||||
    }
 | 
			
		||||
  meta_frame_borders_clear (borders);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -346,35 +286,12 @@ meta_frame_sync_to_window (MetaFrame *frame,
 | 
			
		||||
              frame->rect.x + frame->rect.width,
 | 
			
		||||
              frame->rect.y + frame->rect.height);
 | 
			
		||||
 | 
			
		||||
  /* set bg to none to avoid flicker */
 | 
			
		||||
  if (need_resize)
 | 
			
		||||
    {
 | 
			
		||||
      meta_ui_unflicker_frame_bg (frame->window->screen->ui,
 | 
			
		||||
                                  frame->xwindow,
 | 
			
		||||
                                  frame->rect.width,
 | 
			
		||||
                                  frame->rect.height);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_ui_move_resize_frame (frame->window->screen->ui,
 | 
			
		||||
			     frame->xwindow,
 | 
			
		||||
			     frame->rect.x,
 | 
			
		||||
			     frame->rect.y,
 | 
			
		||||
			     frame->rect.width,
 | 
			
		||||
			     frame->rect.height);
 | 
			
		||||
 | 
			
		||||
  if (need_resize)
 | 
			
		||||
    {
 | 
			
		||||
      meta_ui_reset_frame_bg (frame->window->screen->ui,
 | 
			
		||||
                              frame->xwindow);
 | 
			
		||||
 | 
			
		||||
      /* If we're interactively resizing the frame, repaint
 | 
			
		||||
       * it immediately so we don't start to lag.
 | 
			
		||||
       */
 | 
			
		||||
      if (frame->window->display->grab_window ==
 | 
			
		||||
          frame->window)
 | 
			
		||||
        meta_ui_repaint_frame (frame->window->screen->ui,
 | 
			
		||||
                               frame->xwindow);
 | 
			
		||||
    }
 | 
			
		||||
  XMoveResizeWindow (frame->window->display->xdisplay,
 | 
			
		||||
                     frame->xwindow,
 | 
			
		||||
                     frame->rect.x,
 | 
			
		||||
                     frame->rect.y,
 | 
			
		||||
                     frame->rect.width,
 | 
			
		||||
                     frame->rect.height);
 | 
			
		||||
 | 
			
		||||
  return need_resize;
 | 
			
		||||
}
 | 
			
		||||
@@ -382,25 +299,19 @@ meta_frame_sync_to_window (MetaFrame *frame,
 | 
			
		||||
cairo_region_t *
 | 
			
		||||
meta_frame_get_frame_bounds (MetaFrame *frame)
 | 
			
		||||
{
 | 
			
		||||
  return meta_ui_get_frame_bounds (frame->window->screen->ui,
 | 
			
		||||
                                   frame->xwindow,
 | 
			
		||||
                                   frame->rect.width,
 | 
			
		||||
                                   frame->rect.height);
 | 
			
		||||
}
 | 
			
		||||
  cairo_rectangle_int_t rect;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_frame_get_mask (MetaFrame                    *frame,
 | 
			
		||||
                     cairo_t                      *cr)
 | 
			
		||||
{
 | 
			
		||||
  meta_ui_get_frame_mask (frame->window->screen->ui, frame->xwindow,
 | 
			
		||||
                          frame->rect.width, frame->rect.height, cr);
 | 
			
		||||
  rect.x = frame->window->rect.x;
 | 
			
		||||
  rect.y = frame->window->rect.y;
 | 
			
		||||
  rect.width = frame->window->rect.width;
 | 
			
		||||
  rect.height = frame->window->rect.height;
 | 
			
		||||
 | 
			
		||||
  return cairo_region_create_rectangles (&rect, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_frame_queue_draw (MetaFrame *frame)
 | 
			
		||||
{
 | 
			
		||||
  meta_ui_queue_frame_draw (frame->window->screen->ui,
 | 
			
		||||
                            frame->xwindow);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 
 | 
			
		||||
@@ -72,9 +72,6 @@ void meta_frame_clear_cached_borders (MetaFrame *frame);
 | 
			
		||||
 | 
			
		||||
cairo_region_t *meta_frame_get_frame_bounds (MetaFrame *frame);
 | 
			
		||||
 | 
			
		||||
void meta_frame_get_mask (MetaFrame *frame,
 | 
			
		||||
                          cairo_t   *cr);
 | 
			
		||||
 | 
			
		||||
void meta_frame_set_screen_cursor (MetaFrame	*frame,
 | 
			
		||||
				   MetaCursor	cursor);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -134,16 +134,6 @@ static gboolean process_keyboard_resize_grab (MetaDisplay   *display,
 | 
			
		||||
                                              XIDeviceEvent *event,
 | 
			
		||||
                                              KeySym         keysym);
 | 
			
		||||
 | 
			
		||||
static gboolean process_tab_grab           (MetaDisplay   *display,
 | 
			
		||||
                                            MetaScreen    *screen,
 | 
			
		||||
                                            XIDeviceEvent *event,
 | 
			
		||||
                                            KeySym         keysym);
 | 
			
		||||
 | 
			
		||||
static gboolean process_workspace_switch_grab (MetaDisplay   *display,
 | 
			
		||||
                                               MetaScreen    *screen,
 | 
			
		||||
                                               XIDeviceEvent *event,
 | 
			
		||||
                                               KeySym         keysym);
 | 
			
		||||
 | 
			
		||||
static void grab_key_bindings           (MetaDisplay *display);
 | 
			
		||||
static void ungrab_key_bindings         (MetaDisplay *display);
 | 
			
		||||
 | 
			
		||||
@@ -1672,48 +1662,6 @@ is_modifier (MetaDisplay *display,
 | 
			
		||||
 * mod5 = 7
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
is_specific_modifier (MetaDisplay *display,
 | 
			
		||||
                      unsigned int keycode,
 | 
			
		||||
                      unsigned int mask)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  int end;
 | 
			
		||||
  gboolean retval = FALSE;
 | 
			
		||||
  int mod_index;
 | 
			
		||||
 | 
			
		||||
  g_assert (display->modmap);
 | 
			
		||||
 | 
			
		||||
  meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
              "Checking whether code 0x%x is bound to modifier 0x%x\n",
 | 
			
		||||
              keycode, mask);
 | 
			
		||||
 | 
			
		||||
  mod_index = 0;
 | 
			
		||||
  mask = mask >> 1;
 | 
			
		||||
  while (mask != 0)
 | 
			
		||||
    {
 | 
			
		||||
      mod_index += 1;
 | 
			
		||||
      mask = mask >> 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
              "Modifier has index %d\n", mod_index);
 | 
			
		||||
 | 
			
		||||
  end = (mod_index + 1) * display->modmap->max_keypermod;
 | 
			
		||||
  i = mod_index * display->modmap->max_keypermod;
 | 
			
		||||
  while (i < end)
 | 
			
		||||
    {
 | 
			
		||||
      if (keycode == display->modmap->modifiermap[i])
 | 
			
		||||
        {
 | 
			
		||||
          retval = TRUE;
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      ++i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static unsigned int
 | 
			
		||||
get_primary_modifier (MetaDisplay *display,
 | 
			
		||||
                      unsigned int entire_binding_mask)
 | 
			
		||||
@@ -1741,24 +1689,6 @@ get_primary_modifier (MetaDisplay *display,
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
keycode_is_primary_modifier (MetaDisplay *display,
 | 
			
		||||
                             unsigned int keycode,
 | 
			
		||||
                             unsigned int entire_binding_mask)
 | 
			
		||||
{
 | 
			
		||||
  unsigned int primary_modifier;
 | 
			
		||||
 | 
			
		||||
  meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
              "Checking whether code 0x%x is the primary modifier of mask 0x%x\n",
 | 
			
		||||
              keycode, entire_binding_mask);
 | 
			
		||||
 | 
			
		||||
  primary_modifier = get_primary_modifier (display, entire_binding_mask);
 | 
			
		||||
  if (primary_modifier != 0)
 | 
			
		||||
    return is_specific_modifier (display, keycode, primary_modifier);
 | 
			
		||||
  else
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
primary_modifier_still_pressed (MetaDisplay *display,
 | 
			
		||||
                                unsigned int entire_binding_mask)
 | 
			
		||||
@@ -1820,20 +1750,6 @@ invoke_handler (MetaDisplay    *display,
 | 
			
		||||
                               NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
invoke_handler_by_name (MetaDisplay    *display,
 | 
			
		||||
                        MetaScreen     *screen,
 | 
			
		||||
                        const char     *handler_name,
 | 
			
		||||
                        MetaWindow     *window,
 | 
			
		||||
                        XIDeviceEvent  *event)
 | 
			
		||||
{
 | 
			
		||||
  MetaKeyHandler *handler;
 | 
			
		||||
 | 
			
		||||
  handler = HANDLER (handler_name);
 | 
			
		||||
  if (handler)
 | 
			
		||||
    invoke_handler (display, screen, handler, window, event, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
process_event (MetaKeyBinding       *bindings,
 | 
			
		||||
               int                   n_bindings,
 | 
			
		||||
@@ -2067,10 +1983,6 @@ meta_display_process_key_event (MetaDisplay   *display,
 | 
			
		||||
  if (screen == NULL)
 | 
			
		||||
    return FALSE; /* event window is destroyed */
 | 
			
		||||
 | 
			
		||||
  /* ignore key events on popup menus and such. */
 | 
			
		||||
  if (meta_ui_window_is_widget (screen->ui, event->event))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  /* window may be NULL */
 | 
			
		||||
 | 
			
		||||
  keysym = XKeycodeToKeysym (display->xdisplay, event->detail, 0);
 | 
			
		||||
@@ -2153,23 +2065,6 @@ meta_display_process_key_event (MetaDisplay   *display,
 | 
			
		||||
                                                        window, event, keysym);
 | 
			
		||||
              break;
 | 
			
		||||
 | 
			
		||||
            case META_GRAB_OP_KEYBOARD_TABBING_NORMAL:
 | 
			
		||||
            case META_GRAB_OP_KEYBOARD_TABBING_DOCK:
 | 
			
		||||
            case META_GRAB_OP_KEYBOARD_TABBING_GROUP:
 | 
			
		||||
            case META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL:
 | 
			
		||||
            case META_GRAB_OP_KEYBOARD_ESCAPING_DOCK:
 | 
			
		||||
            case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP:
 | 
			
		||||
              meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
                          "Processing event for keyboard tabbing/cycling\n");
 | 
			
		||||
              keep_grab = process_tab_grab (display, screen, event, keysym);
 | 
			
		||||
              break;
 | 
			
		||||
 | 
			
		||||
            case META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING:
 | 
			
		||||
              meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
                          "Processing event for keyboard workspace switching\n");
 | 
			
		||||
              keep_grab = process_workspace_switch_grab (display, screen, event, keysym);
 | 
			
		||||
              break;
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
              break;
 | 
			
		||||
            }
 | 
			
		||||
@@ -2719,348 +2614,6 @@ process_keyboard_resize_grab (MetaDisplay   *display,
 | 
			
		||||
  return handled;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
end_keyboard_grab (MetaDisplay *display,
 | 
			
		||||
		   unsigned int keycode)
 | 
			
		||||
{
 | 
			
		||||
#ifdef HAVE_XKB
 | 
			
		||||
  if (display->xkb_base_event_type > 0)
 | 
			
		||||
    {
 | 
			
		||||
      unsigned int primary_modifier;
 | 
			
		||||
      XkbStateRec state;
 | 
			
		||||
 | 
			
		||||
      primary_modifier = get_primary_modifier (display, display->grab_mask);
 | 
			
		||||
 | 
			
		||||
      XkbGetState (display->xdisplay, XkbUseCoreKbd, &state);
 | 
			
		||||
 | 
			
		||||
      if (!(primary_modifier & state.mods))
 | 
			
		||||
	return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
      if (keycode_is_primary_modifier (display, keycode, display->grab_mask))
 | 
			
		||||
	return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
process_tab_grab (MetaDisplay   *display,
 | 
			
		||||
                  MetaScreen    *screen,
 | 
			
		||||
                  XIDeviceEvent *event,
 | 
			
		||||
                  KeySym         keysym)
 | 
			
		||||
{
 | 
			
		||||
  MetaKeyBinding *binding;
 | 
			
		||||
  MetaKeyBindingAction action;
 | 
			
		||||
  gboolean popup_not_showing;
 | 
			
		||||
  gboolean backward;
 | 
			
		||||
  gboolean key_used;
 | 
			
		||||
  MetaWindow *prev_window;
 | 
			
		||||
 | 
			
		||||
  if (screen != display->grab_screen)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  binding = display_get_keybinding (display,
 | 
			
		||||
                                    keysym,
 | 
			
		||||
                                    event->detail,
 | 
			
		||||
                                    display->grab_mask);
 | 
			
		||||
  if (binding)
 | 
			
		||||
    action = meta_prefs_get_keybinding_action (binding->name);
 | 
			
		||||
  else
 | 
			
		||||
    action = META_KEYBINDING_ACTION_NONE;
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * If there is no tab_pop up object, i.e., there is some custom handler
 | 
			
		||||
   * implementing Alt+Tab & Co., we call this custom handler; we do not
 | 
			
		||||
   * mess about with the grab, as that is up to the handler to deal with.
 | 
			
		||||
   */
 | 
			
		||||
  if (!screen->tab_popup)
 | 
			
		||||
    {
 | 
			
		||||
      if (event->evtype == XI_KeyRelease)
 | 
			
		||||
        {
 | 
			
		||||
          if (end_keyboard_grab (display, event->detail))
 | 
			
		||||
            {
 | 
			
		||||
              invoke_handler_by_name (display, screen, "tab-popup-select", NULL, event);
 | 
			
		||||
 | 
			
		||||
              /* We return FALSE to end the grab; if the handler ended the grab itself
 | 
			
		||||
               * that will be a noop. If the handler didn't end the grab, then it's a
 | 
			
		||||
               * safety measure to prevent a stuck grab.
 | 
			
		||||
               */
 | 
			
		||||
              return FALSE;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          return TRUE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      switch (action)
 | 
			
		||||
        {
 | 
			
		||||
        case META_KEYBINDING_ACTION_CYCLE_PANELS:
 | 
			
		||||
        case META_KEYBINDING_ACTION_CYCLE_WINDOWS:
 | 
			
		||||
        case META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD:
 | 
			
		||||
        case META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD:
 | 
			
		||||
        case META_KEYBINDING_ACTION_SWITCH_PANELS:
 | 
			
		||||
        case META_KEYBINDING_ACTION_SWITCH_WINDOWS:
 | 
			
		||||
        case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS:
 | 
			
		||||
        case META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD:
 | 
			
		||||
        case META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD:
 | 
			
		||||
        case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD:
 | 
			
		||||
        case META_KEYBINDING_ACTION_CYCLE_GROUP:
 | 
			
		||||
        case META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD:
 | 
			
		||||
        case META_KEYBINDING_ACTION_SWITCH_GROUP:
 | 
			
		||||
        case META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD:
 | 
			
		||||
          /* These are the tab-popup bindings. If a custom Alt-Tab implementation
 | 
			
		||||
           * is in effect, we expect it to want to handle all of these as a group
 | 
			
		||||
           *
 | 
			
		||||
           * If there are some of them that the custom implementation didn't
 | 
			
		||||
           * handle, we treat them as "unbound" for the duration - running the
 | 
			
		||||
           * normal handlers could get us into trouble.
 | 
			
		||||
           */
 | 
			
		||||
          if (binding->handler &&
 | 
			
		||||
              binding->handler->func &&
 | 
			
		||||
              binding->handler->func != binding->handler->default_func)
 | 
			
		||||
            {
 | 
			
		||||
              invoke_handler (display, screen, binding->handler, NULL, event, binding);
 | 
			
		||||
              return TRUE;
 | 
			
		||||
            }
 | 
			
		||||
          break;
 | 
			
		||||
        case META_KEYBINDING_ACTION_NONE:
 | 
			
		||||
          {
 | 
			
		||||
            /*
 | 
			
		||||
             * If this is simply user pressing the Shift key, we do not want
 | 
			
		||||
             * to cancel the grab.
 | 
			
		||||
             */
 | 
			
		||||
            if (is_modifier (display, event->detail))
 | 
			
		||||
              return TRUE;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      /* Some unhandled key press */
 | 
			
		||||
      invoke_handler_by_name (display, screen, "tab-popup-cancel", NULL, event);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (event->evtype == XI_KeyRelease &&
 | 
			
		||||
      end_keyboard_grab (display, event->detail))
 | 
			
		||||
    {
 | 
			
		||||
      /* We're done, move to the new window. */
 | 
			
		||||
      MetaWindow *target_window;
 | 
			
		||||
 | 
			
		||||
      target_window = meta_screen_tab_popup_get_selected (screen);
 | 
			
		||||
 | 
			
		||||
      meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
                  "Ending tab operation, primary modifier released\n");
 | 
			
		||||
 | 
			
		||||
      if (target_window)
 | 
			
		||||
        {
 | 
			
		||||
          target_window->tab_unminimized = FALSE;
 | 
			
		||||
 | 
			
		||||
          meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
                      "Activating target window\n");
 | 
			
		||||
 | 
			
		||||
          meta_topic (META_DEBUG_FOCUS, "Activating %s due to tab popup "
 | 
			
		||||
                      "selection and turning mouse_mode off\n",
 | 
			
		||||
                      target_window->desc);
 | 
			
		||||
          display->mouse_mode = FALSE;
 | 
			
		||||
          meta_window_activate (target_window, event->time);
 | 
			
		||||
 | 
			
		||||
          meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
                      "Ending grab early so we can focus the target window\n");
 | 
			
		||||
          meta_display_end_grab_op (display, event->time);
 | 
			
		||||
 | 
			
		||||
          return TRUE; /* we already ended the grab */
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      return FALSE; /* end grab */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* don't care about other releases, but eat them, don't end grab */
 | 
			
		||||
  if (event->evtype == XI_KeyRelease)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
  /* don't end grab on modifier key presses */
 | 
			
		||||
  if (is_modifier (display, event->detail))
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
  prev_window = meta_screen_tab_popup_get_selected (screen);
 | 
			
		||||
 | 
			
		||||
  /* Cancel when alt-Escape is pressed during using alt-Tab, and vice
 | 
			
		||||
   * versa.
 | 
			
		||||
   */
 | 
			
		||||
  switch (action)
 | 
			
		||||
    {
 | 
			
		||||
    case META_KEYBINDING_ACTION_CYCLE_PANELS:
 | 
			
		||||
    case META_KEYBINDING_ACTION_CYCLE_WINDOWS:
 | 
			
		||||
    case META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD:
 | 
			
		||||
    case META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD:
 | 
			
		||||
      /* CYCLE_* are traditionally Escape-based actions,
 | 
			
		||||
       * and should cancel traditionally Tab-based ones.
 | 
			
		||||
       */
 | 
			
		||||
      switch (display->grab_op)
 | 
			
		||||
        {
 | 
			
		||||
        case META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL:
 | 
			
		||||
        case META_GRAB_OP_KEYBOARD_ESCAPING_DOCK:
 | 
			
		||||
          /* carry on */
 | 
			
		||||
          break;
 | 
			
		||||
        default:
 | 
			
		||||
          return FALSE;
 | 
			
		||||
        }
 | 
			
		||||
      break;
 | 
			
		||||
    case META_KEYBINDING_ACTION_SWITCH_PANELS:
 | 
			
		||||
    case META_KEYBINDING_ACTION_SWITCH_WINDOWS:
 | 
			
		||||
    case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS:
 | 
			
		||||
    case META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD:
 | 
			
		||||
    case META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD:
 | 
			
		||||
    case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD:
 | 
			
		||||
      /* SWITCH_* are traditionally Tab-based actions,
 | 
			
		||||
       * and should cancel traditionally Escape-based ones.
 | 
			
		||||
       */
 | 
			
		||||
      switch (display->grab_op)
 | 
			
		||||
        {
 | 
			
		||||
        case META_GRAB_OP_KEYBOARD_TABBING_NORMAL:
 | 
			
		||||
        case META_GRAB_OP_KEYBOARD_TABBING_DOCK:
 | 
			
		||||
          /* carry on */
 | 
			
		||||
          break;
 | 
			
		||||
        default:
 | 
			
		||||
          /* Also, we must re-lower and re-minimize whatever window
 | 
			
		||||
           * we'd previously raised and unminimized.
 | 
			
		||||
           */
 | 
			
		||||
          meta_stack_set_positions (screen->stack,
 | 
			
		||||
                                    screen->display->grab_old_window_stacking);
 | 
			
		||||
          if (prev_window && prev_window->tab_unminimized)
 | 
			
		||||
            {
 | 
			
		||||
              meta_window_minimize (prev_window);
 | 
			
		||||
              prev_window->tab_unminimized = FALSE;
 | 
			
		||||
            }
 | 
			
		||||
          return FALSE;
 | 
			
		||||
        }
 | 
			
		||||
      break;
 | 
			
		||||
    case META_KEYBINDING_ACTION_CYCLE_GROUP:
 | 
			
		||||
    case META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD:
 | 
			
		||||
    case META_KEYBINDING_ACTION_SWITCH_GROUP:
 | 
			
		||||
    case META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD:
 | 
			
		||||
      switch (display->grab_op)
 | 
			
		||||
        {
 | 
			
		||||
        case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP:
 | 
			
		||||
        case META_GRAB_OP_KEYBOARD_TABBING_GROUP:
 | 
			
		||||
          /* carry on */
 | 
			
		||||
          break;
 | 
			
		||||
        default:
 | 
			
		||||
          return FALSE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* !! TO HERE !!
 | 
			
		||||
   * alt-f6 during alt-{Tab,Escape} does not end the grab
 | 
			
		||||
   * but does change the grab op (and redraws the window,
 | 
			
		||||
   * of course).
 | 
			
		||||
   * See _{SWITCH,CYCLE}_GROUP.@@@
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  popup_not_showing = FALSE;
 | 
			
		||||
  key_used = FALSE;
 | 
			
		||||
  backward = FALSE;
 | 
			
		||||
 | 
			
		||||
  switch (action)
 | 
			
		||||
    {
 | 
			
		||||
    case META_KEYBINDING_ACTION_CYCLE_PANELS:
 | 
			
		||||
    case META_KEYBINDING_ACTION_CYCLE_WINDOWS:
 | 
			
		||||
    case META_KEYBINDING_ACTION_CYCLE_GROUP:
 | 
			
		||||
      popup_not_showing = TRUE;
 | 
			
		||||
      key_used = TRUE;
 | 
			
		||||
      break;
 | 
			
		||||
    case META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD:
 | 
			
		||||
    case META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD:
 | 
			
		||||
    case META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD:
 | 
			
		||||
      popup_not_showing = TRUE;
 | 
			
		||||
      key_used = TRUE;
 | 
			
		||||
      backward = TRUE;
 | 
			
		||||
      break;
 | 
			
		||||
    case META_KEYBINDING_ACTION_SWITCH_PANELS:
 | 
			
		||||
    case META_KEYBINDING_ACTION_SWITCH_WINDOWS:
 | 
			
		||||
    case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS:
 | 
			
		||||
    case META_KEYBINDING_ACTION_SWITCH_GROUP:
 | 
			
		||||
      key_used = TRUE;
 | 
			
		||||
      break;
 | 
			
		||||
    case META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD:
 | 
			
		||||
    case META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD:
 | 
			
		||||
    case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD:
 | 
			
		||||
    case META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD:
 | 
			
		||||
      key_used = TRUE;
 | 
			
		||||
      backward = TRUE;
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (key_used)
 | 
			
		||||
    {
 | 
			
		||||
      meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
                  "Key pressed, moving tab focus in popup\n");
 | 
			
		||||
 | 
			
		||||
      if (event->mods.effective & ShiftMask)
 | 
			
		||||
        backward = !backward;
 | 
			
		||||
 | 
			
		||||
      if (backward)
 | 
			
		||||
        meta_screen_tab_popup_backward (screen);
 | 
			
		||||
      else
 | 
			
		||||
        meta_screen_tab_popup_forward (screen);
 | 
			
		||||
 | 
			
		||||
      if (popup_not_showing)
 | 
			
		||||
        {
 | 
			
		||||
          /* We can't actually change window focus, due to the grab.
 | 
			
		||||
           * but raise the window.
 | 
			
		||||
           */
 | 
			
		||||
          MetaWindow *target_window;
 | 
			
		||||
 | 
			
		||||
          meta_stack_set_positions (screen->stack,
 | 
			
		||||
                                    display->grab_old_window_stacking);
 | 
			
		||||
 | 
			
		||||
          target_window = meta_screen_tab_popup_get_selected (screen);
 | 
			
		||||
 | 
			
		||||
          if (prev_window && prev_window->tab_unminimized)
 | 
			
		||||
            {
 | 
			
		||||
              prev_window->tab_unminimized = FALSE;
 | 
			
		||||
              meta_window_minimize (prev_window);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          if (target_window)
 | 
			
		||||
            {
 | 
			
		||||
              meta_window_raise (target_window);
 | 
			
		||||
              target_window->tab_unminimized = target_window->minimized;
 | 
			
		||||
              meta_window_unminimize (target_window);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      /* end grab */
 | 
			
		||||
      meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
                  "Ending tabbing/cycling, uninteresting key pressed\n");
 | 
			
		||||
 | 
			
		||||
      meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
                  "Syncing to old stack positions.\n");
 | 
			
		||||
      meta_stack_set_positions (screen->stack,
 | 
			
		||||
                                screen->display->grab_old_window_stacking);
 | 
			
		||||
 | 
			
		||||
      if (prev_window && prev_window->tab_unminimized)
 | 
			
		||||
        {
 | 
			
		||||
          meta_window_minimize (prev_window);
 | 
			
		||||
          prev_window->tab_unminimized = FALSE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return key_used;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_switch_to_workspace (MetaDisplay    *display,
 | 
			
		||||
                            MetaScreen     *screen,
 | 
			
		||||
@@ -3313,120 +2866,6 @@ handle_move_to_center  (MetaDisplay    *display,
 | 
			
		||||
                           window->rect.height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
process_workspace_switch_grab (MetaDisplay   *display,
 | 
			
		||||
                               MetaScreen    *screen,
 | 
			
		||||
                               XIDeviceEvent *event,
 | 
			
		||||
                               KeySym         keysym)
 | 
			
		||||
{
 | 
			
		||||
  MetaWorkspace *workspace;
 | 
			
		||||
 | 
			
		||||
  if (screen != display->grab_screen || !screen->ws_popup)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (event->evtype == XI_KeyRelease &&
 | 
			
		||||
      end_keyboard_grab (display, event->detail))
 | 
			
		||||
    {
 | 
			
		||||
      /* We're done, move to the new workspace. */
 | 
			
		||||
      MetaWorkspace *target_workspace;
 | 
			
		||||
 | 
			
		||||
      target_workspace = meta_screen_workspace_popup_get_selected (screen);
 | 
			
		||||
 | 
			
		||||
      meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
                  "Ending workspace tab operation, primary modifier released\n");
 | 
			
		||||
 | 
			
		||||
      if (target_workspace == screen->active_workspace)
 | 
			
		||||
        {
 | 
			
		||||
          meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
                      "Ending grab so we can focus on the target workspace\n");
 | 
			
		||||
          meta_display_end_grab_op (display, event->time);
 | 
			
		||||
 | 
			
		||||
          meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
                      "Focusing default window on target workspace\n");
 | 
			
		||||
 | 
			
		||||
          meta_workspace_focus_default_window (target_workspace,
 | 
			
		||||
                                               NULL,
 | 
			
		||||
                                               event->time);
 | 
			
		||||
 | 
			
		||||
          return TRUE; /* we already ended the grab */
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      /* Workspace switching should have already occurred on KeyPress */
 | 
			
		||||
      meta_warning ("target_workspace != active_workspace.  Some other event must have occurred.\n");
 | 
			
		||||
 | 
			
		||||
      return FALSE; /* end grab */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* don't care about other releases, but eat them, don't end grab */
 | 
			
		||||
  if (event->evtype == XI_KeyRelease)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
  /* don't end grab on modifier key presses */
 | 
			
		||||
  if (is_modifier (display, event->detail))
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
  /* select the next workspace in the popup */
 | 
			
		||||
  workspace = meta_screen_workspace_popup_get_selected (screen);
 | 
			
		||||
 | 
			
		||||
  if (workspace)
 | 
			
		||||
    {
 | 
			
		||||
      MetaWorkspace *target_workspace;
 | 
			
		||||
      MetaKeyBindingAction action;
 | 
			
		||||
 | 
			
		||||
      action = meta_display_get_keybinding_action (display,
 | 
			
		||||
                                                   event->detail,
 | 
			
		||||
                                                   display->grab_mask);
 | 
			
		||||
 | 
			
		||||
      switch (action)
 | 
			
		||||
        {
 | 
			
		||||
        case META_KEYBINDING_ACTION_WORKSPACE_UP:
 | 
			
		||||
          target_workspace = meta_workspace_get_neighbor (workspace,
 | 
			
		||||
                                                          META_MOTION_UP);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case META_KEYBINDING_ACTION_WORKSPACE_DOWN:
 | 
			
		||||
          target_workspace = meta_workspace_get_neighbor (workspace,
 | 
			
		||||
                                                          META_MOTION_DOWN);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case META_KEYBINDING_ACTION_WORKSPACE_LEFT:
 | 
			
		||||
          target_workspace = meta_workspace_get_neighbor (workspace,
 | 
			
		||||
                                                          META_MOTION_LEFT);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case META_KEYBINDING_ACTION_WORKSPACE_RIGHT:
 | 
			
		||||
          target_workspace = meta_workspace_get_neighbor (workspace,
 | 
			
		||||
                                                          META_MOTION_RIGHT);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
          target_workspace = NULL;
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (target_workspace)
 | 
			
		||||
        {
 | 
			
		||||
          meta_screen_workspace_popup_select (screen, target_workspace);
 | 
			
		||||
          meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
                      "Tab key pressed, moving tab focus in popup\n");
 | 
			
		||||
 | 
			
		||||
          meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
                      "Activating target workspace\n");
 | 
			
		||||
 | 
			
		||||
          meta_workspace_activate (target_workspace, event->time);
 | 
			
		||||
 | 
			
		||||
          return TRUE; /* we already ended the grab */
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* end grab */
 | 
			
		||||
  meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
              "Ending workspace tabbing & focusing default window; uninteresting key pressed\n");
 | 
			
		||||
  workspace = meta_screen_workspace_popup_get_selected (screen);
 | 
			
		||||
  meta_workspace_focus_default_window (workspace, NULL, event->time);
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_show_desktop (MetaDisplay    *display,
 | 
			
		||||
                     MetaScreen     *screen,
 | 
			
		||||
@@ -3523,60 +2962,19 @@ handle_activate_window_menu (MetaDisplay    *display,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaGrabOp
 | 
			
		||||
tab_op_from_tab_type (MetaTabList type)
 | 
			
		||||
{
 | 
			
		||||
  switch (type)
 | 
			
		||||
    {
 | 
			
		||||
    case META_TAB_LIST_NORMAL:
 | 
			
		||||
      return META_GRAB_OP_KEYBOARD_TABBING_NORMAL;
 | 
			
		||||
    case META_TAB_LIST_DOCKS:
 | 
			
		||||
      return META_GRAB_OP_KEYBOARD_TABBING_DOCK;
 | 
			
		||||
    case META_TAB_LIST_GROUP:
 | 
			
		||||
      return META_GRAB_OP_KEYBOARD_TABBING_GROUP;
 | 
			
		||||
    case META_TAB_LIST_NORMAL_ALL:
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_assert_not_reached ();
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaGrabOp
 | 
			
		||||
cycle_op_from_tab_type (MetaTabList type)
 | 
			
		||||
{
 | 
			
		||||
  switch (type)
 | 
			
		||||
    {
 | 
			
		||||
    case META_TAB_LIST_NORMAL:
 | 
			
		||||
      return META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL;
 | 
			
		||||
    case META_TAB_LIST_DOCKS:
 | 
			
		||||
      return META_GRAB_OP_KEYBOARD_ESCAPING_DOCK;
 | 
			
		||||
    case META_TAB_LIST_GROUP:
 | 
			
		||||
      return META_GRAB_OP_KEYBOARD_ESCAPING_GROUP;
 | 
			
		||||
    case META_TAB_LIST_NORMAL_ALL:
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_assert_not_reached ();
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
do_choose_window (MetaDisplay    *display,
 | 
			
		||||
                  MetaScreen     *screen,
 | 
			
		||||
                  MetaWindow     *event_window,
 | 
			
		||||
                  XIDeviceEvent  *event,
 | 
			
		||||
                  MetaKeyBinding *binding,
 | 
			
		||||
                  gboolean        backward,
 | 
			
		||||
                  gboolean        show_popup)
 | 
			
		||||
                  gboolean        backward)
 | 
			
		||||
{
 | 
			
		||||
  MetaTabList type = binding->handler->data;
 | 
			
		||||
  MetaWindow *initial_selection;
 | 
			
		||||
 | 
			
		||||
  meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
              "Tab list = %u show_popup = %d\n", type, show_popup);
 | 
			
		||||
              "Tab list = %u\n", type);
 | 
			
		||||
 | 
			
		||||
  /* reverse direction if shift is down */
 | 
			
		||||
  if (event->mods.effective & ShiftMask)
 | 
			
		||||
@@ -3589,82 +2987,7 @@ do_choose_window (MetaDisplay    *display,
 | 
			
		||||
                                                 NULL,
 | 
			
		||||
                                                 backward);
 | 
			
		||||
 | 
			
		||||
  /* Note that focus_window may not be in the tab chain, but it's OK */
 | 
			
		||||
  if (initial_selection == NULL)
 | 
			
		||||
    initial_selection = meta_display_get_tab_current (display,
 | 
			
		||||
                                                      type, screen,
 | 
			
		||||
                                                      screen->active_workspace);
 | 
			
		||||
 | 
			
		||||
  meta_topic (META_DEBUG_KEYBINDINGS,
 | 
			
		||||
              "Initially selecting window %s\n",
 | 
			
		||||
              initial_selection ? initial_selection->desc : "(none)");
 | 
			
		||||
 | 
			
		||||
  if (initial_selection == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (binding->mask == 0)
 | 
			
		||||
    {
 | 
			
		||||
      /* If no modifiers, we can't do the "hold down modifier to keep
 | 
			
		||||
       * moving" thing, so we just instaswitch by one window.
 | 
			
		||||
       */
 | 
			
		||||
      meta_topic (META_DEBUG_FOCUS,
 | 
			
		||||
                  "Activating %s and turning off mouse_mode due to "
 | 
			
		||||
                  "switch/cycle windows with no modifiers\n",
 | 
			
		||||
                  initial_selection->desc);
 | 
			
		||||
      display->mouse_mode = FALSE;
 | 
			
		||||
      meta_window_activate (initial_selection, event->time);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (meta_prefs_get_no_tab_popup ())
 | 
			
		||||
    {
 | 
			
		||||
      /* FIXME? Shouldn't this be merged with the previous case? */
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (!meta_display_begin_grab_op (display,
 | 
			
		||||
                                   screen,
 | 
			
		||||
                                   NULL,
 | 
			
		||||
                                   show_popup ?
 | 
			
		||||
                                   tab_op_from_tab_type (type) :
 | 
			
		||||
                                   cycle_op_from_tab_type (type),
 | 
			
		||||
                                   FALSE,
 | 
			
		||||
                                   FALSE,
 | 
			
		||||
                                   0,
 | 
			
		||||
                                   binding->mask,
 | 
			
		||||
                                   event->time,
 | 
			
		||||
                                   0, 0))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (!primary_modifier_still_pressed (display, binding->mask))
 | 
			
		||||
    {
 | 
			
		||||
      /* This handles a race where modifier might be released before
 | 
			
		||||
       * we establish the grab. must end grab prior to trying to focus
 | 
			
		||||
       * a window.
 | 
			
		||||
       */
 | 
			
		||||
      meta_topic (META_DEBUG_FOCUS,
 | 
			
		||||
                  "Ending grab, activating %s, and turning off "
 | 
			
		||||
                  "mouse_mode due to switch/cycle windows where "
 | 
			
		||||
                  "modifier was released prior to grab\n",
 | 
			
		||||
                  initial_selection->desc);
 | 
			
		||||
      meta_display_end_grab_op (display, event->time);
 | 
			
		||||
      display->mouse_mode = FALSE;
 | 
			
		||||
      meta_window_activate (initial_selection, event->time);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_screen_tab_popup_create (screen, type,
 | 
			
		||||
                                show_popup ? META_TAB_SHOW_ICON :
 | 
			
		||||
                                META_TAB_SHOW_INSTANTLY,
 | 
			
		||||
                                initial_selection);
 | 
			
		||||
 | 
			
		||||
  if (!show_popup)
 | 
			
		||||
    {
 | 
			
		||||
      meta_window_raise (initial_selection);
 | 
			
		||||
      initial_selection->tab_unminimized =
 | 
			
		||||
        initial_selection->minimized;
 | 
			
		||||
      meta_window_unminimize (initial_selection);
 | 
			
		||||
    }
 | 
			
		||||
  meta_window_activate (initial_selection, event->time);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -3677,8 +3000,7 @@ handle_switch (MetaDisplay    *display,
 | 
			
		||||
{
 | 
			
		||||
  gint backwards = (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0;
 | 
			
		||||
 | 
			
		||||
  do_choose_window (display, screen, event_window, event, binding,
 | 
			
		||||
                    backwards, TRUE);
 | 
			
		||||
  do_choose_window (display, screen, event_window, event, binding, backwards);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -3691,30 +3013,7 @@ handle_cycle (MetaDisplay    *display,
 | 
			
		||||
{
 | 
			
		||||
  gint backwards = (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0;
 | 
			
		||||
 | 
			
		||||
  do_choose_window (display, screen, event_window, event, binding,
 | 
			
		||||
                    backwards, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_tab_popup_select (MetaDisplay    *display,
 | 
			
		||||
                         MetaScreen     *screen,
 | 
			
		||||
                         MetaWindow     *window,
 | 
			
		||||
                         XIDeviceEvent  *event,
 | 
			
		||||
                         MetaKeyBinding *binding,
 | 
			
		||||
                         gpointer        dummy)
 | 
			
		||||
{
 | 
			
		||||
  /* Stub for custom handlers; no default implementation */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_tab_popup_cancel (MetaDisplay    *display,
 | 
			
		||||
                         MetaScreen     *screen,
 | 
			
		||||
                         MetaWindow     *window,
 | 
			
		||||
                         XIDeviceEvent  *event,
 | 
			
		||||
                         MetaKeyBinding *binding,
 | 
			
		||||
                         gpointer        dummy)
 | 
			
		||||
{
 | 
			
		||||
  /* Stub for custom handlers; no default implementation */
 | 
			
		||||
  do_choose_window (display, screen, event_window, event, binding, backwards);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -4112,9 +3411,6 @@ handle_workspace_switch  (MetaDisplay    *display,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_workspace_activate (next, event->time);
 | 
			
		||||
 | 
			
		||||
  if (grabbed_before_release && !meta_prefs_get_no_tab_popup ())
 | 
			
		||||
    meta_screen_workspace_popup_create (screen, next);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -4380,26 +3676,6 @@ init_builtin_key_bindings (MetaDisplay *display)
 | 
			
		||||
                          META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD,
 | 
			
		||||
                          handle_cycle, META_TAB_LIST_DOCKS);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /* These two are special pseudo-bindings that are provided for allowing
 | 
			
		||||
   * custom handlers, but will never be bound to a key. While a tab
 | 
			
		||||
   * grab is in effect, they are invoked for releasing the primary modifier
 | 
			
		||||
   * or pressing some unbound key, respectively.
 | 
			
		||||
   */
 | 
			
		||||
  add_builtin_keybinding (display,
 | 
			
		||||
                          "tab-popup-select",
 | 
			
		||||
                          mutter_keybindings,
 | 
			
		||||
                          META_KEY_BINDING_NONE,
 | 
			
		||||
                          META_KEYBINDING_ACTION_TAB_POPUP_SELECT,
 | 
			
		||||
                          handle_tab_popup_select, 0);
 | 
			
		||||
 | 
			
		||||
  add_builtin_keybinding (display,
 | 
			
		||||
                          "tab-popup-cancel",
 | 
			
		||||
                          mutter_keybindings,
 | 
			
		||||
                          META_KEY_BINDING_NONE,
 | 
			
		||||
                          META_KEYBINDING_ACTION_TAB_POPUP_CANCEL,
 | 
			
		||||
                          handle_tab_popup_cancel, 0);
 | 
			
		||||
 | 
			
		||||
  /***********************************/
 | 
			
		||||
 | 
			
		||||
  add_builtin_keybinding (display,
 | 
			
		||||
 
 | 
			
		||||
@@ -523,42 +523,6 @@ meta_run (void)
 | 
			
		||||
 | 
			
		||||
  if (g_getenv ("MUTTER_G_FATAL_WARNINGS") != NULL)
 | 
			
		||||
    g_log_set_always_fatal (G_LOG_LEVEL_MASK);
 | 
			
		||||
  
 | 
			
		||||
  meta_ui_set_current_theme (meta_prefs_get_theme ());
 | 
			
		||||
 | 
			
		||||
  /* Try to find some theme that'll work if the theme preference
 | 
			
		||||
   * doesn't exist.  First try Simple (the default theme) then just
 | 
			
		||||
   * try anything in the themes directory.
 | 
			
		||||
   */
 | 
			
		||||
  if (!meta_ui_have_a_theme ())
 | 
			
		||||
    meta_ui_set_current_theme ("Simple");
 | 
			
		||||
  
 | 
			
		||||
  if (!meta_ui_have_a_theme ())
 | 
			
		||||
    {
 | 
			
		||||
      const char *dir_entry = NULL;
 | 
			
		||||
      GError *err = NULL;
 | 
			
		||||
      GDir   *themes_dir = NULL;
 | 
			
		||||
      
 | 
			
		||||
      if (!(themes_dir = g_dir_open (MUTTER_DATADIR"/themes", 0, &err)))
 | 
			
		||||
        {
 | 
			
		||||
          meta_fatal (_("Failed to scan themes directory: %s\n"), err->message);
 | 
			
		||||
          g_error_free (err);
 | 
			
		||||
        } 
 | 
			
		||||
      else 
 | 
			
		||||
        {
 | 
			
		||||
          while (((dir_entry = g_dir_read_name (themes_dir)) != NULL) && 
 | 
			
		||||
                 (!meta_ui_have_a_theme ()))
 | 
			
		||||
            {
 | 
			
		||||
              meta_ui_set_current_theme (dir_entry);
 | 
			
		||||
            }
 | 
			
		||||
          
 | 
			
		||||
          g_dir_close (themes_dir);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  if (!meta_ui_have_a_theme ())
 | 
			
		||||
    meta_fatal (_("Could not find a theme! Be sure %s exists and contains the usual themes.\n"),
 | 
			
		||||
                MUTTER_DATADIR"/themes");
 | 
			
		||||
 | 
			
		||||
  if (!meta_display_open ())
 | 
			
		||||
    meta_exit (META_EXIT_ERROR);
 | 
			
		||||
@@ -606,12 +570,6 @@ prefs_changed_callback (MetaPreference pref,
 | 
			
		||||
{
 | 
			
		||||
  switch (pref)
 | 
			
		||||
    {
 | 
			
		||||
    case META_PREF_THEME:
 | 
			
		||||
    case META_PREF_DRAGGABLE_BORDER_WIDTH:
 | 
			
		||||
      meta_ui_set_current_theme (meta_prefs_get_theme ());
 | 
			
		||||
      meta_display_retheme_all ();
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case META_PREF_CURSOR_THEME:
 | 
			
		||||
    case META_PREF_CURSOR_SIZE:
 | 
			
		||||
      meta_display_set_cursor_theme (meta_prefs_get_cursor_theme (),
 | 
			
		||||
 
 | 
			
		||||
@@ -57,7 +57,6 @@
 | 
			
		||||
 | 
			
		||||
#define KEY_OVERLAY_KEY "overlay-key"
 | 
			
		||||
#define KEY_WORKSPACES_ONLY_ON_PRIMARY "workspaces-only-on-primary"
 | 
			
		||||
#define KEY_NO_TAB_POPUP "no-tab-popup"
 | 
			
		||||
 | 
			
		||||
/* These are the different schemas we are keeping
 | 
			
		||||
 * a GSettings instance for */
 | 
			
		||||
@@ -81,7 +80,6 @@ static GDesktopFocusMode focus_mode = G_DESKTOP_FOCUS_MODE_CLICK;
 | 
			
		||||
static GDesktopFocusNewWindows focus_new_windows = G_DESKTOP_FOCUS_NEW_WINDOWS_SMART;
 | 
			
		||||
static gboolean raise_on_click = TRUE;
 | 
			
		||||
static gboolean attach_modal_dialogs = FALSE;
 | 
			
		||||
static char* current_theme = NULL;
 | 
			
		||||
static int num_workspaces = 4;
 | 
			
		||||
static GDesktopTitlebarAction action_double_click_titlebar = G_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE;
 | 
			
		||||
static GDesktopTitlebarAction action_middle_click_titlebar = G_DESKTOP_TITLEBAR_ACTION_LOWER;
 | 
			
		||||
@@ -112,8 +110,6 @@ static char **workspace_names = NULL;
 | 
			
		||||
 | 
			
		||||
static gboolean workspaces_only_on_primary = FALSE;
 | 
			
		||||
 | 
			
		||||
static gboolean no_tab_popup = FALSE;
 | 
			
		||||
 | 
			
		||||
static char *iso_next_group_option = NULL;
 | 
			
		||||
 | 
			
		||||
static void handle_preference_update_enum (GSettings *settings,
 | 
			
		||||
@@ -135,7 +131,6 @@ static void queue_changed (MetaPreference  pref);
 | 
			
		||||
static void maybe_give_disable_workarounds_warning (void);
 | 
			
		||||
 | 
			
		||||
static gboolean titlebar_handler (GVariant*, gpointer*, gpointer);
 | 
			
		||||
static gboolean theme_name_handler (GVariant*, gpointer*, gpointer);
 | 
			
		||||
static gboolean mouse_button_mods_handler (GVariant*, gpointer*, gpointer);
 | 
			
		||||
static gboolean button_layout_handler (GVariant*, gpointer*, gpointer);
 | 
			
		||||
static gboolean overlay_key_handler (GVariant*, gpointer*, gpointer);
 | 
			
		||||
@@ -365,13 +360,6 @@ static MetaBoolPreference preferences_bool[] =
 | 
			
		||||
      },
 | 
			
		||||
      &workspaces_only_on_primary,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      { KEY_NO_TAB_POPUP,
 | 
			
		||||
        SCHEMA_MUTTER,
 | 
			
		||||
        META_PREF_NO_TAB_POPUP,
 | 
			
		||||
      },
 | 
			
		||||
      &no_tab_popup,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      { "auto-maximize",
 | 
			
		||||
        SCHEMA_MUTTER,
 | 
			
		||||
@@ -392,14 +380,6 @@ static MetaStringPreference preferences_string[] =
 | 
			
		||||
      mouse_button_mods_handler,
 | 
			
		||||
      NULL,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      { "theme",
 | 
			
		||||
        SCHEMA_GENERAL,
 | 
			
		||||
        META_PREF_THEME,
 | 
			
		||||
      },
 | 
			
		||||
      theme_name_handler,
 | 
			
		||||
      NULL,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      { KEY_TITLEBAR_FONT,
 | 
			
		||||
        SCHEMA_GENERAL,
 | 
			
		||||
@@ -1235,12 +1215,6 @@ meta_prefs_get_raise_on_click (void)
 | 
			
		||||
  return raise_on_click || focus_mode == G_DESKTOP_FOCUS_MODE_CLICK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char*
 | 
			
		||||
meta_prefs_get_theme (void)
 | 
			
		||||
{
 | 
			
		||||
  return current_theme;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char*
 | 
			
		||||
meta_prefs_get_cursor_theme (void)
 | 
			
		||||
{
 | 
			
		||||
@@ -1297,31 +1271,6 @@ titlebar_handler (GVariant *value,
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
theme_name_handler (GVariant *value,
 | 
			
		||||
                    gpointer *result,
 | 
			
		||||
                    gpointer  data)
 | 
			
		||||
{
 | 
			
		||||
  const gchar *string_value;
 | 
			
		||||
 | 
			
		||||
  *result = NULL; /* ignored */
 | 
			
		||||
  string_value = g_variant_get_string (value, NULL);
 | 
			
		||||
 | 
			
		||||
  if (!string_value || !*string_value)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (g_strcmp0 (current_theme, string_value) != 0)
 | 
			
		||||
    {
 | 
			
		||||
      if (current_theme)
 | 
			
		||||
        g_free (current_theme);
 | 
			
		||||
 | 
			
		||||
      current_theme = g_strdup (string_value);
 | 
			
		||||
      queue_changed (META_PREF_THEME);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
mouse_button_mods_handler (GVariant *value,
 | 
			
		||||
                           gpointer *result,
 | 
			
		||||
@@ -1741,9 +1690,6 @@ meta_preference_to_string (MetaPreference pref)
 | 
			
		||||
    case META_PREF_RAISE_ON_CLICK:
 | 
			
		||||
      return "RAISE_ON_CLICK";
 | 
			
		||||
      
 | 
			
		||||
    case META_PREF_THEME:
 | 
			
		||||
      return "THEME";
 | 
			
		||||
 | 
			
		||||
    case META_PREF_TITLEBAR_FONT:
 | 
			
		||||
      return "TITLEBAR_FONT";
 | 
			
		||||
 | 
			
		||||
@@ -1813,9 +1759,6 @@ meta_preference_to_string (MetaPreference pref)
 | 
			
		||||
    case META_PREF_WORKSPACES_ONLY_ON_PRIMARY:
 | 
			
		||||
      return "WORKSPACES_ONLY_ON_PRIMARY";
 | 
			
		||||
 | 
			
		||||
    case META_PREF_NO_TAB_POPUP:
 | 
			
		||||
      return "NO_TAB_POPUP";
 | 
			
		||||
 | 
			
		||||
    case META_PREF_DRAGGABLE_BORDER_WIDTH:
 | 
			
		||||
      return "DRAGGABLE_BORDER_WIDTH";
 | 
			
		||||
 | 
			
		||||
@@ -2320,25 +2263,6 @@ meta_prefs_get_workspaces_only_on_primary (void)
 | 
			
		||||
  return workspaces_only_on_primary;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_prefs_get_no_tab_popup (void)
 | 
			
		||||
{
 | 
			
		||||
  return no_tab_popup;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_prefs_set_no_tab_popup (gboolean whether)
 | 
			
		||||
{
 | 
			
		||||
  MetaBasePreference *pref;
 | 
			
		||||
 | 
			
		||||
  if (find_pref (preferences_bool, sizeof(MetaBoolPreference),
 | 
			
		||||
                 KEY_NO_TAB_POPUP, &pref))
 | 
			
		||||
    {
 | 
			
		||||
      g_settings_set_boolean (SETTINGS (pref->schema), KEY_NO_TAB_POPUP, whether);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
meta_prefs_get_draggable_border_width (void)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -64,7 +64,6 @@ struct _MetaScreen
 | 
			
		||||
  Visual *default_xvisual;
 | 
			
		||||
  MetaRectangle rect;  /* Size of screen; rect.x & rect.y are always 0 */
 | 
			
		||||
  MetaUI *ui;
 | 
			
		||||
  MetaTabPopup *tab_popup, *ws_popup;
 | 
			
		||||
 | 
			
		||||
  guint tile_preview_timeout_id;
 | 
			
		||||
 | 
			
		||||
@@ -150,26 +149,6 @@ void          meta_screen_foreach_window      (MetaScreen                 *scree
 | 
			
		||||
 | 
			
		||||
void          meta_screen_update_cursor       (MetaScreen                 *screen);
 | 
			
		||||
 | 
			
		||||
void          meta_screen_tab_popup_create       (MetaScreen              *screen,
 | 
			
		||||
                                                  MetaTabList              list_type,
 | 
			
		||||
                                                  MetaTabShowType          show_type,
 | 
			
		||||
                                                  MetaWindow              *initial_window);
 | 
			
		||||
void          meta_screen_tab_popup_forward      (MetaScreen              *screen);
 | 
			
		||||
void          meta_screen_tab_popup_backward     (MetaScreen              *screen);
 | 
			
		||||
MetaWindow*   meta_screen_tab_popup_get_selected (MetaScreen              *screen);
 | 
			
		||||
void          meta_screen_tab_popup_destroy      (MetaScreen              *screen);
 | 
			
		||||
 | 
			
		||||
void          meta_screen_workspace_popup_create       (MetaScreen    *screen,
 | 
			
		||||
                                                        MetaWorkspace *initial_selection);
 | 
			
		||||
void          meta_screen_workspace_popup_select       (MetaScreen    *screen,
 | 
			
		||||
                                                        MetaWorkspace *workspace);
 | 
			
		||||
MetaWorkspace*meta_screen_workspace_popup_get_selected (MetaScreen    *screen);
 | 
			
		||||
void          meta_screen_workspace_popup_destroy      (MetaScreen    *screen);
 | 
			
		||||
 | 
			
		||||
void          meta_screen_update_tile_preview          (MetaScreen    *screen,
 | 
			
		||||
                                                        gboolean       delay);
 | 
			
		||||
void          meta_screen_hide_tile_preview            (MetaScreen    *screen);
 | 
			
		||||
 | 
			
		||||
MetaWindow*   meta_screen_get_mouse_window     (MetaScreen                 *screen,
 | 
			
		||||
                                                MetaWindow                 *not_this_one);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -760,9 +760,6 @@ meta_screen_new (MetaDisplay *display,
 | 
			
		||||
  screen->ui = meta_ui_new (screen->display->xdisplay,
 | 
			
		||||
                            screen->xscreen);
 | 
			
		||||
 | 
			
		||||
  screen->tab_popup = NULL;
 | 
			
		||||
  screen->ws_popup = NULL;
 | 
			
		||||
 | 
			
		||||
  screen->tile_preview_timeout_id = 0;
 | 
			
		||||
 | 
			
		||||
  screen->stack = meta_stack_new (screen);
 | 
			
		||||
@@ -1425,253 +1422,6 @@ meta_screen_update_cursor (MetaScreen *screen)
 | 
			
		||||
                                       screen->current_cursor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_screen_tab_popup_create (MetaScreen      *screen,
 | 
			
		||||
                              MetaTabList      list_type,
 | 
			
		||||
                              MetaTabShowType  show_type,
 | 
			
		||||
                              MetaWindow      *initial_selection)
 | 
			
		||||
{
 | 
			
		||||
  MetaTabEntry *entries;
 | 
			
		||||
  GList *tab_list;
 | 
			
		||||
  GList *tmp;
 | 
			
		||||
  int len;
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  if (screen->tab_popup)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  tab_list = meta_display_get_tab_list (screen->display,
 | 
			
		||||
                                        list_type,
 | 
			
		||||
                                        screen,
 | 
			
		||||
                                        screen->active_workspace);
 | 
			
		||||
 | 
			
		||||
  len = g_list_length (tab_list);
 | 
			
		||||
 | 
			
		||||
  entries = g_new (MetaTabEntry, len + 1);
 | 
			
		||||
  entries[len].key = NULL;
 | 
			
		||||
  entries[len].title = NULL;
 | 
			
		||||
  entries[len].icon = NULL;
 | 
			
		||||
 | 
			
		||||
  i = 0;
 | 
			
		||||
  tmp = tab_list;
 | 
			
		||||
  while (i < len)
 | 
			
		||||
    {
 | 
			
		||||
      MetaWindow *window;
 | 
			
		||||
      MetaRectangle r;
 | 
			
		||||
 | 
			
		||||
      window = tmp->data;
 | 
			
		||||
 | 
			
		||||
      entries[i].key = (MetaTabEntryKey) window;
 | 
			
		||||
      entries[i].title = window->title;
 | 
			
		||||
      entries[i].icon = g_object_ref (window->icon);
 | 
			
		||||
      entries[i].blank = FALSE;
 | 
			
		||||
      entries[i].hidden = !meta_window_showing_on_its_workspace (window);
 | 
			
		||||
      entries[i].demands_attention = window->wm_state_demands_attention;
 | 
			
		||||
 | 
			
		||||
      if (show_type == META_TAB_SHOW_INSTANTLY ||
 | 
			
		||||
          !entries[i].hidden                   ||
 | 
			
		||||
          !meta_window_get_icon_geometry (window, &r))
 | 
			
		||||
        meta_window_get_frame_rect (window, &r);
 | 
			
		||||
 | 
			
		||||
      entries[i].rect = r;
 | 
			
		||||
 | 
			
		||||
      /* Find inside of highlight rectangle to be used when window is
 | 
			
		||||
       * outlined for tabbing.  This should be the size of the
 | 
			
		||||
       * east/west frame, and the size of the south frame, on those
 | 
			
		||||
       * sides.  On the top it should be the size of the south frame
 | 
			
		||||
       * edge.
 | 
			
		||||
       */
 | 
			
		||||
#define OUTLINE_WIDTH 5
 | 
			
		||||
      /* Top side */
 | 
			
		||||
      if (!entries[i].hidden &&
 | 
			
		||||
          window->frame && window->frame->bottom_height > 0 &&
 | 
			
		||||
          window->frame->child_y >= window->frame->bottom_height)
 | 
			
		||||
        entries[i].inner_rect.y = window->frame->bottom_height;
 | 
			
		||||
      else
 | 
			
		||||
        entries[i].inner_rect.y = OUTLINE_WIDTH;
 | 
			
		||||
 | 
			
		||||
      /* Bottom side */
 | 
			
		||||
      if (!entries[i].hidden &&
 | 
			
		||||
          window->frame && window->frame->bottom_height != 0)
 | 
			
		||||
        entries[i].inner_rect.height = r.height
 | 
			
		||||
          - entries[i].inner_rect.y - window->frame->bottom_height;
 | 
			
		||||
      else
 | 
			
		||||
        entries[i].inner_rect.height = r.height
 | 
			
		||||
          - entries[i].inner_rect.y - OUTLINE_WIDTH;
 | 
			
		||||
 | 
			
		||||
      /* Left side */
 | 
			
		||||
      if (!entries[i].hidden && window->frame && window->frame->child_x != 0)
 | 
			
		||||
        entries[i].inner_rect.x = window->frame->child_x;
 | 
			
		||||
      else
 | 
			
		||||
        entries[i].inner_rect.x = OUTLINE_WIDTH;
 | 
			
		||||
 | 
			
		||||
      /* Right side */
 | 
			
		||||
      if (!entries[i].hidden &&
 | 
			
		||||
          window->frame && window->frame->right_width != 0)
 | 
			
		||||
        entries[i].inner_rect.width = r.width
 | 
			
		||||
          - entries[i].inner_rect.x - window->frame->right_width;
 | 
			
		||||
      else
 | 
			
		||||
        entries[i].inner_rect.width = r.width
 | 
			
		||||
          - entries[i].inner_rect.x - OUTLINE_WIDTH;
 | 
			
		||||
 | 
			
		||||
      ++i;
 | 
			
		||||
      tmp = tmp->next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (!meta_prefs_get_no_tab_popup ())
 | 
			
		||||
    screen->tab_popup = meta_ui_tab_popup_new (entries,
 | 
			
		||||
                                               screen->number,
 | 
			
		||||
                                               len,
 | 
			
		||||
                                               5, /* FIXME */
 | 
			
		||||
                                               TRUE);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < len; i++)
 | 
			
		||||
    g_object_unref (entries[i].icon);
 | 
			
		||||
 | 
			
		||||
  g_free (entries);
 | 
			
		||||
 | 
			
		||||
  g_list_free (tab_list);
 | 
			
		||||
 | 
			
		||||
  meta_ui_tab_popup_select (screen->tab_popup,
 | 
			
		||||
                            (MetaTabEntryKey) initial_selection);
 | 
			
		||||
 | 
			
		||||
  if (show_type != META_TAB_SHOW_INSTANTLY)
 | 
			
		||||
    meta_ui_tab_popup_set_showing (screen->tab_popup, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_screen_tab_popup_forward (MetaScreen *screen)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (screen->tab_popup != NULL);
 | 
			
		||||
 | 
			
		||||
  meta_ui_tab_popup_forward (screen->tab_popup);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_screen_tab_popup_backward (MetaScreen *screen)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (screen->tab_popup != NULL);
 | 
			
		||||
 | 
			
		||||
  meta_ui_tab_popup_backward (screen->tab_popup);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaWindow *
 | 
			
		||||
meta_screen_tab_popup_get_selected (MetaScreen *screen)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (screen->tab_popup != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  return (MetaWindow *) meta_ui_tab_popup_get_selected (screen->tab_popup);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_screen_tab_popup_destroy (MetaScreen *screen)
 | 
			
		||||
{
 | 
			
		||||
  if (screen->tab_popup)
 | 
			
		||||
    {
 | 
			
		||||
      meta_ui_tab_popup_free (screen->tab_popup);
 | 
			
		||||
      screen->tab_popup = NULL;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_screen_workspace_popup_create (MetaScreen    *screen,
 | 
			
		||||
                                    MetaWorkspace *initial_selection)
 | 
			
		||||
{
 | 
			
		||||
  MetaTabEntry *entries;
 | 
			
		||||
  int len;
 | 
			
		||||
  int i;
 | 
			
		||||
  MetaWorkspaceLayout layout;
 | 
			
		||||
  int n_workspaces;
 | 
			
		||||
  int current_workspace;
 | 
			
		||||
 | 
			
		||||
  if (screen->ws_popup || meta_prefs_get_no_tab_popup ())
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  current_workspace = meta_workspace_index (screen->active_workspace);
 | 
			
		||||
  n_workspaces = meta_screen_get_n_workspaces (screen);
 | 
			
		||||
 | 
			
		||||
  meta_screen_calc_workspace_layout (screen, n_workspaces,
 | 
			
		||||
                                     current_workspace, &layout);
 | 
			
		||||
 | 
			
		||||
  len = layout.grid_area;
 | 
			
		||||
  
 | 
			
		||||
  entries = g_new (MetaTabEntry, len + 1);
 | 
			
		||||
  entries[len].key = NULL;
 | 
			
		||||
  entries[len].title = NULL;
 | 
			
		||||
  entries[len].icon = NULL;
 | 
			
		||||
 | 
			
		||||
  i = 0;
 | 
			
		||||
  while (i < len)
 | 
			
		||||
    {
 | 
			
		||||
      if (layout.grid[i] >= 0)
 | 
			
		||||
        {
 | 
			
		||||
          MetaWorkspace *workspace;
 | 
			
		||||
          
 | 
			
		||||
          workspace = meta_screen_get_workspace_by_index (screen,
 | 
			
		||||
                                                          layout.grid[i]);
 | 
			
		||||
          
 | 
			
		||||
          entries[i].key = (MetaTabEntryKey) workspace;
 | 
			
		||||
          entries[i].title = meta_workspace_get_name (workspace);
 | 
			
		||||
          entries[i].icon = NULL;
 | 
			
		||||
          entries[i].blank = FALSE;
 | 
			
		||||
          
 | 
			
		||||
          g_assert (entries[i].title != NULL);
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          entries[i].key = NULL;
 | 
			
		||||
          entries[i].title = NULL;
 | 
			
		||||
          entries[i].icon = NULL;
 | 
			
		||||
          entries[i].blank = TRUE;
 | 
			
		||||
        }
 | 
			
		||||
      entries[i].hidden = FALSE;
 | 
			
		||||
      entries[i].demands_attention = FALSE;
 | 
			
		||||
 | 
			
		||||
      ++i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  screen->ws_popup = meta_ui_tab_popup_new (entries,
 | 
			
		||||
                                            screen->number,
 | 
			
		||||
                                            len,
 | 
			
		||||
                                            layout.cols,
 | 
			
		||||
                                            FALSE);
 | 
			
		||||
 | 
			
		||||
  g_free (entries);
 | 
			
		||||
  meta_screen_free_workspace_layout (&layout);
 | 
			
		||||
 | 
			
		||||
  meta_ui_tab_popup_select (screen->ws_popup,
 | 
			
		||||
                            (MetaTabEntryKey) initial_selection);
 | 
			
		||||
  meta_ui_tab_popup_set_showing (screen->ws_popup, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_screen_workspace_popup_select (MetaScreen    *screen,
 | 
			
		||||
                                    MetaWorkspace *workspace)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (screen->ws_popup != NULL);
 | 
			
		||||
 | 
			
		||||
  meta_ui_tab_popup_select (screen->ws_popup,
 | 
			
		||||
                            (MetaTabEntryKey) workspace);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaWorkspace *
 | 
			
		||||
meta_screen_workspace_popup_get_selected (MetaScreen *screen)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (screen->ws_popup != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  return (MetaWorkspace *) meta_ui_tab_popup_get_selected (screen->ws_popup);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_screen_workspace_popup_destroy (MetaScreen *screen)
 | 
			
		||||
{
 | 
			
		||||
  if (screen->ws_popup)
 | 
			
		||||
    {
 | 
			
		||||
      meta_ui_tab_popup_free (screen->ws_popup);
 | 
			
		||||
      screen->ws_popup = NULL;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
meta_screen_update_tile_preview_timeout (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -711,9 +711,7 @@ meta_stack_tracker_sync_stack (MetaStackTracker *tracker)
 | 
			
		||||
       * XID => window table. (Wine uses a toplevel for _NET_WM_USER_TIME_WINDOW;
 | 
			
		||||
       * see window-prop.c:reload_net_wm_user_time_window() for registration.)
 | 
			
		||||
       */
 | 
			
		||||
      if (meta_window &&
 | 
			
		||||
          (windows[i] == meta_window->xwindow ||
 | 
			
		||||
           (meta_window->frame && windows[i] == meta_window->frame->xwindow)))
 | 
			
		||||
      if (meta_window && windows[i] == meta_window->xwindow)
 | 
			
		||||
        meta_windows = g_list_prepend (meta_windows, meta_window);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1189,10 +1189,7 @@ stack_sync_to_server (MetaStack *stack)
 | 
			
		||||
      else
 | 
			
		||||
	g_array_prepend_val (stacked, w->xwindow);
 | 
			
		||||
      
 | 
			
		||||
      if (w->frame)
 | 
			
		||||
	top_level_window = w->frame->xwindow;
 | 
			
		||||
      else
 | 
			
		||||
	top_level_window = w->xwindow;
 | 
			
		||||
      top_level_window = w->xwindow;
 | 
			
		||||
 | 
			
		||||
      /* We don't restack hidden windows along with the rest, though they are
 | 
			
		||||
       * reflected in the _NET hints. Hidden windows all get pushed below
 | 
			
		||||
 
 | 
			
		||||
@@ -1705,13 +1705,6 @@ meta_window_unmanage (MetaWindow  *window,
 | 
			
		||||
      meta_compositor_remove_window (window->display->compositor, window);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (window->display->window_with_menu == window)
 | 
			
		||||
    {
 | 
			
		||||
      meta_ui_window_menu_free (window->display->window_menu);
 | 
			
		||||
      window->display->window_menu = NULL;
 | 
			
		||||
      window->display->window_with_menu = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (destroying_windows_disallowed > 0)
 | 
			
		||||
    meta_bug ("Tried to destroy window %s while destruction was not allowed\n",
 | 
			
		||||
              window->desc);
 | 
			
		||||
@@ -3697,10 +3690,6 @@ meta_window_tile (MetaWindow *window)
 | 
			
		||||
                                       window,
 | 
			
		||||
                                       &old_rect,
 | 
			
		||||
                                       &new_rect);
 | 
			
		||||
 | 
			
		||||
      if (window->frame)
 | 
			
		||||
        meta_ui_queue_frame_draw (window->screen->ui,
 | 
			
		||||
                                  window->frame->xwindow);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
@@ -7888,11 +7877,6 @@ meta_window_update_shape_region_x11 (MetaWindow *window)
 | 
			
		||||
static void
 | 
			
		||||
redraw_icon (MetaWindow *window)
 | 
			
		||||
{
 | 
			
		||||
  /* We could probably be smart and just redraw the icon here,
 | 
			
		||||
   * instead of the whole frame.
 | 
			
		||||
   */
 | 
			
		||||
  if (window->frame)
 | 
			
		||||
    meta_ui_queue_frame_draw (window->screen->ui, window->frame->xwindow);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -8644,145 +8628,6 @@ recalc_window_features (MetaWindow *window)
 | 
			
		||||
   */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
menu_callback (MetaWindowMenu *menu,
 | 
			
		||||
               Display        *xdisplay,
 | 
			
		||||
               Window          client_xwindow,
 | 
			
		||||
               guint32         timestamp,
 | 
			
		||||
               MetaMenuOp      op,
 | 
			
		||||
               int             workspace_index,
 | 
			
		||||
               gpointer        data)
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
  MetaWindow *window;
 | 
			
		||||
  MetaWorkspace *workspace;
 | 
			
		||||
 | 
			
		||||
  display = meta_display_for_x_display (xdisplay);
 | 
			
		||||
  window = meta_display_lookup_x_window (display, client_xwindow);
 | 
			
		||||
  workspace = NULL;
 | 
			
		||||
 | 
			
		||||
  if (window != NULL) /* window can be NULL */
 | 
			
		||||
    {
 | 
			
		||||
      meta_verbose ("Menu op %u on %s\n", op, window->desc);
 | 
			
		||||
 | 
			
		||||
      switch (op)
 | 
			
		||||
        {
 | 
			
		||||
        case META_MENU_OP_NONE:
 | 
			
		||||
          /* nothing */
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case META_MENU_OP_DELETE:
 | 
			
		||||
          meta_window_delete (window, timestamp);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case META_MENU_OP_MINIMIZE:
 | 
			
		||||
          meta_window_minimize (window);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case META_MENU_OP_UNMAXIMIZE:
 | 
			
		||||
          meta_window_unmaximize (window,
 | 
			
		||||
                                  META_MAXIMIZE_HORIZONTAL |
 | 
			
		||||
                                  META_MAXIMIZE_VERTICAL);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case META_MENU_OP_MAXIMIZE:
 | 
			
		||||
          meta_window_maximize (window,
 | 
			
		||||
                                META_MAXIMIZE_HORIZONTAL |
 | 
			
		||||
                                META_MAXIMIZE_VERTICAL);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case META_MENU_OP_UNSHADE:
 | 
			
		||||
          meta_window_unshade (window, timestamp);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case META_MENU_OP_SHADE:
 | 
			
		||||
          meta_window_shade (window, timestamp);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case META_MENU_OP_MOVE_LEFT:
 | 
			
		||||
          workspace = meta_workspace_get_neighbor (window->screen->active_workspace,
 | 
			
		||||
                                                   META_MOTION_LEFT);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case META_MENU_OP_MOVE_RIGHT:
 | 
			
		||||
          workspace = meta_workspace_get_neighbor (window->screen->active_workspace,
 | 
			
		||||
                                                   META_MOTION_RIGHT);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case META_MENU_OP_MOVE_UP:
 | 
			
		||||
          workspace = meta_workspace_get_neighbor (window->screen->active_workspace,
 | 
			
		||||
                                                   META_MOTION_UP);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case META_MENU_OP_MOVE_DOWN:
 | 
			
		||||
          workspace = meta_workspace_get_neighbor (window->screen->active_workspace,
 | 
			
		||||
                                                   META_MOTION_DOWN);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case META_MENU_OP_WORKSPACES:
 | 
			
		||||
          workspace = meta_screen_get_workspace_by_index (window->screen,
 | 
			
		||||
                                                          workspace_index);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case META_MENU_OP_STICK:
 | 
			
		||||
          meta_window_stick (window);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case META_MENU_OP_UNSTICK:
 | 
			
		||||
          meta_window_unstick (window);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case META_MENU_OP_ABOVE:
 | 
			
		||||
        case META_MENU_OP_UNABOVE:
 | 
			
		||||
          if (window->wm_state_above == FALSE)
 | 
			
		||||
            meta_window_make_above (window);
 | 
			
		||||
          else
 | 
			
		||||
            meta_window_unmake_above (window);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case META_MENU_OP_MOVE:
 | 
			
		||||
          meta_window_begin_grab_op (window,
 | 
			
		||||
                                     META_GRAB_OP_KEYBOARD_MOVING,
 | 
			
		||||
                                     TRUE,
 | 
			
		||||
                                     timestamp);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case META_MENU_OP_RESIZE:
 | 
			
		||||
          meta_window_begin_grab_op (window,
 | 
			
		||||
                                     META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN,
 | 
			
		||||
                                     TRUE,
 | 
			
		||||
                                     timestamp);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case META_MENU_OP_RECOVER:
 | 
			
		||||
          meta_window_shove_titlebar_onscreen (window);
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
          meta_warning (G_STRLOC": Unknown window op\n");
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (workspace)
 | 
			
		||||
	{
 | 
			
		||||
	  meta_window_change_workspace (window,
 | 
			
		||||
					workspace);
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      meta_verbose ("Menu callback on nonexistent window\n");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (display->window_menu == menu)
 | 
			
		||||
    {
 | 
			
		||||
      display->window_menu = NULL;
 | 
			
		||||
      display->window_with_menu = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_ui_window_menu_free (menu);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_window_show_menu (MetaWindow *window,
 | 
			
		||||
                       int         root_x,
 | 
			
		||||
@@ -8790,126 +8635,6 @@ meta_window_show_menu (MetaWindow *window,
 | 
			
		||||
                       int         button,
 | 
			
		||||
                       guint32     timestamp)
 | 
			
		||||
{
 | 
			
		||||
  MetaMenuOp ops;
 | 
			
		||||
  MetaMenuOp insensitive;
 | 
			
		||||
  MetaWindowMenu *menu;
 | 
			
		||||
  MetaWorkspaceLayout layout;
 | 
			
		||||
  int n_workspaces;
 | 
			
		||||
  gboolean ltr;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (!window->override_redirect);
 | 
			
		||||
 | 
			
		||||
  if (window->display->window_menu)
 | 
			
		||||
    {
 | 
			
		||||
      meta_ui_window_menu_free (window->display->window_menu);
 | 
			
		||||
      window->display->window_menu = NULL;
 | 
			
		||||
      window->display->window_with_menu = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  ops = META_MENU_OP_NONE;
 | 
			
		||||
  insensitive = META_MENU_OP_NONE;
 | 
			
		||||
 | 
			
		||||
  ops |= (META_MENU_OP_DELETE | META_MENU_OP_MINIMIZE | META_MENU_OP_MOVE | META_MENU_OP_RESIZE);
 | 
			
		||||
 | 
			
		||||
  if (!meta_window_titlebar_is_onscreen (window) &&
 | 
			
		||||
      window->type != META_WINDOW_DOCK &&
 | 
			
		||||
      window->type != META_WINDOW_DESKTOP)
 | 
			
		||||
    ops |= META_MENU_OP_RECOVER;
 | 
			
		||||
 | 
			
		||||
  if (!meta_prefs_get_workspaces_only_on_primary () ||
 | 
			
		||||
      meta_window_is_on_primary_monitor (window))
 | 
			
		||||
    {
 | 
			
		||||
      n_workspaces = meta_screen_get_n_workspaces (window->screen);
 | 
			
		||||
 | 
			
		||||
      if (n_workspaces > 1)
 | 
			
		||||
        ops |= META_MENU_OP_WORKSPACES;
 | 
			
		||||
 | 
			
		||||
      meta_screen_calc_workspace_layout (window->screen,
 | 
			
		||||
                                         n_workspaces,
 | 
			
		||||
                                         meta_workspace_index ( window->screen->active_workspace),
 | 
			
		||||
                                         &layout);
 | 
			
		||||
 | 
			
		||||
      if (!window->on_all_workspaces)
 | 
			
		||||
        {
 | 
			
		||||
          ltr = meta_ui_get_direction() == META_UI_DIRECTION_LTR;
 | 
			
		||||
 | 
			
		||||
          if (layout.current_col > 0)
 | 
			
		||||
            ops |= ltr ? META_MENU_OP_MOVE_LEFT : META_MENU_OP_MOVE_RIGHT;
 | 
			
		||||
          if ((layout.current_col < layout.cols - 1) &&
 | 
			
		||||
              (layout.current_row * layout.cols + (layout.current_col + 1) < n_workspaces))
 | 
			
		||||
            ops |= ltr ? META_MENU_OP_MOVE_RIGHT : META_MENU_OP_MOVE_LEFT;
 | 
			
		||||
          if (layout.current_row > 0)
 | 
			
		||||
            ops |= META_MENU_OP_MOVE_UP;
 | 
			
		||||
          if ((layout.current_row < layout.rows - 1) &&
 | 
			
		||||
              ((layout.current_row + 1) * layout.cols + layout.current_col < n_workspaces))
 | 
			
		||||
            ops |= META_MENU_OP_MOVE_DOWN;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      meta_screen_free_workspace_layout (&layout);
 | 
			
		||||
 | 
			
		||||
      ops |= META_MENU_OP_UNSTICK;
 | 
			
		||||
      ops |= META_MENU_OP_STICK;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (META_WINDOW_MAXIMIZED (window))
 | 
			
		||||
    ops |= META_MENU_OP_UNMAXIMIZE;
 | 
			
		||||
  else
 | 
			
		||||
    ops |= META_MENU_OP_MAXIMIZE;
 | 
			
		||||
 | 
			
		||||
  if (window->wm_state_above)
 | 
			
		||||
    ops |= META_MENU_OP_UNABOVE;
 | 
			
		||||
  else
 | 
			
		||||
    ops |= META_MENU_OP_ABOVE;
 | 
			
		||||
 | 
			
		||||
  if (!window->has_maximize_func)
 | 
			
		||||
    insensitive |= META_MENU_OP_UNMAXIMIZE | META_MENU_OP_MAXIMIZE;
 | 
			
		||||
 | 
			
		||||
  if (!window->has_minimize_func)
 | 
			
		||||
    insensitive |= META_MENU_OP_MINIMIZE;
 | 
			
		||||
 | 
			
		||||
  if (!window->has_close_func)
 | 
			
		||||
    insensitive |= META_MENU_OP_DELETE;
 | 
			
		||||
 | 
			
		||||
  if (!window->has_shade_func)
 | 
			
		||||
    insensitive |= META_MENU_OP_SHADE | META_MENU_OP_UNSHADE;
 | 
			
		||||
 | 
			
		||||
  if (!META_WINDOW_ALLOWS_MOVE (window))
 | 
			
		||||
    insensitive |= META_MENU_OP_MOVE;
 | 
			
		||||
 | 
			
		||||
  if (!META_WINDOW_ALLOWS_RESIZE (window))
 | 
			
		||||
    insensitive |= META_MENU_OP_RESIZE;
 | 
			
		||||
 | 
			
		||||
   if (window->always_sticky)
 | 
			
		||||
     insensitive |= META_MENU_OP_STICK | META_MENU_OP_UNSTICK | META_MENU_OP_WORKSPACES;
 | 
			
		||||
 | 
			
		||||
  if ((window->type == META_WINDOW_DESKTOP) ||
 | 
			
		||||
      (window->type == META_WINDOW_DOCK) ||
 | 
			
		||||
      (window->type == META_WINDOW_SPLASHSCREEN ||
 | 
			
		||||
      META_WINDOW_MAXIMIZED (window)))
 | 
			
		||||
    insensitive |= META_MENU_OP_ABOVE | META_MENU_OP_UNABOVE;
 | 
			
		||||
 | 
			
		||||
  /* If all operations are disabled, just quit without showing the menu.
 | 
			
		||||
   * This is the case, for example, with META_WINDOW_DESKTOP windows.
 | 
			
		||||
   */
 | 
			
		||||
  if ((ops & ~insensitive) == 0)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  menu =
 | 
			
		||||
    meta_ui_window_menu_new (window->screen->ui,
 | 
			
		||||
                             window->xwindow,
 | 
			
		||||
                             ops,
 | 
			
		||||
                             insensitive,
 | 
			
		||||
                             meta_window_get_net_wm_desktop (window),
 | 
			
		||||
                             meta_screen_get_n_workspaces (window->screen),
 | 
			
		||||
                             menu_callback,
 | 
			
		||||
                             NULL);
 | 
			
		||||
 | 
			
		||||
  window->display->window_menu = menu;
 | 
			
		||||
  window->display->window_with_menu = window;
 | 
			
		||||
 | 
			
		||||
  meta_verbose ("Popping up window menu for %s\n", window->desc);
 | 
			
		||||
 | 
			
		||||
  meta_ui_window_menu_popup (menu, root_x, root_y, button, timestamp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -11245,13 +10970,7 @@ meta_window_get_frame_type (MetaWindow *window)
 | 
			
		||||
cairo_region_t *
 | 
			
		||||
meta_window_get_frame_bounds (MetaWindow *window)
 | 
			
		||||
{
 | 
			
		||||
  if (!window->frame_bounds)
 | 
			
		||||
    {
 | 
			
		||||
      if (window->frame)
 | 
			
		||||
        window->frame_bounds = meta_frame_get_frame_bounds (window->frame);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return window->frame_bounds;
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										143
									
								
								src/gtk-decorator/gtk-decorator.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								src/gtk-decorator/gtk-decorator.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,143 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2013 Red Hat
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
			
		||||
 * 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by:
 | 
			
		||||
 *     Jasper St. Pierre <jstpierre@mecheye.net>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include <gdk/gdkx.h>
 | 
			
		||||
 | 
			
		||||
#include <X11/extensions/Xcomposite.h>
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  Display *xdisplay;
 | 
			
		||||
} Decorator;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  Decorator decorator;
 | 
			
		||||
  Window child_window;
 | 
			
		||||
 | 
			
		||||
  GtkWidget *window;
 | 
			
		||||
  GtkWidget *socket;
 | 
			
		||||
} WindowFrame;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
socket_size_allocate (GtkWidget     *widget,
 | 
			
		||||
                      GtkAllocation *allocation,
 | 
			
		||||
                      gpointer       user_data)
 | 
			
		||||
{
 | 
			
		||||
  WindowFrame *frame = user_data;
 | 
			
		||||
 | 
			
		||||
  XMoveResizeWindow (GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (widget)),
 | 
			
		||||
                     frame->child_window,
 | 
			
		||||
                     allocation->x, allocation->y,
 | 
			
		||||
                     allocation->width, allocation->height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static WindowFrame *
 | 
			
		||||
frame_window (Decorator *decorator,
 | 
			
		||||
              Window     child_window)
 | 
			
		||||
{
 | 
			
		||||
  WindowFrame *frame;
 | 
			
		||||
  XWindowAttributes attrs;
 | 
			
		||||
  GtkWidget *window, *socket;
 | 
			
		||||
 | 
			
		||||
  XGetWindowAttributes (decorator->xdisplay, child_window, &attrs);
 | 
			
		||||
 | 
			
		||||
  frame = g_slice_new0 (WindowFrame);
 | 
			
		||||
  frame->child_window = child_window;
 | 
			
		||||
 | 
			
		||||
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 | 
			
		||||
  frame->window = window;
 | 
			
		||||
  gtk_window_move (GTK_WINDOW (window), attrs.x, attrs.y);
 | 
			
		||||
 | 
			
		||||
  socket = gtk_frame_new (NULL);
 | 
			
		||||
  frame->socket = socket;
 | 
			
		||||
  gtk_widget_set_size_request (socket, attrs.width, attrs.height);
 | 
			
		||||
  g_signal_connect (socket, "size-allocate",
 | 
			
		||||
                    G_CALLBACK (socket_size_allocate), frame);
 | 
			
		||||
  gtk_container_add (GTK_CONTAINER (window), socket);
 | 
			
		||||
 | 
			
		||||
  gtk_widget_show (socket);
 | 
			
		||||
  gtk_widget_show (window);
 | 
			
		||||
 | 
			
		||||
  XReparentWindow (decorator->xdisplay,
 | 
			
		||||
                   child_window,
 | 
			
		||||
                   GDK_WINDOW_XID (gtk_widget_get_window (window)),
 | 
			
		||||
                   /* these will be positioned correctly at the
 | 
			
		||||
                    * next size-allocate pass... */
 | 
			
		||||
                   0, 0);
 | 
			
		||||
 | 
			
		||||
  return frame;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Window
 | 
			
		||||
find_test_window (Display *dpy)
 | 
			
		||||
{
 | 
			
		||||
  Window root, parent;
 | 
			
		||||
  Window *children;
 | 
			
		||||
  Window ret = None;
 | 
			
		||||
  unsigned int i, n_children;
 | 
			
		||||
 | 
			
		||||
  XQueryTree (dpy, DefaultRootWindow (dpy),
 | 
			
		||||
              &root, &parent,
 | 
			
		||||
              &children, &n_children);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_children; i++)
 | 
			
		||||
    {
 | 
			
		||||
      Window child = children[i];
 | 
			
		||||
      char *name;
 | 
			
		||||
 | 
			
		||||
      XFetchName (dpy, child, &name);
 | 
			
		||||
      if (g_strcmp0 (name, "this is a test window") == 0)
 | 
			
		||||
        ret = child;
 | 
			
		||||
 | 
			
		||||
      g_free (name);
 | 
			
		||||
 | 
			
		||||
      if (ret)
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
decorator_init (Decorator *decorator)
 | 
			
		||||
{
 | 
			
		||||
  decorator->xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main (int    argc,
 | 
			
		||||
      char **argv)
 | 
			
		||||
{
 | 
			
		||||
  Decorator decorator;
 | 
			
		||||
  Window window;
 | 
			
		||||
 | 
			
		||||
  gtk_init (&argc, &argv);
 | 
			
		||||
 | 
			
		||||
  decorator_init (&decorator);
 | 
			
		||||
 | 
			
		||||
  window = find_test_window (decorator.xdisplay);
 | 
			
		||||
  frame_window (&decorator, window);
 | 
			
		||||
 | 
			
		||||
  gtk_main ();
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,71 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/* Mutter gradient rendering */
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2001 Havoc Pennington, 99% copied from wrlib in
 | 
			
		||||
 * WindowMaker, Copyright (C) 1997-2000 Dan Pascu and Alfredo Kojima
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.  */
 | 
			
		||||
 | 
			
		||||
#ifndef META_GRADIENT_H
 | 
			
		||||
#define META_GRADIENT_H
 | 
			
		||||
 | 
			
		||||
#include <gdk-pixbuf/gdk-pixbuf.h>
 | 
			
		||||
#include <gdk/gdk.h>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * MetaGradientType:
 | 
			
		||||
 * @META_GRADIENT_VERTICAL: Vertical gradient
 | 
			
		||||
 * @META_GRADIENT_HORIZONTAL: Horizontal gradient
 | 
			
		||||
 * @META_GRADIENT_DIAGONAL: Diagonal gradient
 | 
			
		||||
 * @META_GRADIENT_LAST: Marks the end of the #MetaGradientType enumeration
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
  META_GRADIENT_VERTICAL,
 | 
			
		||||
  META_GRADIENT_HORIZONTAL,
 | 
			
		||||
  META_GRADIENT_DIAGONAL,
 | 
			
		||||
  META_GRADIENT_LAST
 | 
			
		||||
} MetaGradientType;
 | 
			
		||||
 | 
			
		||||
GdkPixbuf* meta_gradient_create_simple     (int               width,
 | 
			
		||||
                                            int               height,
 | 
			
		||||
                                            const GdkRGBA    *from,
 | 
			
		||||
                                            const GdkRGBA    *to,
 | 
			
		||||
                                            MetaGradientType  style);
 | 
			
		||||
GdkPixbuf* meta_gradient_create_multi      (int               width,
 | 
			
		||||
                                            int               height,
 | 
			
		||||
                                            const GdkRGBA    *colors,
 | 
			
		||||
                                            int               n_colors,
 | 
			
		||||
                                            MetaGradientType  style);
 | 
			
		||||
GdkPixbuf* meta_gradient_create_interwoven (int               width,
 | 
			
		||||
                                            int               height,
 | 
			
		||||
                                            const GdkRGBA     colors1[2],
 | 
			
		||||
                                            int               thickness1,
 | 
			
		||||
                                            const GdkRGBA     colors2[2],
 | 
			
		||||
                                            int               thickness2);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Generate an alpha gradient and multiply it with the existing alpha
 | 
			
		||||
 * channel of the given pixbuf
 | 
			
		||||
 */
 | 
			
		||||
void meta_gradient_add_alpha (GdkPixbuf       *pixbuf,
 | 
			
		||||
                              const guchar    *alphas,
 | 
			
		||||
                              int              n_alphas,
 | 
			
		||||
                              MetaGradientType type);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -24,7 +24,6 @@
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
#include <cogl/cogl.h>
 | 
			
		||||
 | 
			
		||||
#include <meta/gradient.h>
 | 
			
		||||
#include <meta/screen.h>
 | 
			
		||||
 | 
			
		||||
#include <gsettings-desktop-schemas/gdesktop-enums.h>
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,6 @@
 | 
			
		||||
#include <cogl/cogl.h>
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
 | 
			
		||||
#include <meta/gradient.h>
 | 
			
		||||
#include <meta/screen.h>
 | 
			
		||||
 | 
			
		||||
#include <gsettings-desktop-schemas/gdesktop-enums.h>
 | 
			
		||||
 
 | 
			
		||||
@@ -43,7 +43,6 @@
 | 
			
		||||
 * @META_PREF_AUTO_RAISE: auto-raise
 | 
			
		||||
 * @META_PREF_AUTO_RAISE_DELAY: auto-raise delay
 | 
			
		||||
 * @META_PREF_FOCUS_CHANGE_ON_POINTER_REST: focus change on pointer rest
 | 
			
		||||
 * @META_PREF_THEME: theme
 | 
			
		||||
 * @META_PREF_TITLEBAR_FONT: title-bar font
 | 
			
		||||
 * @META_PREF_NUM_WORKSPACES: number of workspaces
 | 
			
		||||
 * @META_PREF_DYNAMIC_WORKSPACES: dynamic workspaces
 | 
			
		||||
@@ -62,7 +61,6 @@
 | 
			
		||||
 * @META_PREF_EDGE_TILING: edge tiling
 | 
			
		||||
 * @META_PREF_FORCE_FULLSCREEN: force fullscreen
 | 
			
		||||
 * @META_PREF_WORKSPACES_ONLY_ON_PRIMARY: workspaces only on primary
 | 
			
		||||
 * @META_PREF_NO_TAB_POPUP: no tab popup
 | 
			
		||||
 * @META_PREF_DRAGGABLE_BORDER_WIDTH: draggable border width
 | 
			
		||||
 * @META_PREF_AUTO_MAXIMIZE: auto-maximize
 | 
			
		||||
 */
 | 
			
		||||
@@ -81,7 +79,6 @@ typedef enum
 | 
			
		||||
  META_PREF_AUTO_RAISE,
 | 
			
		||||
  META_PREF_AUTO_RAISE_DELAY,
 | 
			
		||||
  META_PREF_FOCUS_CHANGE_ON_POINTER_REST,
 | 
			
		||||
  META_PREF_THEME,
 | 
			
		||||
  META_PREF_TITLEBAR_FONT,
 | 
			
		||||
  META_PREF_NUM_WORKSPACES,
 | 
			
		||||
  META_PREF_DYNAMIC_WORKSPACES,
 | 
			
		||||
@@ -100,7 +97,6 @@ typedef enum
 | 
			
		||||
  META_PREF_EDGE_TILING,
 | 
			
		||||
  META_PREF_FORCE_FULLSCREEN,
 | 
			
		||||
  META_PREF_WORKSPACES_ONLY_ON_PRIMARY,
 | 
			
		||||
  META_PREF_NO_TAB_POPUP,
 | 
			
		||||
  META_PREF_DRAGGABLE_BORDER_WIDTH,
 | 
			
		||||
  META_PREF_AUTO_MAXIMIZE
 | 
			
		||||
} MetaPreference;
 | 
			
		||||
@@ -127,7 +123,6 @@ GDesktopFocusMode           meta_prefs_get_focus_mode         (void);
 | 
			
		||||
GDesktopFocusNewWindows     meta_prefs_get_focus_new_windows  (void);
 | 
			
		||||
gboolean                    meta_prefs_get_attach_modal_dialogs (void);
 | 
			
		||||
gboolean                    meta_prefs_get_raise_on_click     (void);
 | 
			
		||||
const char*                 meta_prefs_get_theme              (void);
 | 
			
		||||
/* returns NULL if GTK default should be used */
 | 
			
		||||
const PangoFontDescription* meta_prefs_get_titlebar_font      (void);
 | 
			
		||||
int                         meta_prefs_get_num_workspaces     (void);
 | 
			
		||||
@@ -163,9 +158,6 @@ void meta_prefs_set_force_fullscreen (gboolean whether);
 | 
			
		||||
 | 
			
		||||
gboolean meta_prefs_get_workspaces_only_on_primary (void);
 | 
			
		||||
 | 
			
		||||
gboolean meta_prefs_get_no_tab_popup (void);
 | 
			
		||||
void     meta_prefs_set_no_tab_popup (gboolean whether);
 | 
			
		||||
 | 
			
		||||
int      meta_prefs_get_draggable_border_width (void);
 | 
			
		||||
 | 
			
		||||
gboolean meta_prefs_get_ignore_request_hide_titlebar (void);
 | 
			
		||||
@@ -204,8 +196,6 @@ void     meta_prefs_set_ignore_request_hide_titlebar (gboolean whether);
 | 
			
		||||
 * @META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD: FILLME 
 | 
			
		||||
 * @META_KEYBINDING_ACTION_CYCLE_PANELS: FILLME 
 | 
			
		||||
 * @META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD: FILLME 
 | 
			
		||||
 * @META_KEYBINDING_ACTION_TAB_POPUP_SELECT: FILLME 
 | 
			
		||||
 * @META_KEYBINDING_ACTION_TAB_POPUP_CANCEL: FILLME 
 | 
			
		||||
 * @META_KEYBINDING_ACTION_SHOW_DESKTOP: FILLME 
 | 
			
		||||
 * @META_KEYBINDING_ACTION_PANEL_MAIN_MENU: FILLME 
 | 
			
		||||
 * @META_KEYBINDING_ACTION_PANEL_RUN_DIALOG: FILLME 
 | 
			
		||||
@@ -301,8 +291,6 @@ typedef enum _MetaKeyBindingAction
 | 
			
		||||
  META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD,
 | 
			
		||||
  META_KEYBINDING_ACTION_CYCLE_PANELS,
 | 
			
		||||
  META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD,
 | 
			
		||||
  META_KEYBINDING_ACTION_TAB_POPUP_SELECT,
 | 
			
		||||
  META_KEYBINDING_ACTION_TAB_POPUP_CANCEL,
 | 
			
		||||
  META_KEYBINDING_ACTION_SHOW_DESKTOP,
 | 
			
		||||
  META_KEYBINDING_ACTION_PANEL_MAIN_MENU,
 | 
			
		||||
  META_KEYBINDING_ACTION_PANEL_RUN_DIALOG,
 | 
			
		||||
 
 | 
			
		||||
@@ -111,7 +111,6 @@ gint  meta_unsigned_long_equal (gconstpointer v1,
 | 
			
		||||
                                gconstpointer v2);
 | 
			
		||||
guint meta_unsigned_long_hash  (gconstpointer v);
 | 
			
		||||
 | 
			
		||||
const char* meta_frame_type_to_string (MetaFrameType type);
 | 
			
		||||
const char* meta_gravity_to_string (int gravity);
 | 
			
		||||
 | 
			
		||||
char* meta_external_binding_name_for_action (guint keybinding_action);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,224 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/* Draw a workspace */
 | 
			
		||||
 | 
			
		||||
/* This file should not be modified to depend on other files in
 | 
			
		||||
 * libwnck or mutter, since it's used in both of them
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2002 Red Hat Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "draw-workspace.h"
 | 
			
		||||
#include "theme-private.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
get_window_rect (const WnckWindowDisplayInfo *win,
 | 
			
		||||
                 int                    screen_width,
 | 
			
		||||
                 int                    screen_height,
 | 
			
		||||
                 const GdkRectangle    *workspace_rect,
 | 
			
		||||
                 GdkRectangle          *rect)
 | 
			
		||||
{
 | 
			
		||||
  double width_ratio, height_ratio;
 | 
			
		||||
  int x, y, width, height;
 | 
			
		||||
  
 | 
			
		||||
  width_ratio = (double) workspace_rect->width / (double) screen_width;
 | 
			
		||||
  height_ratio = (double) workspace_rect->height / (double) screen_height;
 | 
			
		||||
  
 | 
			
		||||
  x = win->x;
 | 
			
		||||
  y = win->y;
 | 
			
		||||
  width = win->width;
 | 
			
		||||
  height = win->height;
 | 
			
		||||
  
 | 
			
		||||
  x *= width_ratio;
 | 
			
		||||
  y *= height_ratio;
 | 
			
		||||
  width *= width_ratio;
 | 
			
		||||
  height *= height_ratio;
 | 
			
		||||
  
 | 
			
		||||
  x += workspace_rect->x;
 | 
			
		||||
  y += workspace_rect->y;
 | 
			
		||||
  
 | 
			
		||||
  if (width < 3)
 | 
			
		||||
    width = 3;
 | 
			
		||||
  if (height < 3)
 | 
			
		||||
    height = 3;
 | 
			
		||||
 | 
			
		||||
  rect->x = x;
 | 
			
		||||
  rect->y = y;
 | 
			
		||||
  rect->width = width;
 | 
			
		||||
  rect->height = height;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
draw_window (GtkWidget                   *widget,
 | 
			
		||||
             cairo_t                     *cr,
 | 
			
		||||
             const WnckWindowDisplayInfo *win,
 | 
			
		||||
             const GdkRectangle          *winrect,
 | 
			
		||||
             GtkStateFlags               state)
 | 
			
		||||
{
 | 
			
		||||
  GdkPixbuf *icon;
 | 
			
		||||
  int icon_x, icon_y, icon_w, icon_h;
 | 
			
		||||
  gboolean is_active;
 | 
			
		||||
  GdkRGBA color;
 | 
			
		||||
  GtkStyleContext *style;
 | 
			
		||||
 | 
			
		||||
  is_active = win->is_active;
 | 
			
		||||
  
 | 
			
		||||
  cairo_save (cr);
 | 
			
		||||
 | 
			
		||||
  cairo_rectangle (cr, winrect->x, winrect->y, winrect->width, winrect->height);
 | 
			
		||||
  cairo_clip (cr);
 | 
			
		||||
 | 
			
		||||
  style = gtk_widget_get_style_context (widget);
 | 
			
		||||
  if (is_active)
 | 
			
		||||
    meta_gtk_style_get_light_color (style, state, &color);
 | 
			
		||||
  else
 | 
			
		||||
    gtk_style_context_get_background_color (style, state, &color);
 | 
			
		||||
  gdk_cairo_set_source_rgba (cr, &color);
 | 
			
		||||
 | 
			
		||||
  cairo_rectangle (cr,
 | 
			
		||||
                   winrect->x + 1, winrect->y + 1,
 | 
			
		||||
                   MAX (0, winrect->width - 2), MAX (0, winrect->height - 2));
 | 
			
		||||
  cairo_fill (cr);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  icon = win->icon;
 | 
			
		||||
 | 
			
		||||
  icon_w = icon_h = 0;
 | 
			
		||||
          
 | 
			
		||||
  if (icon)
 | 
			
		||||
    {              
 | 
			
		||||
      icon_w = gdk_pixbuf_get_width (icon);
 | 
			
		||||
      icon_h = gdk_pixbuf_get_height (icon);
 | 
			
		||||
 | 
			
		||||
      /* If the icon is too big, fall back to mini icon.
 | 
			
		||||
       * We don't arbitrarily scale the icon, because it's
 | 
			
		||||
       * just too slow on my Athlon 850.
 | 
			
		||||
       */
 | 
			
		||||
      if (icon_w > (winrect->width - 2) ||
 | 
			
		||||
          icon_h > (winrect->height - 2))
 | 
			
		||||
        {
 | 
			
		||||
          icon = win->mini_icon;
 | 
			
		||||
          if (icon)
 | 
			
		||||
            {
 | 
			
		||||
              icon_w = gdk_pixbuf_get_width (icon);
 | 
			
		||||
              icon_h = gdk_pixbuf_get_height (icon);
 | 
			
		||||
        
 | 
			
		||||
              /* Give up. */
 | 
			
		||||
              if (icon_w > (winrect->width - 2) ||
 | 
			
		||||
                  icon_h > (winrect->height - 2))
 | 
			
		||||
                icon = NULL;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (icon)
 | 
			
		||||
    {
 | 
			
		||||
      icon_x = winrect->x + (winrect->width - icon_w) / 2;
 | 
			
		||||
      icon_y = winrect->y + (winrect->height - icon_h) / 2;
 | 
			
		||||
      
 | 
			
		||||
      cairo_save (cr);
 | 
			
		||||
      gdk_cairo_set_source_pixbuf (cr, icon, icon_x, icon_y);
 | 
			
		||||
      cairo_rectangle (cr, icon_x, icon_y, icon_w, icon_h);
 | 
			
		||||
      cairo_clip (cr);
 | 
			
		||||
      cairo_paint (cr);
 | 
			
		||||
      cairo_restore (cr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  gtk_style_context_get_color (style, state, &color);
 | 
			
		||||
  gdk_cairo_set_source_rgba (cr, &color);
 | 
			
		||||
  cairo_set_line_width (cr, 1.0);
 | 
			
		||||
  cairo_rectangle (cr,
 | 
			
		||||
                   winrect->x + 0.5, winrect->y + 0.5,
 | 
			
		||||
                   MAX (0, winrect->width - 1), MAX (0, winrect->height - 1));
 | 
			
		||||
  cairo_stroke (cr);
 | 
			
		||||
  
 | 
			
		||||
  cairo_restore (cr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
wnck_draw_workspace (GtkWidget                   *widget,
 | 
			
		||||
                     cairo_t                     *cr,
 | 
			
		||||
                     int                          x,
 | 
			
		||||
                     int                          y,
 | 
			
		||||
                     int                          width,
 | 
			
		||||
                     int                          height,
 | 
			
		||||
                     int                          screen_width,
 | 
			
		||||
                     int                          screen_height,
 | 
			
		||||
                     GdkPixbuf                   *workspace_background,
 | 
			
		||||
                     gboolean                     is_active,
 | 
			
		||||
                     const WnckWindowDisplayInfo *windows,
 | 
			
		||||
                     int                          n_windows)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  GdkRectangle workspace_rect;
 | 
			
		||||
  GtkStateFlags state;
 | 
			
		||||
  GtkStyleContext *style;
 | 
			
		||||
 | 
			
		||||
  workspace_rect.x = x;
 | 
			
		||||
  workspace_rect.y = y;
 | 
			
		||||
  workspace_rect.width = width;
 | 
			
		||||
  workspace_rect.height = height;
 | 
			
		||||
 | 
			
		||||
  if (is_active)
 | 
			
		||||
    state = GTK_STATE_FLAG_SELECTED;
 | 
			
		||||
  else if (workspace_background) 
 | 
			
		||||
    state = GTK_STATE_FLAG_PRELIGHT;
 | 
			
		||||
  else
 | 
			
		||||
    state = GTK_STATE_FLAG_NORMAL;
 | 
			
		||||
 | 
			
		||||
  style = gtk_widget_get_style_context (widget);
 | 
			
		||||
  
 | 
			
		||||
  cairo_save (cr);
 | 
			
		||||
 | 
			
		||||
  if (workspace_background)
 | 
			
		||||
    {
 | 
			
		||||
      gdk_cairo_set_source_pixbuf (cr, workspace_background, x, y);
 | 
			
		||||
      cairo_paint (cr);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      GdkRGBA color;
 | 
			
		||||
 | 
			
		||||
      meta_gtk_style_get_dark_color (style,state, &color);
 | 
			
		||||
      gdk_cairo_set_source_rgba (cr, &color);
 | 
			
		||||
      cairo_rectangle (cr, x, y, width, height);
 | 
			
		||||
      cairo_fill (cr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  i = 0;
 | 
			
		||||
  while (i < n_windows)
 | 
			
		||||
    {
 | 
			
		||||
      const WnckWindowDisplayInfo *win = &windows[i];
 | 
			
		||||
      GdkRectangle winrect;
 | 
			
		||||
      
 | 
			
		||||
      get_window_rect (win, screen_width,
 | 
			
		||||
                       screen_height, &workspace_rect, &winrect);
 | 
			
		||||
      
 | 
			
		||||
      draw_window (widget,
 | 
			
		||||
                   cr,
 | 
			
		||||
                   win,
 | 
			
		||||
                   &winrect,
 | 
			
		||||
                   state);
 | 
			
		||||
      
 | 
			
		||||
      ++i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  cairo_restore (cr);
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
@@ -1,59 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/* Draw a workspace */
 | 
			
		||||
 | 
			
		||||
/* This file should not be modified to depend on other files in
 | 
			
		||||
 * libwnck or metacity, since it's used in both of them
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2002 Red Hat Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef WNCK_DRAW_WORKSPACE_H
 | 
			
		||||
#define WNCK_DRAW_WORKSPACE_H
 | 
			
		||||
 | 
			
		||||
#include <gdk/gdk.h>
 | 
			
		||||
#include <gdk-pixbuf/gdk-pixbuf.h>
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  GdkPixbuf *icon;
 | 
			
		||||
  GdkPixbuf *mini_icon;
 | 
			
		||||
  int x;
 | 
			
		||||
  int y;
 | 
			
		||||
  int width;
 | 
			
		||||
  int height;
 | 
			
		||||
 | 
			
		||||
  guint is_active : 1;
 | 
			
		||||
  
 | 
			
		||||
} WnckWindowDisplayInfo;
 | 
			
		||||
 | 
			
		||||
void wnck_draw_workspace (GtkWidget                   *widget,
 | 
			
		||||
                          cairo_t                     *cr,
 | 
			
		||||
                          int                          x,
 | 
			
		||||
                          int                          y,
 | 
			
		||||
                          int                          width,
 | 
			
		||||
                          int                          height,
 | 
			
		||||
                          int                          screen_width,
 | 
			
		||||
                          int                          screen_height,
 | 
			
		||||
                          GdkPixbuf                   *workspace_background,
 | 
			
		||||
                          gboolean                     is_active,
 | 
			
		||||
                          const WnckWindowDisplayInfo *windows,
 | 
			
		||||
                          int                          n_windows);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										2412
									
								
								src/ui/frames.c
									
									
									
									
									
								
							
							
						
						
									
										2412
									
								
								src/ui/frames.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										160
									
								
								src/ui/frames.h
									
									
									
									
									
								
							
							
						
						
									
										160
									
								
								src/ui/frames.h
									
									
									
									
									
								
							@@ -1,160 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/* Metacity window frame manager widget */
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2001 Havoc Pennington
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_FRAMES_H
 | 
			
		||||
#define META_FRAMES_H
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include <gdk/gdkx.h>
 | 
			
		||||
#include <meta/common.h>
 | 
			
		||||
#include "theme-private.h"
 | 
			
		||||
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
  META_FRAME_CONTROL_NONE,
 | 
			
		||||
  META_FRAME_CONTROL_TITLE,
 | 
			
		||||
  META_FRAME_CONTROL_DELETE,
 | 
			
		||||
  META_FRAME_CONTROL_MENU,
 | 
			
		||||
  META_FRAME_CONTROL_MINIMIZE,
 | 
			
		||||
  META_FRAME_CONTROL_MAXIMIZE,
 | 
			
		||||
  META_FRAME_CONTROL_UNMAXIMIZE,
 | 
			
		||||
  META_FRAME_CONTROL_SHADE,
 | 
			
		||||
  META_FRAME_CONTROL_UNSHADE,
 | 
			
		||||
  META_FRAME_CONTROL_ABOVE,
 | 
			
		||||
  META_FRAME_CONTROL_UNABOVE,
 | 
			
		||||
  META_FRAME_CONTROL_STICK,
 | 
			
		||||
  META_FRAME_CONTROL_UNSTICK,
 | 
			
		||||
  META_FRAME_CONTROL_RESIZE_SE,
 | 
			
		||||
  META_FRAME_CONTROL_RESIZE_S,
 | 
			
		||||
  META_FRAME_CONTROL_RESIZE_SW,
 | 
			
		||||
  META_FRAME_CONTROL_RESIZE_N,
 | 
			
		||||
  META_FRAME_CONTROL_RESIZE_NE,
 | 
			
		||||
  META_FRAME_CONTROL_RESIZE_NW,
 | 
			
		||||
  META_FRAME_CONTROL_RESIZE_W,
 | 
			
		||||
  META_FRAME_CONTROL_RESIZE_E,
 | 
			
		||||
  META_FRAME_CONTROL_CLIENT_AREA
 | 
			
		||||
} MetaFrameControl;
 | 
			
		||||
 | 
			
		||||
/* This is one widget that manages all the window frames
 | 
			
		||||
 * as subwindows.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_FRAMES            (meta_frames_get_type ())
 | 
			
		||||
#define META_FRAMES(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_FRAMES, MetaFrames))
 | 
			
		||||
#define META_FRAMES_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_FRAMES, MetaFramesClass))
 | 
			
		||||
#define META_IS_FRAMES(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_FRAMES))
 | 
			
		||||
#define META_IS_FRAMES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_FRAMES))
 | 
			
		||||
#define META_FRAMES_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_FRAMES, MetaFramesClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaFrames        MetaFrames;
 | 
			
		||||
typedef struct _MetaFramesClass   MetaFramesClass;
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaUIFrame         MetaUIFrame;
 | 
			
		||||
 | 
			
		||||
struct _MetaUIFrame
 | 
			
		||||
{
 | 
			
		||||
  Window xwindow;
 | 
			
		||||
  GdkWindow *window;
 | 
			
		||||
  GtkStyleContext *style;
 | 
			
		||||
  MetaFrameStyle *cache_style;
 | 
			
		||||
  PangoLayout *layout;
 | 
			
		||||
  int text_height;
 | 
			
		||||
  char *title; /* NULL once we have a layout */
 | 
			
		||||
  guint shape_applied : 1;
 | 
			
		||||
  
 | 
			
		||||
  /* FIXME get rid of this, it can just be in the MetaFrames struct */
 | 
			
		||||
  MetaFrameControl prelit_control;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaFrames
 | 
			
		||||
{
 | 
			
		||||
  GtkWindow parent_instance;
 | 
			
		||||
  
 | 
			
		||||
  GHashTable *text_heights;
 | 
			
		||||
 | 
			
		||||
  GHashTable *frames;
 | 
			
		||||
  MetaUIFrame *last_motion_frame;
 | 
			
		||||
 | 
			
		||||
  GtkStyleContext *normal_style;
 | 
			
		||||
  GHashTable *style_variants;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaFramesClass
 | 
			
		||||
{
 | 
			
		||||
  GtkWindowClass parent_class;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType        meta_frames_get_type               (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
MetaFrames *meta_frames_new (int screen_number);
 | 
			
		||||
 | 
			
		||||
void meta_frames_manage_window (MetaFrames *frames,
 | 
			
		||||
                                Window      xwindow,
 | 
			
		||||
				GdkWindow  *window);
 | 
			
		||||
void meta_frames_unmanage_window (MetaFrames *frames,
 | 
			
		||||
                                  Window      xwindow);
 | 
			
		||||
void meta_frames_set_title (MetaFrames *frames,
 | 
			
		||||
                            Window      xwindow,
 | 
			
		||||
                            const char *title);
 | 
			
		||||
 | 
			
		||||
void meta_frames_update_frame_style (MetaFrames *frames,
 | 
			
		||||
                                     Window      xwindow);
 | 
			
		||||
 | 
			
		||||
void meta_frames_repaint_frame (MetaFrames *frames,
 | 
			
		||||
                                Window      xwindow);
 | 
			
		||||
 | 
			
		||||
void meta_frames_get_borders (MetaFrames *frames,
 | 
			
		||||
                              Window xwindow,
 | 
			
		||||
                              MetaFrameBorders *borders);
 | 
			
		||||
 | 
			
		||||
void meta_frames_reset_bg     (MetaFrames *frames,
 | 
			
		||||
                               Window      xwindow);
 | 
			
		||||
void meta_frames_unflicker_bg (MetaFrames *frames,
 | 
			
		||||
                               Window      xwindow,
 | 
			
		||||
                               int         target_width,
 | 
			
		||||
                               int         target_height);
 | 
			
		||||
 | 
			
		||||
cairo_region_t *meta_frames_get_frame_bounds (MetaFrames *frames,
 | 
			
		||||
                                              Window      xwindow,
 | 
			
		||||
                                              int         window_width,
 | 
			
		||||
                                              int         window_height);
 | 
			
		||||
 | 
			
		||||
void meta_frames_get_mask (MetaFrames *frames,
 | 
			
		||||
                           Window      xwindow,
 | 
			
		||||
                           guint       width,
 | 
			
		||||
                           guint       height,
 | 
			
		||||
                           cairo_t    *cr);
 | 
			
		||||
 | 
			
		||||
void meta_frames_move_resize_frame (MetaFrames *frames,
 | 
			
		||||
				    Window      xwindow,
 | 
			
		||||
				    int         x,
 | 
			
		||||
				    int         y,
 | 
			
		||||
				    int         width,
 | 
			
		||||
				    int         height);
 | 
			
		||||
void meta_frames_queue_draw (MetaFrames *frames,
 | 
			
		||||
                             Window      xwindow);
 | 
			
		||||
 | 
			
		||||
void meta_frames_notify_menu_hide (MetaFrames *frames);
 | 
			
		||||
 | 
			
		||||
Window meta_frames_get_moving_frame (MetaFrames *frames);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,873 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2001 Havoc Pennington, 99% copied from wrlib in
 | 
			
		||||
 * WindowMaker, Copyright (C) 1997-2000 Dan Pascu and Alfredo Kojima
 | 
			
		||||
 * Copyright (C) 2005 Elijah Newren
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.  */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:gradient
 | 
			
		||||
 * @title: Gradients
 | 
			
		||||
 * @short_description: Metacity gradient rendering
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <meta/gradient.h>
 | 
			
		||||
#include <meta/util.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
/* This is all Alfredo's and Dan's usual very nice WindowMaker code,
 | 
			
		||||
 * slightly GTK-ized
 | 
			
		||||
 */
 | 
			
		||||
static GdkPixbuf* meta_gradient_create_horizontal       (int             width,
 | 
			
		||||
                                                         int             height,
 | 
			
		||||
                                                         const GdkRGBA  *from,
 | 
			
		||||
                                                         const GdkRGBA  *to);
 | 
			
		||||
static GdkPixbuf* meta_gradient_create_vertical         (int             width,
 | 
			
		||||
                                                         int             height,
 | 
			
		||||
                                                         const GdkRGBA  *from,
 | 
			
		||||
                                                         const GdkRGBA  *to);
 | 
			
		||||
static GdkPixbuf* meta_gradient_create_diagonal         (int             width,
 | 
			
		||||
                                                         int             height,
 | 
			
		||||
                                                         const GdkRGBA  *from,
 | 
			
		||||
                                                         const GdkRGBA  *to);
 | 
			
		||||
static GdkPixbuf* meta_gradient_create_multi_horizontal (int             width,
 | 
			
		||||
                                                         int             height,
 | 
			
		||||
                                                         const GdkRGBA  *colors,
 | 
			
		||||
                                                         int             count);
 | 
			
		||||
static GdkPixbuf* meta_gradient_create_multi_vertical   (int             width,
 | 
			
		||||
                                                         int             height,
 | 
			
		||||
                                                         const GdkRGBA  *colors,
 | 
			
		||||
                                                         int             count);
 | 
			
		||||
static GdkPixbuf* meta_gradient_create_multi_diagonal   (int             width,
 | 
			
		||||
                                                         int             height,
 | 
			
		||||
                                                         const GdkRGBA  *colors,
 | 
			
		||||
                                                         int             count);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Used as the destroy notification function for gdk_pixbuf_new() */
 | 
			
		||||
static void
 | 
			
		||||
free_buffer (guchar *pixels, gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  g_free (pixels);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GdkPixbuf*
 | 
			
		||||
blank_pixbuf (int width, int height, gboolean no_padding)
 | 
			
		||||
{
 | 
			
		||||
  guchar *buf;
 | 
			
		||||
  int rowstride;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (width > 0, NULL);
 | 
			
		||||
  g_return_val_if_fail (height > 0, NULL);
 | 
			
		||||
 | 
			
		||||
  if (no_padding)
 | 
			
		||||
    rowstride = width * 3;
 | 
			
		||||
  else
 | 
			
		||||
    /* Always align rows to 32-bit boundaries */  
 | 
			
		||||
    rowstride = 4 * ((3 * width + 3) / 4);
 | 
			
		||||
 | 
			
		||||
  buf = g_try_malloc (height * rowstride);
 | 
			
		||||
  if (!buf)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  return gdk_pixbuf_new_from_data (buf, GDK_COLORSPACE_RGB,
 | 
			
		||||
                                   FALSE, 8,
 | 
			
		||||
                                   width, height, rowstride,
 | 
			
		||||
                                   free_buffer, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_gradient_create_simple:
 | 
			
		||||
 * @width: Width in pixels
 | 
			
		||||
 * @height: Height in pixels
 | 
			
		||||
 * @from: Starting color
 | 
			
		||||
 * @to: Ending color
 | 
			
		||||
 * @style: Gradient style
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer full): A new linear gradient
 | 
			
		||||
 */
 | 
			
		||||
GdkPixbuf*
 | 
			
		||||
meta_gradient_create_simple (int              width,
 | 
			
		||||
                             int              height,
 | 
			
		||||
                             const GdkRGBA   *from,
 | 
			
		||||
                             const GdkRGBA   *to,
 | 
			
		||||
                             MetaGradientType style)
 | 
			
		||||
{
 | 
			
		||||
  switch (style)
 | 
			
		||||
    {
 | 
			
		||||
    case META_GRADIENT_HORIZONTAL:
 | 
			
		||||
      return meta_gradient_create_horizontal (width, height,
 | 
			
		||||
                                              from, to);
 | 
			
		||||
    case META_GRADIENT_VERTICAL:
 | 
			
		||||
      return meta_gradient_create_vertical (width, height,
 | 
			
		||||
                                            from, to);
 | 
			
		||||
 | 
			
		||||
    case META_GRADIENT_DIAGONAL:
 | 
			
		||||
      return meta_gradient_create_diagonal (width, height,
 | 
			
		||||
                                            from, to);
 | 
			
		||||
    case META_GRADIENT_LAST:
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  g_assert_not_reached ();
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_gradient_create_multi:
 | 
			
		||||
 * @width: Width in pixels
 | 
			
		||||
 * @height: Height in pixels
 | 
			
		||||
 * @colors: (array length=n_colors): Array of colors
 | 
			
		||||
 * @n_colors: Number of colors
 | 
			
		||||
 * @style: Gradient style
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer full): A new multi-step linear gradient
 | 
			
		||||
 */
 | 
			
		||||
GdkPixbuf*
 | 
			
		||||
meta_gradient_create_multi (int              width,
 | 
			
		||||
                            int              height,
 | 
			
		||||
                            const GdkRGBA   *colors,
 | 
			
		||||
                            int              n_colors,
 | 
			
		||||
                            MetaGradientType style)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
  if (n_colors > 2)
 | 
			
		||||
    {
 | 
			
		||||
      switch (style)
 | 
			
		||||
        {
 | 
			
		||||
        case META_GRADIENT_HORIZONTAL:
 | 
			
		||||
          return meta_gradient_create_multi_horizontal (width, height, colors, n_colors);
 | 
			
		||||
        case META_GRADIENT_VERTICAL:
 | 
			
		||||
          return meta_gradient_create_multi_vertical (width, height, colors, n_colors);
 | 
			
		||||
        case META_GRADIENT_DIAGONAL:
 | 
			
		||||
          return meta_gradient_create_multi_diagonal (width, height, colors, n_colors);
 | 
			
		||||
        case META_GRADIENT_LAST:
 | 
			
		||||
          g_assert_not_reached ();
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  else if (n_colors > 1)
 | 
			
		||||
    {
 | 
			
		||||
      return meta_gradient_create_simple (width, height, &colors[0], &colors[1],
 | 
			
		||||
                                          style);
 | 
			
		||||
    }
 | 
			
		||||
  else if (n_colors > 0)
 | 
			
		||||
    {
 | 
			
		||||
      return meta_gradient_create_simple (width, height, &colors[0], &colors[0],
 | 
			
		||||
                                          style);
 | 
			
		||||
    }
 | 
			
		||||
  g_assert_not_reached ();
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_gradient_create_interwoven: (skip)
 | 
			
		||||
 * @width: Width in pixels
 | 
			
		||||
 * @height: Height in pixels
 | 
			
		||||
 * @colors1: Array of colors
 | 
			
		||||
 * @thickness1: Thickness
 | 
			
		||||
 * @colors2: Array of colors
 | 
			
		||||
 * @thickness2: Thickness
 | 
			
		||||
 *
 | 
			
		||||
 * Interwoven essentially means we have two vertical gradients,
 | 
			
		||||
 * cut into horizontal strips of the given thickness, and then the strips
 | 
			
		||||
 * are alternated. I'm not sure what it's good for, just copied since
 | 
			
		||||
 * WindowMaker had it.
 | 
			
		||||
 */
 | 
			
		||||
GdkPixbuf*
 | 
			
		||||
meta_gradient_create_interwoven (int            width,
 | 
			
		||||
                                 int            height,
 | 
			
		||||
                                 const GdkRGBA  colors1[2],
 | 
			
		||||
                                 int            thickness1,
 | 
			
		||||
                                 const GdkRGBA  colors2[2],
 | 
			
		||||
                                 int            thickness2)
 | 
			
		||||
{
 | 
			
		||||
  
 | 
			
		||||
  int i, j, k, l, ll;
 | 
			
		||||
  long r1, g1, b1, dr1, dg1, db1;
 | 
			
		||||
  long r2, g2, b2, dr2, dg2, db2;
 | 
			
		||||
  GdkPixbuf *pixbuf;
 | 
			
		||||
  unsigned char *ptr;
 | 
			
		||||
  unsigned char *pixels;
 | 
			
		||||
  int rowstride;
 | 
			
		||||
  
 | 
			
		||||
  pixbuf = blank_pixbuf (width, height, FALSE);
 | 
			
		||||
  if (pixbuf == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
    
 | 
			
		||||
  pixels = gdk_pixbuf_get_pixels (pixbuf);
 | 
			
		||||
  rowstride = gdk_pixbuf_get_rowstride (pixbuf);
 | 
			
		||||
  
 | 
			
		||||
  r1 = (long)(colors1[0].red*0xffffff);
 | 
			
		||||
  g1 = (long)(colors1[0].green*0xffffff);
 | 
			
		||||
  b1 = (long)(colors1[0].blue*0xffffff);
 | 
			
		||||
 | 
			
		||||
  r2 = (long)(colors2[0].red*0xffffff);
 | 
			
		||||
  g2 = (long)(colors2[0].green*0xffffff);
 | 
			
		||||
  b2 = (long)(colors2[0].blue*0xffffff);
 | 
			
		||||
 | 
			
		||||
  dr1 = ((colors1[1].red-colors1[0].red)*0xffffff)/(int)height;
 | 
			
		||||
  dg1 = ((colors1[1].green-colors1[0].green)*0xffffff)/(int)height;
 | 
			
		||||
  db1 = ((colors1[1].blue-colors1[0].blue)*0xffffff)/(int)height;
 | 
			
		||||
 | 
			
		||||
  dr2 = ((colors2[1].red-colors2[0].red)*0xffffff)/(int)height;
 | 
			
		||||
  dg2 = ((colors2[1].green-colors2[0].green)*0xffffff)/(int)height;
 | 
			
		||||
  db2 = ((colors2[1].blue-colors2[0].blue)*0xffffff)/(int)height;
 | 
			
		||||
 | 
			
		||||
  for (i=0,k=0,l=0,ll=thickness1; i<height; i++)
 | 
			
		||||
    {
 | 
			
		||||
      ptr = pixels + i * rowstride;
 | 
			
		||||
      
 | 
			
		||||
      if (k == 0)
 | 
			
		||||
        {
 | 
			
		||||
          ptr[0] = (unsigned char) (r1>>16);
 | 
			
		||||
          ptr[1] = (unsigned char) (g1>>16);
 | 
			
		||||
          ptr[2] = (unsigned char) (b1>>16);
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          ptr[0] = (unsigned char) (r2>>16);
 | 
			
		||||
          ptr[1] = (unsigned char) (g2>>16);
 | 
			
		||||
          ptr[2] = (unsigned char) (b2>>16);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      for (j=1; j <= width/2; j *= 2)
 | 
			
		||||
        memcpy (&(ptr[j*3]), ptr, j*3);
 | 
			
		||||
      memcpy (&(ptr[j*3]), ptr, (width - j)*3);
 | 
			
		||||
 | 
			
		||||
      if (++l == ll)
 | 
			
		||||
        {
 | 
			
		||||
          if (k == 0)
 | 
			
		||||
            {
 | 
			
		||||
              k = 1;
 | 
			
		||||
              ll = thickness2;
 | 
			
		||||
            }
 | 
			
		||||
          else
 | 
			
		||||
            {
 | 
			
		||||
              k = 0;
 | 
			
		||||
              ll = thickness1;
 | 
			
		||||
            }
 | 
			
		||||
          l = 0;
 | 
			
		||||
        }
 | 
			
		||||
      r1+=dr1;
 | 
			
		||||
      g1+=dg1;
 | 
			
		||||
      b1+=db1;
 | 
			
		||||
	
 | 
			
		||||
      r2+=dr2;
 | 
			
		||||
      g2+=dg2;
 | 
			
		||||
      b2+=db2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return pixbuf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *----------------------------------------------------------------------
 | 
			
		||||
 * meta_gradient_create_horizontal--
 | 
			
		||||
 * 	Renders a horizontal linear gradient of the specified size in the
 | 
			
		||||
 * GdkPixbuf format with a border of the specified type. 
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns:
 | 
			
		||||
 * 	A 24bit GdkPixbuf with the gradient (no alpha channel).
 | 
			
		||||
 * 
 | 
			
		||||
 * Side effects:
 | 
			
		||||
 * 	None
 | 
			
		||||
 *---------------------------------------------------------------------- 
 | 
			
		||||
 */
 | 
			
		||||
static GdkPixbuf*
 | 
			
		||||
meta_gradient_create_horizontal (int width, int height,
 | 
			
		||||
                                 const GdkRGBA *from,
 | 
			
		||||
                                 const GdkRGBA *to)
 | 
			
		||||
{    
 | 
			
		||||
  int i;
 | 
			
		||||
  long r, g, b, dr, dg, db;
 | 
			
		||||
  GdkPixbuf *pixbuf;
 | 
			
		||||
  unsigned char *ptr;
 | 
			
		||||
  unsigned char *pixels;
 | 
			
		||||
  int r0, g0, b0;
 | 
			
		||||
  int rf, gf, bf;
 | 
			
		||||
  int rowstride;
 | 
			
		||||
 | 
			
		||||
  pixbuf = blank_pixbuf (width, height, FALSE);
 | 
			
		||||
  if (pixbuf == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
    
 | 
			
		||||
  pixels = gdk_pixbuf_get_pixels (pixbuf);
 | 
			
		||||
  ptr = pixels;
 | 
			
		||||
  rowstride = gdk_pixbuf_get_rowstride (pixbuf);
 | 
			
		||||
  
 | 
			
		||||
  r0 = (guchar) (from->red * 0xff);
 | 
			
		||||
  g0 = (guchar) (from->green * 0xff);
 | 
			
		||||
  b0 = (guchar) (from->blue * 0xff);
 | 
			
		||||
  rf = (guchar) (to->red * 0xff);
 | 
			
		||||
  gf = (guchar) (to->green * 0xff);
 | 
			
		||||
  bf = (guchar) (to->blue * 0xff);
 | 
			
		||||
  
 | 
			
		||||
  r = r0 << 16;
 | 
			
		||||
  g = g0 << 16;
 | 
			
		||||
  b = b0 << 16;
 | 
			
		||||
    
 | 
			
		||||
  dr = ((rf-r0)<<16)/(int)width;
 | 
			
		||||
  dg = ((gf-g0)<<16)/(int)width;
 | 
			
		||||
  db = ((bf-b0)<<16)/(int)width;
 | 
			
		||||
  /* render the first line */
 | 
			
		||||
  for (i=0; i<width; i++)
 | 
			
		||||
    {
 | 
			
		||||
      *(ptr++) = (unsigned char)(r>>16);
 | 
			
		||||
      *(ptr++) = (unsigned char)(g>>16);
 | 
			
		||||
      *(ptr++) = (unsigned char)(b>>16);
 | 
			
		||||
      r += dr;
 | 
			
		||||
      g += dg;
 | 
			
		||||
      b += db;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* copy the first line to the other lines */
 | 
			
		||||
  for (i=1; i<height; i++)
 | 
			
		||||
    {
 | 
			
		||||
      memcpy (&(pixels[i*rowstride]), pixels, rowstride);
 | 
			
		||||
    }
 | 
			
		||||
  return pixbuf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *----------------------------------------------------------------------
 | 
			
		||||
 * meta_gradient_create_vertical--
 | 
			
		||||
 *      Renders a vertical linear gradient of the specified size in the
 | 
			
		||||
 * GdkPixbuf format with a border of the specified type.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns:
 | 
			
		||||
 *      A 24bit GdkPixbuf with the gradient (no alpha channel).
 | 
			
		||||
 *
 | 
			
		||||
 * Side effects:
 | 
			
		||||
 *      None
 | 
			
		||||
 *----------------------------------------------------------------------
 | 
			
		||||
 */
 | 
			
		||||
static GdkPixbuf*
 | 
			
		||||
meta_gradient_create_vertical (int width, int height,
 | 
			
		||||
                               const GdkRGBA *from,
 | 
			
		||||
                               const GdkRGBA *to)
 | 
			
		||||
{
 | 
			
		||||
  int i, j;
 | 
			
		||||
  long r, g, b, dr, dg, db;
 | 
			
		||||
  GdkPixbuf *pixbuf;
 | 
			
		||||
  unsigned char *ptr;
 | 
			
		||||
  int r0, g0, b0;
 | 
			
		||||
  int rf, gf, bf;
 | 
			
		||||
  int rowstride;
 | 
			
		||||
  unsigned char *pixels;
 | 
			
		||||
  
 | 
			
		||||
  pixbuf = blank_pixbuf (width, height, FALSE);
 | 
			
		||||
  if (pixbuf == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
    
 | 
			
		||||
  pixels = gdk_pixbuf_get_pixels (pixbuf);
 | 
			
		||||
  rowstride = gdk_pixbuf_get_rowstride (pixbuf);
 | 
			
		||||
  
 | 
			
		||||
  r0 = (guchar) (from->red * 0xff);
 | 
			
		||||
  g0 = (guchar) (from->green * 0xff);
 | 
			
		||||
  b0 = (guchar) (from->blue * 0xff);
 | 
			
		||||
  rf = (guchar) (to->red * 0xff);
 | 
			
		||||
  gf = (guchar) (to->green * 0xff);
 | 
			
		||||
  bf = (guchar) (to->blue * 0xff);
 | 
			
		||||
  
 | 
			
		||||
  r = r0<<16;
 | 
			
		||||
  g = g0<<16;
 | 
			
		||||
  b = b0<<16;
 | 
			
		||||
 | 
			
		||||
  dr = ((rf-r0)<<16)/(int)height;
 | 
			
		||||
  dg = ((gf-g0)<<16)/(int)height;
 | 
			
		||||
  db = ((bf-b0)<<16)/(int)height;
 | 
			
		||||
 | 
			
		||||
  for (i=0; i<height; i++)
 | 
			
		||||
    {
 | 
			
		||||
      ptr = pixels + i * rowstride;
 | 
			
		||||
      
 | 
			
		||||
      ptr[0] = (unsigned char)(r>>16);
 | 
			
		||||
      ptr[1] = (unsigned char)(g>>16);
 | 
			
		||||
      ptr[2] = (unsigned char)(b>>16);
 | 
			
		||||
 | 
			
		||||
      for (j=1; j <= width/2; j *= 2)
 | 
			
		||||
        memcpy (&(ptr[j*3]), ptr, j*3);
 | 
			
		||||
      memcpy (&(ptr[j*3]), ptr, (width - j)*3);
 | 
			
		||||
 | 
			
		||||
      r+=dr;
 | 
			
		||||
      g+=dg;
 | 
			
		||||
      b+=db;
 | 
			
		||||
    }
 | 
			
		||||
  return pixbuf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *----------------------------------------------------------------------
 | 
			
		||||
 * meta_gradient_create_diagonal--
 | 
			
		||||
 *      Renders a diagonal linear gradient of the specified size in the
 | 
			
		||||
 * GdkPixbuf format with a border of the specified type.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns:
 | 
			
		||||
 *      A 24bit GdkPixbuf with the gradient (no alpha channel).
 | 
			
		||||
 *
 | 
			
		||||
 * Side effects:
 | 
			
		||||
 *      None
 | 
			
		||||
 *----------------------------------------------------------------------
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static GdkPixbuf*
 | 
			
		||||
meta_gradient_create_diagonal (int width, int height,
 | 
			
		||||
                               const GdkRGBA *from,
 | 
			
		||||
                               const GdkRGBA *to)
 | 
			
		||||
{
 | 
			
		||||
  GdkPixbuf *pixbuf, *tmp;
 | 
			
		||||
  int j;
 | 
			
		||||
  float a, offset;
 | 
			
		||||
  unsigned char *ptr;
 | 
			
		||||
  unsigned char *pixels;
 | 
			
		||||
  int rowstride;
 | 
			
		||||
  
 | 
			
		||||
  if (width == 1)
 | 
			
		||||
    return meta_gradient_create_vertical (width, height, from, to);
 | 
			
		||||
  else if (height == 1)
 | 
			
		||||
    return meta_gradient_create_horizontal (width, height, from, to);
 | 
			
		||||
 | 
			
		||||
  pixbuf = blank_pixbuf (width, height, FALSE);
 | 
			
		||||
  if (pixbuf == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
    
 | 
			
		||||
  pixels = gdk_pixbuf_get_pixels (pixbuf);
 | 
			
		||||
  rowstride = gdk_pixbuf_get_rowstride (pixbuf);
 | 
			
		||||
 | 
			
		||||
  tmp = meta_gradient_create_horizontal (2*width-1, 1, from, to);
 | 
			
		||||
  if (!tmp)
 | 
			
		||||
    {
 | 
			
		||||
      g_object_unref (G_OBJECT (pixbuf));
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  ptr = gdk_pixbuf_get_pixels (tmp);
 | 
			
		||||
 | 
			
		||||
  a = ((float)(width - 1))/((float)(height - 1));
 | 
			
		||||
  width = width * 3;
 | 
			
		||||
 | 
			
		||||
  /* copy the first line to the other lines with corresponding offset */
 | 
			
		||||
  for (j=0, offset=0.0; j<rowstride*height; j += rowstride)
 | 
			
		||||
    {
 | 
			
		||||
      memcpy (&(pixels[j]), &ptr[3*(int)offset], width);
 | 
			
		||||
      offset += a;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_object_unref (G_OBJECT (tmp));
 | 
			
		||||
  return pixbuf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static GdkPixbuf*
 | 
			
		||||
meta_gradient_create_multi_horizontal (int width, int height,
 | 
			
		||||
                                       const GdkRGBA *colors,
 | 
			
		||||
                                       int count)
 | 
			
		||||
{
 | 
			
		||||
  int i, j, k;
 | 
			
		||||
  long r, g, b, dr, dg, db;
 | 
			
		||||
  GdkPixbuf *pixbuf;
 | 
			
		||||
  unsigned char *ptr;
 | 
			
		||||
  unsigned char *pixels;
 | 
			
		||||
  int width2;  
 | 
			
		||||
  int rowstride;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (count > 2, NULL);
 | 
			
		||||
 | 
			
		||||
  pixbuf = blank_pixbuf (width, height, FALSE);
 | 
			
		||||
  if (pixbuf == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
    
 | 
			
		||||
  pixels = gdk_pixbuf_get_pixels (pixbuf);
 | 
			
		||||
  rowstride = gdk_pixbuf_get_rowstride (pixbuf);
 | 
			
		||||
  ptr = pixels;
 | 
			
		||||
    
 | 
			
		||||
  if (count > width)
 | 
			
		||||
    count = width;
 | 
			
		||||
    
 | 
			
		||||
  if (count > 1)
 | 
			
		||||
    width2 = width/(count-1);
 | 
			
		||||
  else
 | 
			
		||||
    width2 = width;
 | 
			
		||||
    
 | 
			
		||||
  k = 0;
 | 
			
		||||
 | 
			
		||||
  r = (long)(colors[0].red * 0xffffff);
 | 
			
		||||
  g = (long)(colors[0].green * 0xffffff);
 | 
			
		||||
  b = (long)(colors[0].blue * 0xffffff);
 | 
			
		||||
 | 
			
		||||
  /* render the first line */
 | 
			
		||||
  for (i=1; i<count; i++)
 | 
			
		||||
    {
 | 
			
		||||
      dr = (int)((colors[i].red   - colors[i-1].red)  *0xffffff)/(int)width2;
 | 
			
		||||
      dg = (int)((colors[i].green - colors[i-1].green)*0xffffff)/(int)width2;
 | 
			
		||||
      db = (int)((colors[i].blue  - colors[i-1].blue) *0xffffff)/(int)width2;
 | 
			
		||||
      for (j=0; j<width2; j++)
 | 
			
		||||
        {
 | 
			
		||||
          *ptr++ = (unsigned char)(r>>16);
 | 
			
		||||
          *ptr++ = (unsigned char)(g>>16);
 | 
			
		||||
          *ptr++ = (unsigned char)(b>>16);
 | 
			
		||||
          r += dr;
 | 
			
		||||
          g += dg;
 | 
			
		||||
          b += db;
 | 
			
		||||
          k++;
 | 
			
		||||
	}
 | 
			
		||||
      r = (long)(colors[i].red   * 0xffffff);
 | 
			
		||||
      g = (long)(colors[i].green * 0xffffff);
 | 
			
		||||
      b = (long)(colors[i].blue  * 0xffffff);
 | 
			
		||||
    }
 | 
			
		||||
  for (j=k; j<width; j++)
 | 
			
		||||
    {
 | 
			
		||||
      *ptr++ = (unsigned char)(r>>16);
 | 
			
		||||
      *ptr++ = (unsigned char)(g>>16);
 | 
			
		||||
      *ptr++ = (unsigned char)(b>>16);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
  /* copy the first line to the other lines */
 | 
			
		||||
  for (i=1; i<height; i++)
 | 
			
		||||
    {
 | 
			
		||||
      memcpy (&(pixels[i*rowstride]), pixels, rowstride);
 | 
			
		||||
    }
 | 
			
		||||
  return pixbuf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GdkPixbuf*
 | 
			
		||||
meta_gradient_create_multi_vertical (int width, int height,
 | 
			
		||||
                                     const GdkRGBA *colors,
 | 
			
		||||
                                     int count)
 | 
			
		||||
{
 | 
			
		||||
  int i, j, k;
 | 
			
		||||
  long r, g, b, dr, dg, db;
 | 
			
		||||
  GdkPixbuf *pixbuf;
 | 
			
		||||
  unsigned char *ptr, *tmp, *pixels;
 | 
			
		||||
  int height2;
 | 
			
		||||
  int x;
 | 
			
		||||
  int rowstride;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (count > 2, NULL);
 | 
			
		||||
 | 
			
		||||
  pixbuf = blank_pixbuf (width, height, FALSE);
 | 
			
		||||
  if (pixbuf == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
    
 | 
			
		||||
  pixels = gdk_pixbuf_get_pixels (pixbuf);
 | 
			
		||||
  rowstride = gdk_pixbuf_get_rowstride (pixbuf);
 | 
			
		||||
  ptr = pixels;
 | 
			
		||||
    
 | 
			
		||||
  if (count > height)
 | 
			
		||||
    count = height;
 | 
			
		||||
    
 | 
			
		||||
  if (count > 1)
 | 
			
		||||
    height2 = height/(count-1);
 | 
			
		||||
  else
 | 
			
		||||
    height2 = height;
 | 
			
		||||
    
 | 
			
		||||
  k = 0;
 | 
			
		||||
 | 
			
		||||
  r = (long)(colors[0].red * 0xffffff);
 | 
			
		||||
  g = (long)(colors[0].green * 0xffffff);
 | 
			
		||||
  b = (long)(colors[0].blue * 0xffffff);
 | 
			
		||||
 | 
			
		||||
  for (i=1; i<count; i++)
 | 
			
		||||
    {
 | 
			
		||||
      dr = (int)((colors[i].red   - colors[i-1].red)  *0xffffff)/(int)height2;
 | 
			
		||||
      dg = (int)((colors[i].green - colors[i-1].green)*0xffffff)/(int)height2;
 | 
			
		||||
      db = (int)((colors[i].blue  - colors[i-1].blue) *0xffffff)/(int)height2;
 | 
			
		||||
 | 
			
		||||
      for (j=0; j<height2; j++)
 | 
			
		||||
        {
 | 
			
		||||
          ptr[0] = (unsigned char)(r>>16);
 | 
			
		||||
          ptr[1] = (unsigned char)(g>>16);
 | 
			
		||||
          ptr[2] = (unsigned char)(b>>16);
 | 
			
		||||
 | 
			
		||||
          for (x=1; x <= width/2; x *= 2)
 | 
			
		||||
            memcpy (&(ptr[x*3]), ptr, x*3);
 | 
			
		||||
          memcpy (&(ptr[x*3]), ptr, (width - x)*3);
 | 
			
		||||
 | 
			
		||||
          ptr += rowstride;
 | 
			
		||||
          
 | 
			
		||||
          r += dr;
 | 
			
		||||
          g += dg;
 | 
			
		||||
          b += db;
 | 
			
		||||
          k++;
 | 
			
		||||
	}
 | 
			
		||||
      r = (long)(colors[i].red   * 0xffffff);
 | 
			
		||||
      g = (long)(colors[i].green * 0xffffff);
 | 
			
		||||
      b = (long)(colors[i].blue  * 0xffffff);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (k<height)
 | 
			
		||||
    {
 | 
			
		||||
      tmp = ptr;
 | 
			
		||||
 | 
			
		||||
      ptr[0] = (unsigned char) (r>>16);
 | 
			
		||||
      ptr[1] = (unsigned char) (g>>16);
 | 
			
		||||
      ptr[2] = (unsigned char) (b>>16);
 | 
			
		||||
 | 
			
		||||
      for (x=1; x <= width/2; x *= 2)
 | 
			
		||||
        memcpy (&(ptr[x*3]), ptr, x*3);
 | 
			
		||||
      memcpy (&(ptr[x*3]), ptr, (width - x)*3);
 | 
			
		||||
 | 
			
		||||
      ptr += rowstride;
 | 
			
		||||
      
 | 
			
		||||
      for (j=k+1; j<height; j++)
 | 
			
		||||
        {
 | 
			
		||||
          memcpy (ptr, tmp, rowstride);
 | 
			
		||||
          ptr += rowstride;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
  return pixbuf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static GdkPixbuf*
 | 
			
		||||
meta_gradient_create_multi_diagonal (int width, int height,
 | 
			
		||||
                                     const GdkRGBA *colors,
 | 
			
		||||
                                     int count)
 | 
			
		||||
{
 | 
			
		||||
  GdkPixbuf *pixbuf, *tmp;
 | 
			
		||||
  float a, offset;
 | 
			
		||||
  int j;
 | 
			
		||||
  unsigned char *ptr;
 | 
			
		||||
  unsigned char *pixels;
 | 
			
		||||
  int rowstride;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (count > 2, NULL);
 | 
			
		||||
 | 
			
		||||
  if (width == 1)
 | 
			
		||||
    return meta_gradient_create_multi_vertical (width, height, colors, count);
 | 
			
		||||
  else if (height == 1)
 | 
			
		||||
    return meta_gradient_create_multi_horizontal (width, height, colors, count);
 | 
			
		||||
 | 
			
		||||
  pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8,
 | 
			
		||||
                           width, height);
 | 
			
		||||
  if (pixbuf == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
    
 | 
			
		||||
  pixels = gdk_pixbuf_get_pixels (pixbuf);
 | 
			
		||||
  rowstride = gdk_pixbuf_get_rowstride (pixbuf);
 | 
			
		||||
  
 | 
			
		||||
  if (count > width)
 | 
			
		||||
    count = width;
 | 
			
		||||
  if (count > height)
 | 
			
		||||
    count = height;
 | 
			
		||||
 | 
			
		||||
  if (count > 2)
 | 
			
		||||
    tmp = meta_gradient_create_multi_horizontal (2*width-1, 1, colors, count);
 | 
			
		||||
  else
 | 
			
		||||
    /* wrlib multiplies these colors by 256 before passing them in, but
 | 
			
		||||
     * I think it's a bug in wrlib, so changed here. I could be wrong
 | 
			
		||||
     * though, if we notice two-color multi diagonals not working.
 | 
			
		||||
     */
 | 
			
		||||
    tmp = meta_gradient_create_horizontal (2*width-1, 1,
 | 
			
		||||
                                           &colors[0], &colors[1]);
 | 
			
		||||
 | 
			
		||||
  if (!tmp)
 | 
			
		||||
    {
 | 
			
		||||
      g_object_unref (G_OBJECT (pixbuf));
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
  ptr = gdk_pixbuf_get_pixels (tmp);
 | 
			
		||||
 | 
			
		||||
  a = ((float)(width - 1))/((float)(height - 1));
 | 
			
		||||
  width = width * 3;
 | 
			
		||||
 | 
			
		||||
  /* copy the first line to the other lines with corresponding offset */
 | 
			
		||||
  for (j=0, offset=0; j<rowstride*height; j += rowstride)
 | 
			
		||||
    {
 | 
			
		||||
      memcpy (&(pixels[j]), &ptr[3*(int)offset], width);
 | 
			
		||||
      offset += a;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_object_unref (G_OBJECT (tmp));
 | 
			
		||||
  return pixbuf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
simple_multiply_alpha (GdkPixbuf *pixbuf,
 | 
			
		||||
                       guchar     alpha)
 | 
			
		||||
{
 | 
			
		||||
  guchar *pixels;
 | 
			
		||||
  int rowstride;
 | 
			
		||||
  int height;
 | 
			
		||||
  int row;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
 | 
			
		||||
  
 | 
			
		||||
  if (alpha == 255)
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  g_assert (gdk_pixbuf_get_has_alpha (pixbuf));
 | 
			
		||||
  
 | 
			
		||||
  pixels = gdk_pixbuf_get_pixels (pixbuf);
 | 
			
		||||
  rowstride = gdk_pixbuf_get_rowstride (pixbuf);
 | 
			
		||||
  height = gdk_pixbuf_get_height (pixbuf);
 | 
			
		||||
 | 
			
		||||
  row = 0;
 | 
			
		||||
  while (row < height)
 | 
			
		||||
    {
 | 
			
		||||
      guchar *p;
 | 
			
		||||
      guchar *end;
 | 
			
		||||
 | 
			
		||||
      p = pixels + row * rowstride;
 | 
			
		||||
      end = p + rowstride;
 | 
			
		||||
 | 
			
		||||
      while (p != end)
 | 
			
		||||
        {
 | 
			
		||||
          p += 3; /* skip RGB */
 | 
			
		||||
 | 
			
		||||
          /* multiply the two alpha channels. not sure this is right.
 | 
			
		||||
           * but some end cases are that if the pixbuf contains 255,
 | 
			
		||||
           * then it should be modified to contain "alpha"; if the
 | 
			
		||||
           * pixbuf contains 0, it should remain 0.
 | 
			
		||||
           */
 | 
			
		||||
          /* ((*p / 255.0) * (alpha / 255.0)) * 255; */
 | 
			
		||||
          *p = (guchar) (((int) *p * (int) alpha) / (int) 255);
 | 
			
		||||
          
 | 
			
		||||
          ++p; /* skip A */
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      ++row;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_gradient_add_alpha_horizontal (GdkPixbuf           *pixbuf,
 | 
			
		||||
                                    const unsigned char *alphas,
 | 
			
		||||
                                    int                  n_alphas)
 | 
			
		||||
{
 | 
			
		||||
  int i, j;
 | 
			
		||||
  long a, da;
 | 
			
		||||
  unsigned char *p;
 | 
			
		||||
  unsigned char *pixels;
 | 
			
		||||
  int width2;  
 | 
			
		||||
  int rowstride;
 | 
			
		||||
  int width, height;
 | 
			
		||||
  unsigned char *gradient;
 | 
			
		||||
  unsigned char *gradient_p;
 | 
			
		||||
  unsigned char *gradient_end;
 | 
			
		||||
  
 | 
			
		||||
  g_return_if_fail (n_alphas > 0);
 | 
			
		||||
 | 
			
		||||
  if (n_alphas == 1)
 | 
			
		||||
    {
 | 
			
		||||
      /* Optimize this */
 | 
			
		||||
      simple_multiply_alpha (pixbuf, alphas[0]);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  width = gdk_pixbuf_get_width (pixbuf);
 | 
			
		||||
  height = gdk_pixbuf_get_height (pixbuf);
 | 
			
		||||
 | 
			
		||||
  gradient = g_new (unsigned char, width);
 | 
			
		||||
  gradient_end = gradient + width;
 | 
			
		||||
  
 | 
			
		||||
  if (n_alphas > width)
 | 
			
		||||
    n_alphas = width;
 | 
			
		||||
    
 | 
			
		||||
  if (n_alphas > 1)
 | 
			
		||||
    width2 = width / (n_alphas - 1);
 | 
			
		||||
  else
 | 
			
		||||
    width2 = width;
 | 
			
		||||
    
 | 
			
		||||
  a = alphas[0] << 8;
 | 
			
		||||
  gradient_p = gradient;
 | 
			
		||||
  
 | 
			
		||||
  /* render the gradient into an array */
 | 
			
		||||
  for (i = 1; i < n_alphas; i++)
 | 
			
		||||
    {
 | 
			
		||||
      da = (((int)(alphas[i] - (int) alphas[i-1])) << 8) / (int) width2;
 | 
			
		||||
 | 
			
		||||
      for (j = 0; j < width2; j++)
 | 
			
		||||
        {
 | 
			
		||||
          *gradient_p++ = (a >> 8);
 | 
			
		||||
          
 | 
			
		||||
          a += da;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      a = alphas[i] << 8;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* get leftover pixels */
 | 
			
		||||
  while (gradient_p != gradient_end)
 | 
			
		||||
    {
 | 
			
		||||
      *gradient_p++ = a >> 8;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
  /* Now for each line of the pixbuf, fill in with the gradient */
 | 
			
		||||
  pixels = gdk_pixbuf_get_pixels (pixbuf);
 | 
			
		||||
  rowstride = gdk_pixbuf_get_rowstride (pixbuf);
 | 
			
		||||
  
 | 
			
		||||
  p = pixels;
 | 
			
		||||
  i = 0;
 | 
			
		||||
  while (i < height)
 | 
			
		||||
    {
 | 
			
		||||
      unsigned char *row_end = p + rowstride;
 | 
			
		||||
      gradient_p = gradient;
 | 
			
		||||
 | 
			
		||||
      p += 3;
 | 
			
		||||
      while (gradient_p != gradient_end)
 | 
			
		||||
        {
 | 
			
		||||
          /* multiply the two alpha channels. not sure this is right.
 | 
			
		||||
           * but some end cases are that if the pixbuf contains 255,
 | 
			
		||||
           * then it should be modified to contain "alpha"; if the
 | 
			
		||||
           * pixbuf contains 0, it should remain 0.
 | 
			
		||||
           */
 | 
			
		||||
          /* ((*p / 255.0) * (alpha / 255.0)) * 255; */
 | 
			
		||||
          *p = (guchar) (((int) *p * (int) *gradient_p) / (int) 255);
 | 
			
		||||
 | 
			
		||||
          p += 4;
 | 
			
		||||
          ++gradient_p;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      p = row_end;
 | 
			
		||||
      ++i;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  g_free (gradient);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_gradient_add_alpha (GdkPixbuf       *pixbuf,
 | 
			
		||||
                         const guchar    *alphas,
 | 
			
		||||
                         int              n_alphas,
 | 
			
		||||
                         MetaGradientType type)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
 | 
			
		||||
  g_return_if_fail (gdk_pixbuf_get_has_alpha (pixbuf));
 | 
			
		||||
  g_return_if_fail (n_alphas > 0);
 | 
			
		||||
  
 | 
			
		||||
  switch (type)
 | 
			
		||||
    {
 | 
			
		||||
    case META_GRADIENT_HORIZONTAL:
 | 
			
		||||
      meta_gradient_add_alpha_horizontal (pixbuf, alphas, n_alphas);
 | 
			
		||||
      break;
 | 
			
		||||
      
 | 
			
		||||
    case META_GRADIENT_VERTICAL:
 | 
			
		||||
      g_printerr ("metacity: vertical alpha channel gradient not implemented yet\n");
 | 
			
		||||
      break;
 | 
			
		||||
      
 | 
			
		||||
    case META_GRADIENT_DIAGONAL:
 | 
			
		||||
      g_printerr ("metacity: diagonal alpha channel gradient not implemented yet\n");
 | 
			
		||||
      break;
 | 
			
		||||
      
 | 
			
		||||
    case META_GRADIENT_LAST:
 | 
			
		||||
      g_assert_not_reached ();
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										518
									
								
								src/ui/menu.c
									
									
									
									
									
								
							
							
						
						
									
										518
									
								
								src/ui/menu.c
									
									
									
									
									
								
							@@ -1,518 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/* Mutter window menu */
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2001 Havoc Pennington
 | 
			
		||||
 * Copyright (C) 2004 Rob Adams
 | 
			
		||||
 * Copyright (C) 2005 Elijah Newren
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "menu.h"
 | 
			
		||||
#include <meta/main.h>
 | 
			
		||||
#include "util-private.h"
 | 
			
		||||
#include "core.h"
 | 
			
		||||
#include "metaaccellabel.h"
 | 
			
		||||
#include "ui.h"
 | 
			
		||||
 | 
			
		||||
typedef struct _MenuItem MenuItem;
 | 
			
		||||
typedef struct _MenuData MenuData;
 | 
			
		||||
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
  MENU_ITEM_SEPARATOR = 0,
 | 
			
		||||
  MENU_ITEM_NORMAL,
 | 
			
		||||
  MENU_ITEM_CHECKBOX,
 | 
			
		||||
  MENU_ITEM_RADIOBUTTON,
 | 
			
		||||
  MENU_ITEM_WORKSPACE_LIST,
 | 
			
		||||
} MetaMenuItemType;
 | 
			
		||||
 | 
			
		||||
struct _MenuItem
 | 
			
		||||
{
 | 
			
		||||
  MetaMenuOp op;
 | 
			
		||||
  MetaMenuItemType type;
 | 
			
		||||
  const gboolean checked;
 | 
			
		||||
  const char *label;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct _MenuData
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowMenu *menu;
 | 
			
		||||
  MetaMenuOp op;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void activate_cb (GtkWidget *menuitem, gpointer data);
 | 
			
		||||
 | 
			
		||||
static MenuItem menuitems[] = {
 | 
			
		||||
  /* Translators: Translate this string the same way as you do in libwnck! */
 | 
			
		||||
  { META_MENU_OP_MINIMIZE, MENU_ITEM_NORMAL, FALSE, N_("Mi_nimize") },
 | 
			
		||||
  /* Translators: Translate this string the same way as you do in libwnck! */
 | 
			
		||||
  { META_MENU_OP_MAXIMIZE, MENU_ITEM_NORMAL, FALSE, N_("Ma_ximize") },
 | 
			
		||||
  /* Translators: Translate this string the same way as you do in libwnck! */
 | 
			
		||||
  { META_MENU_OP_UNMAXIMIZE, MENU_ITEM_NORMAL, FALSE, N_("Unma_ximize") },
 | 
			
		||||
  /* Translators: Translate this string the same way as you do in libwnck! */
 | 
			
		||||
  { META_MENU_OP_SHADE, MENU_ITEM_NORMAL, FALSE, N_("Roll _Up") },
 | 
			
		||||
  /* Translators: Translate this string the same way as you do in libwnck! */
 | 
			
		||||
  { META_MENU_OP_UNSHADE, MENU_ITEM_NORMAL, FALSE, N_("_Unroll") },
 | 
			
		||||
  /* Translators: Translate this string the same way as you do in libwnck! */
 | 
			
		||||
  { META_MENU_OP_MOVE, MENU_ITEM_NORMAL, FALSE, N_("_Move") },
 | 
			
		||||
  /* Translators: Translate this string the same way as you do in libwnck! */
 | 
			
		||||
  { META_MENU_OP_RESIZE, MENU_ITEM_NORMAL, FALSE, N_("_Resize") },
 | 
			
		||||
  /* Translators: Translate this string the same way as you do in libwnck! */
 | 
			
		||||
  { META_MENU_OP_RECOVER, MENU_ITEM_NORMAL, FALSE, N_("Move Titlebar On_screen") },
 | 
			
		||||
  { META_MENU_OP_WORKSPACES, MENU_ITEM_SEPARATOR, FALSE, NULL }, /* separator */
 | 
			
		||||
  /* Translators: Translate this string the same way as you do in libwnck! */
 | 
			
		||||
  { META_MENU_OP_ABOVE, MENU_ITEM_CHECKBOX, FALSE, N_("Always on _Top") },
 | 
			
		||||
  /* Translators: Translate this string the same way as you do in libwnck! */
 | 
			
		||||
  { META_MENU_OP_UNABOVE, MENU_ITEM_CHECKBOX, TRUE, N_("Always on _Top") },
 | 
			
		||||
  /* Translators: Translate this string the same way as you do in libwnck! */
 | 
			
		||||
  { META_MENU_OP_STICK, MENU_ITEM_RADIOBUTTON, FALSE, N_("_Always on Visible Workspace") },
 | 
			
		||||
  /* Translators: Translate this string the same way as you do in libwnck! */
 | 
			
		||||
  { META_MENU_OP_UNSTICK, MENU_ITEM_RADIOBUTTON, FALSE,  N_("_Only on This Workspace") },
 | 
			
		||||
  /* Translators: Translate this string the same way as you do in libwnck! */
 | 
			
		||||
  { META_MENU_OP_MOVE_LEFT, MENU_ITEM_NORMAL, FALSE, N_("Move to Workspace _Left") },
 | 
			
		||||
  /* Translators: Translate this string the same way as you do in libwnck! */
 | 
			
		||||
  { META_MENU_OP_MOVE_RIGHT, MENU_ITEM_NORMAL, FALSE, N_("Move to Workspace R_ight") },
 | 
			
		||||
  /* Translators: Translate this string the same way as you do in libwnck! */
 | 
			
		||||
  { META_MENU_OP_MOVE_UP, MENU_ITEM_NORMAL, FALSE, N_("Move to Workspace _Up") },
 | 
			
		||||
  /* Translators: Translate this string the same way as you do in libwnck! */
 | 
			
		||||
  { META_MENU_OP_MOVE_DOWN, MENU_ITEM_NORMAL, FALSE, N_("Move to Workspace _Down") },
 | 
			
		||||
  { 0, MENU_ITEM_WORKSPACE_LIST, FALSE, NULL },
 | 
			
		||||
  { 0, MENU_ITEM_SEPARATOR, FALSE, NULL }, /* separator */
 | 
			
		||||
  /* Translators: Translate this string the same way as you do in libwnck! */
 | 
			
		||||
  { META_MENU_OP_DELETE, MENU_ITEM_NORMAL, FALSE, N_("_Close") }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
popup_position_func (GtkMenu   *menu,
 | 
			
		||||
                     gint      *x,
 | 
			
		||||
                     gint      *y,
 | 
			
		||||
                     gboolean  *push_in,
 | 
			
		||||
                     gpointer  user_data)
 | 
			
		||||
{
 | 
			
		||||
  GtkRequisition req;      
 | 
			
		||||
  GdkPoint *pos;
 | 
			
		||||
 | 
			
		||||
  pos = user_data;
 | 
			
		||||
  
 | 
			
		||||
  gtk_widget_get_preferred_size (GTK_WIDGET (menu), &req, NULL);
 | 
			
		||||
 | 
			
		||||
  *x = pos->x;
 | 
			
		||||
  *y = pos->y;
 | 
			
		||||
  
 | 
			
		||||
  if (meta_ui_get_direction() == META_UI_DIRECTION_RTL)
 | 
			
		||||
    *x = MAX (0, *x - req.width); 
 | 
			
		||||
 | 
			
		||||
  /* Ensure onscreen */
 | 
			
		||||
  *x = CLAMP (*x, 0, MAX (0, gdk_screen_width () - req.width));
 | 
			
		||||
  *y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
menu_closed (GtkMenu *widget,
 | 
			
		||||
             gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowMenu *menu;
 | 
			
		||||
  
 | 
			
		||||
  menu = data;
 | 
			
		||||
 | 
			
		||||
  meta_frames_notify_menu_hide (menu->frames);
 | 
			
		||||
  (* menu->func) (menu,
 | 
			
		||||
                  GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
 | 
			
		||||
                  menu->client_xwindow,
 | 
			
		||||
                  gtk_get_current_event_time (),
 | 
			
		||||
                  0, 0,
 | 
			
		||||
                  menu->data);
 | 
			
		||||
  
 | 
			
		||||
  /* menu may now be freed */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
activate_cb (GtkWidget *menuitem, gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  MenuData *md;
 | 
			
		||||
  
 | 
			
		||||
  g_return_if_fail (GTK_IS_WIDGET (menuitem));
 | 
			
		||||
  
 | 
			
		||||
  md = data;
 | 
			
		||||
 | 
			
		||||
  meta_frames_notify_menu_hide (md->menu->frames);
 | 
			
		||||
  (* md->menu->func) (md->menu,
 | 
			
		||||
                      GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
 | 
			
		||||
                      md->menu->client_xwindow,
 | 
			
		||||
                      gtk_get_current_event_time (),
 | 
			
		||||
                      md->op,
 | 
			
		||||
                      GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem),
 | 
			
		||||
                                                          "workspace")),
 | 
			
		||||
                      md->menu->data);
 | 
			
		||||
 | 
			
		||||
  /* menu may now be freed */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Given a Display and an index, get the workspace name and add any
 | 
			
		||||
 * accelerators. At the moment this means adding a _ if the name is of
 | 
			
		||||
 * the form "Workspace n" where n is less than 10, and escaping any
 | 
			
		||||
 * other '_'s so they do not create inadvertant accelerators.
 | 
			
		||||
 * 
 | 
			
		||||
 * The calling code owns the string, and is reponsible to free the
 | 
			
		||||
 * memory after use.
 | 
			
		||||
 *
 | 
			
		||||
 * See also http://mail.gnome.org/archives/gnome-i18n/2008-March/msg00380.html
 | 
			
		||||
 * which discusses possible i18n concerns.
 | 
			
		||||
 */
 | 
			
		||||
static char*
 | 
			
		||||
get_workspace_name_with_accel (Display *display,
 | 
			
		||||
                               Window   xroot,
 | 
			
		||||
                               int      index)
 | 
			
		||||
{
 | 
			
		||||
  const char *name;
 | 
			
		||||
  int number;
 | 
			
		||||
  int charcount=0;
 | 
			
		||||
 | 
			
		||||
  name = meta_core_get_workspace_name_with_index (display, xroot, index);
 | 
			
		||||
 | 
			
		||||
  g_assert (name != NULL);
 | 
			
		||||
  
 | 
			
		||||
  /*
 | 
			
		||||
   * If the name is of the form "Workspace x" where x is an unsigned
 | 
			
		||||
   * integer, insert a '_' before the number if it is less than 10 and
 | 
			
		||||
   * return it
 | 
			
		||||
   */
 | 
			
		||||
  number = 0;
 | 
			
		||||
  if (sscanf (name, _("Workspace %d%n"), &number, &charcount) != 0 &&
 | 
			
		||||
      *(name + charcount)=='\0')
 | 
			
		||||
    {
 | 
			
		||||
      char *new_name;
 | 
			
		||||
      
 | 
			
		||||
      /*
 | 
			
		||||
       * Above name is a pointer into the Workspace struct. Here we make
 | 
			
		||||
       * a copy copy so we can have our wicked way with it.
 | 
			
		||||
       */
 | 
			
		||||
      if (number == 10)
 | 
			
		||||
        new_name = g_strdup_printf (_("Workspace 1_0"));
 | 
			
		||||
      else
 | 
			
		||||
        new_name = g_strdup_printf (_("Workspace %s%d"),
 | 
			
		||||
                                    number < 10 ? "_" : "",
 | 
			
		||||
                                    number);
 | 
			
		||||
      return new_name;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      /*
 | 
			
		||||
       * Otherwise this is just a normal name. Escape any _ characters so that
 | 
			
		||||
       * the user's workspace names do not get mangled.  If the number is less
 | 
			
		||||
       * than 10 we provide an accelerator.
 | 
			
		||||
       */
 | 
			
		||||
      char *new_name;
 | 
			
		||||
      const char *source;
 | 
			
		||||
      char *dest;
 | 
			
		||||
 | 
			
		||||
      /*
 | 
			
		||||
       * Assume the worst case, that every character is a _.  We also
 | 
			
		||||
       * provide memory for " (_#)"
 | 
			
		||||
       */
 | 
			
		||||
      new_name = g_malloc0 (strlen (name) * 2 + 6 + 1);
 | 
			
		||||
 | 
			
		||||
      /*
 | 
			
		||||
       * Now iterate down the strings, adding '_' to escape as we go
 | 
			
		||||
       */
 | 
			
		||||
      dest = new_name;
 | 
			
		||||
      source = name;
 | 
			
		||||
      while (*source != '\0')
 | 
			
		||||
        {
 | 
			
		||||
          if (*source == '_')
 | 
			
		||||
            *dest++ = '_';
 | 
			
		||||
          *dest++ = *source++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      /* People don't start at workspace 0, but workspace 1 */
 | 
			
		||||
      if (index < 9)
 | 
			
		||||
        {
 | 
			
		||||
          g_snprintf (dest, 6, " (_%d)", index + 1);
 | 
			
		||||
        }
 | 
			
		||||
      else if (index == 9)
 | 
			
		||||
        {
 | 
			
		||||
          g_snprintf (dest, 6, " (_0)");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      return new_name;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GtkWidget *
 | 
			
		||||
menu_item_new (MenuItem *menuitem, int workspace_id)
 | 
			
		||||
{
 | 
			
		||||
  unsigned int key;
 | 
			
		||||
  MetaVirtualModifier mods;
 | 
			
		||||
  const char *i18n_label;
 | 
			
		||||
  GtkWidget *mi;
 | 
			
		||||
  GtkWidget *accel_label;
 | 
			
		||||
 | 
			
		||||
  if (menuitem->type == MENU_ITEM_NORMAL)
 | 
			
		||||
    {
 | 
			
		||||
      mi = gtk_menu_item_new ();
 | 
			
		||||
    }
 | 
			
		||||
  else if (menuitem->type == MENU_ITEM_CHECKBOX)
 | 
			
		||||
    {
 | 
			
		||||
      mi = gtk_check_menu_item_new ();
 | 
			
		||||
      
 | 
			
		||||
      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi),
 | 
			
		||||
                                      menuitem->checked);
 | 
			
		||||
    }    
 | 
			
		||||
  else if (menuitem->type == MENU_ITEM_RADIOBUTTON)
 | 
			
		||||
    {
 | 
			
		||||
      mi = gtk_check_menu_item_new ();
 | 
			
		||||
 | 
			
		||||
      gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (mi),
 | 
			
		||||
                                             TRUE);
 | 
			
		||||
      gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi),
 | 
			
		||||
                                      menuitem->checked);
 | 
			
		||||
    }
 | 
			
		||||
  else if (menuitem->type == MENU_ITEM_WORKSPACE_LIST)
 | 
			
		||||
    return NULL;
 | 
			
		||||
  else
 | 
			
		||||
    return gtk_separator_menu_item_new ();
 | 
			
		||||
 | 
			
		||||
  i18n_label = _(menuitem->label);
 | 
			
		||||
  meta_core_get_menu_accelerator (menuitem->op, workspace_id, &key, &mods);
 | 
			
		||||
 | 
			
		||||
  accel_label = meta_accel_label_new_with_mnemonic (i18n_label);
 | 
			
		||||
  gtk_misc_set_alignment (GTK_MISC (accel_label), 0.0, 0.5);
 | 
			
		||||
 | 
			
		||||
  gtk_container_add (GTK_CONTAINER (mi), accel_label);
 | 
			
		||||
  gtk_widget_show (accel_label);
 | 
			
		||||
 | 
			
		||||
  meta_accel_label_set_accelerator (META_ACCEL_LABEL (accel_label),
 | 
			
		||||
                                    key, mods);
 | 
			
		||||
  
 | 
			
		||||
  return mi;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaWindowMenu*
 | 
			
		||||
meta_window_menu_new   (MetaFrames         *frames,
 | 
			
		||||
                        MetaMenuOp          ops,
 | 
			
		||||
                        MetaMenuOp          insensitive,
 | 
			
		||||
                        Window              client_xwindow,
 | 
			
		||||
                        unsigned long       active_workspace,
 | 
			
		||||
                        int                 n_workspaces,
 | 
			
		||||
                        MetaWindowMenuFunc  func,
 | 
			
		||||
                        gpointer            data)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  MetaWindowMenu *menu;
 | 
			
		||||
 | 
			
		||||
  /* FIXME: Modifications to 'ops' should happen in meta_window_show_menu */
 | 
			
		||||
  if (n_workspaces < 2)
 | 
			
		||||
    ops &= ~(META_MENU_OP_STICK | META_MENU_OP_UNSTICK | META_MENU_OP_WORKSPACES);
 | 
			
		||||
  else if (n_workspaces == 2) 
 | 
			
		||||
    /* #151183: If we only have two workspaces, disable the menu listing them. */
 | 
			
		||||
    ops &= ~(META_MENU_OP_WORKSPACES);
 | 
			
		||||
  
 | 
			
		||||
  menu = g_new (MetaWindowMenu, 1);
 | 
			
		||||
  menu->frames = frames;
 | 
			
		||||
  menu->client_xwindow = client_xwindow;
 | 
			
		||||
  menu->func = func;
 | 
			
		||||
  menu->data = data;
 | 
			
		||||
  menu->ops = ops;
 | 
			
		||||
  menu->insensitive = insensitive;  
 | 
			
		||||
  
 | 
			
		||||
  menu->menu = gtk_menu_new ();
 | 
			
		||||
 | 
			
		||||
  gtk_menu_set_screen (GTK_MENU (menu->menu),
 | 
			
		||||
                       gtk_widget_get_screen (GTK_WIDGET (frames)));
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < (int) G_N_ELEMENTS (menuitems); i++)
 | 
			
		||||
    {
 | 
			
		||||
      MenuItem menuitem = menuitems[i];
 | 
			
		||||
      if (ops & menuitem.op || menuitem.op == 0)
 | 
			
		||||
        {
 | 
			
		||||
          GtkWidget *mi;
 | 
			
		||||
          MenuData *md;
 | 
			
		||||
          unsigned int key;
 | 
			
		||||
          MetaVirtualModifier mods;
 | 
			
		||||
 | 
			
		||||
          mi = menu_item_new (&menuitem, -1);
 | 
			
		||||
 | 
			
		||||
          /* Set the activeness of radiobuttons. */
 | 
			
		||||
          switch (menuitem.op)
 | 
			
		||||
            {
 | 
			
		||||
            case META_MENU_OP_STICK:
 | 
			
		||||
              gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi),
 | 
			
		||||
                                              active_workspace == 0xFFFFFFFF);
 | 
			
		||||
              break;
 | 
			
		||||
            case META_MENU_OP_UNSTICK:
 | 
			
		||||
              gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mi),
 | 
			
		||||
                                              active_workspace != 0xFFFFFFFF);
 | 
			
		||||
              break;
 | 
			
		||||
            default:
 | 
			
		||||
              break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          if (menuitem.type == MENU_ITEM_WORKSPACE_LIST)
 | 
			
		||||
            {
 | 
			
		||||
              if (ops & META_MENU_OP_WORKSPACES)
 | 
			
		||||
                {
 | 
			
		||||
                  Display *display;
 | 
			
		||||
                  Window xroot;
 | 
			
		||||
                  GdkScreen *screen;
 | 
			
		||||
                  GdkWindow *window;
 | 
			
		||||
                  GtkWidget *submenu;
 | 
			
		||||
                  int j;
 | 
			
		||||
 | 
			
		||||
                  MenuItem to_another_workspace = {
 | 
			
		||||
                    0, MENU_ITEM_NORMAL, FALSE,
 | 
			
		||||
                    N_("Move to Another _Workspace")
 | 
			
		||||
                  };
 | 
			
		||||
 | 
			
		||||
                  meta_verbose ("Creating %d-workspace menu current space %lu\n",
 | 
			
		||||
                      n_workspaces, active_workspace);
 | 
			
		||||
 | 
			
		||||
                  window = gtk_widget_get_window (GTK_WIDGET (frames));
 | 
			
		||||
                  display = GDK_WINDOW_XDISPLAY (window);
 | 
			
		||||
 | 
			
		||||
                  screen = gdk_window_get_screen (window);
 | 
			
		||||
                  xroot = GDK_WINDOW_XID (gdk_screen_get_root_window (screen));
 | 
			
		||||
 | 
			
		||||
                  submenu = gtk_menu_new ();
 | 
			
		||||
 | 
			
		||||
                  g_assert (mi==NULL);
 | 
			
		||||
                  mi = menu_item_new (&to_another_workspace, -1);
 | 
			
		||||
                  gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), submenu);
 | 
			
		||||
 | 
			
		||||
                  for (j = 0; j < n_workspaces; j++)
 | 
			
		||||
                    {
 | 
			
		||||
                      char *label;
 | 
			
		||||
                      MenuData *md;
 | 
			
		||||
                      unsigned int key;
 | 
			
		||||
                      MetaVirtualModifier mods;
 | 
			
		||||
                      MenuItem moveitem;
 | 
			
		||||
                      GtkWidget *submi;
 | 
			
		||||
 | 
			
		||||
                      meta_core_get_menu_accelerator (META_MENU_OP_WORKSPACES,
 | 
			
		||||
                          j + 1,
 | 
			
		||||
                          &key, &mods);
 | 
			
		||||
 | 
			
		||||
                      label = get_workspace_name_with_accel (display, xroot, j);
 | 
			
		||||
 | 
			
		||||
                      moveitem.type = MENU_ITEM_NORMAL;
 | 
			
		||||
                      moveitem.op = META_MENU_OP_WORKSPACES;
 | 
			
		||||
                      moveitem.label = label;
 | 
			
		||||
                      submi = menu_item_new (&moveitem, j + 1);
 | 
			
		||||
 | 
			
		||||
                      g_free (label);
 | 
			
		||||
 | 
			
		||||
                      if ((active_workspace == (unsigned)j) && (ops & META_MENU_OP_UNSTICK))
 | 
			
		||||
                        gtk_widget_set_sensitive (submi, FALSE);
 | 
			
		||||
 | 
			
		||||
                      md = g_new (MenuData, 1);
 | 
			
		||||
 | 
			
		||||
                      md->menu = menu;
 | 
			
		||||
                      md->op = META_MENU_OP_WORKSPACES;
 | 
			
		||||
 | 
			
		||||
                      g_object_set_data (G_OBJECT (submi),
 | 
			
		||||
                          "workspace",
 | 
			
		||||
                          GINT_TO_POINTER (j));
 | 
			
		||||
 | 
			
		||||
                      g_signal_connect_data (G_OBJECT (submi),
 | 
			
		||||
                          "activate",
 | 
			
		||||
                          G_CALLBACK (activate_cb),
 | 
			
		||||
                          md,
 | 
			
		||||
                          (GClosureNotify) g_free, 0);
 | 
			
		||||
 | 
			
		||||
                      gtk_menu_shell_append (GTK_MENU_SHELL (submenu), submi);
 | 
			
		||||
 | 
			
		||||
                      gtk_widget_show (submi);
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
                else
 | 
			
		||||
                  meta_verbose ("not creating workspace menu\n");
 | 
			
		||||
            }
 | 
			
		||||
          else if (menuitem.type != MENU_ITEM_SEPARATOR)
 | 
			
		||||
            {
 | 
			
		||||
              meta_core_get_menu_accelerator (menuitems[i].op, -1,
 | 
			
		||||
                                              &key, &mods);
 | 
			
		||||
 | 
			
		||||
              if (insensitive & menuitem.op)
 | 
			
		||||
                gtk_widget_set_sensitive (mi, FALSE);
 | 
			
		||||
              
 | 
			
		||||
              md = g_new (MenuData, 1);
 | 
			
		||||
              
 | 
			
		||||
              md->menu = menu;
 | 
			
		||||
              md->op = menuitem.op;
 | 
			
		||||
              
 | 
			
		||||
              g_signal_connect_data (G_OBJECT (mi),
 | 
			
		||||
                                     "activate",
 | 
			
		||||
                                     G_CALLBACK (activate_cb),
 | 
			
		||||
                                     md,
 | 
			
		||||
                                     (GClosureNotify) g_free, 0);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          if (mi)
 | 
			
		||||
            {
 | 
			
		||||
              gtk_menu_shell_append (GTK_MENU_SHELL (menu->menu), mi);
 | 
			
		||||
          
 | 
			
		||||
              gtk_widget_show (mi);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
  g_signal_connect (menu->menu, "selection_done",
 | 
			
		||||
                    G_CALLBACK (menu_closed), menu);  
 | 
			
		||||
 | 
			
		||||
  return menu;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_window_menu_popup (MetaWindowMenu     *menu,
 | 
			
		||||
                        int                 root_x,
 | 
			
		||||
                        int                 root_y,
 | 
			
		||||
                        int                 button,
 | 
			
		||||
                        guint32             timestamp)
 | 
			
		||||
{
 | 
			
		||||
  GdkPoint *pt;
 | 
			
		||||
  
 | 
			
		||||
  pt = g_new (GdkPoint, 1);
 | 
			
		||||
 | 
			
		||||
  g_object_set_data_full (G_OBJECT (menu->menu),
 | 
			
		||||
                          "destroy-point",
 | 
			
		||||
                          pt,
 | 
			
		||||
                          g_free);
 | 
			
		||||
 | 
			
		||||
  pt->x = root_x;
 | 
			
		||||
  pt->y = root_y;
 | 
			
		||||
  
 | 
			
		||||
  gtk_menu_popup (GTK_MENU (menu->menu),
 | 
			
		||||
                  NULL, NULL,
 | 
			
		||||
                  popup_position_func, pt,
 | 
			
		||||
                  button,
 | 
			
		||||
                  timestamp);
 | 
			
		||||
 | 
			
		||||
  if (!gtk_widget_get_visible (menu->menu))
 | 
			
		||||
    meta_warning ("GtkMenu failed to grab the pointer\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_window_menu_free (MetaWindowMenu *menu)
 | 
			
		||||
{
 | 
			
		||||
  gtk_widget_destroy (menu->menu);
 | 
			
		||||
  g_free (menu);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,55 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/* Mutter window menu */
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2001 Havoc Pennington
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_MENU_H
 | 
			
		||||
#define META_MENU_H
 | 
			
		||||
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include "frames.h"
 | 
			
		||||
 | 
			
		||||
struct _MetaWindowMenu
 | 
			
		||||
{
 | 
			
		||||
  MetaFrames *frames;
 | 
			
		||||
  Window client_xwindow;
 | 
			
		||||
  GtkWidget *menu;
 | 
			
		||||
  MetaWindowMenuFunc func;
 | 
			
		||||
  gpointer data;
 | 
			
		||||
  MetaMenuOp ops;
 | 
			
		||||
  MetaMenuOp insensitive;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MetaWindowMenu* meta_window_menu_new      (MetaFrames         *frames,
 | 
			
		||||
                                           MetaMenuOp          ops,
 | 
			
		||||
                                           MetaMenuOp          insensitive,
 | 
			
		||||
                                           Window              client_xwindow,
 | 
			
		||||
                                           unsigned long       active_workspace,
 | 
			
		||||
                                           int                 n_workspaces,
 | 
			
		||||
                                           MetaWindowMenuFunc  func,
 | 
			
		||||
                                           gpointer            data);
 | 
			
		||||
void            meta_window_menu_popup    (MetaWindowMenu     *menu,
 | 
			
		||||
                                           int                 root_x,
 | 
			
		||||
                                           int                 root_y,
 | 
			
		||||
                                           int                 button,
 | 
			
		||||
                                           guint32             timestamp);
 | 
			
		||||
void            meta_window_menu_free     (MetaWindowMenu     *menu);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,963 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/* Mutter popup window thing showing windows you can tab to */
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2001 Havoc Pennington
 | 
			
		||||
 * Copyright (C) 2002 Red Hat, Inc.
 | 
			
		||||
 * Copyright (C) 2005 Elijah Newren
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include <meta/util.h>
 | 
			
		||||
#include "core.h"
 | 
			
		||||
#include "tabpopup.h"
 | 
			
		||||
/* FIXME these two includes are 100% broken ...
 | 
			
		||||
 */
 | 
			
		||||
#include "workspace-private.h"
 | 
			
		||||
#include "frame.h"
 | 
			
		||||
#include "draw-workspace.h"
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
#include <math.h>
 | 
			
		||||
 | 
			
		||||
#define OUTSIDE_SELECT_RECT 2
 | 
			
		||||
#define INSIDE_SELECT_RECT 2
 | 
			
		||||
 | 
			
		||||
typedef struct _TabEntry TabEntry;
 | 
			
		||||
 | 
			
		||||
struct _TabEntry
 | 
			
		||||
{
 | 
			
		||||
  MetaTabEntryKey  key;
 | 
			
		||||
  char            *title;
 | 
			
		||||
  GdkPixbuf       *icon, *dimmed_icon;
 | 
			
		||||
  GtkWidget       *widget;
 | 
			
		||||
  GdkRectangle     rect;
 | 
			
		||||
  GdkRectangle     inner_rect;
 | 
			
		||||
  guint blank : 1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaTabPopup
 | 
			
		||||
{
 | 
			
		||||
  GtkWidget *window;
 | 
			
		||||
  GtkWidget *label;
 | 
			
		||||
  GList *current;
 | 
			
		||||
  GList *entries;
 | 
			
		||||
  TabEntry *current_selected_entry;
 | 
			
		||||
  GtkWidget *outline_window;
 | 
			
		||||
  gboolean outline;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static GtkWidget* selectable_image_new (GdkPixbuf *pixbuf);
 | 
			
		||||
static void       select_image         (GtkWidget *widget);
 | 
			
		||||
static void       unselect_image       (GtkWidget *widget);
 | 
			
		||||
 | 
			
		||||
static GtkWidget* selectable_workspace_new (MetaWorkspace *workspace);
 | 
			
		||||
static void       select_workspace         (GtkWidget *widget);
 | 
			
		||||
static void       unselect_workspace       (GtkWidget *widget);
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
outline_window_draw (GtkWidget *widget,
 | 
			
		||||
                     cairo_t   *cr,
 | 
			
		||||
                     gpointer   data)
 | 
			
		||||
{
 | 
			
		||||
  MetaTabPopup *popup;
 | 
			
		||||
  TabEntry *te;
 | 
			
		||||
  
 | 
			
		||||
  popup = data;
 | 
			
		||||
 | 
			
		||||
  if (!popup->outline || popup->current_selected_entry == NULL)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  te = popup->current_selected_entry;
 | 
			
		||||
 | 
			
		||||
  cairo_set_line_width (cr, 1.0);
 | 
			
		||||
  cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
 | 
			
		||||
 | 
			
		||||
  cairo_rectangle (cr,
 | 
			
		||||
                   0.5, 0.5,
 | 
			
		||||
                   te->rect.width - 1,
 | 
			
		||||
                   te->rect.height - 1);
 | 
			
		||||
  cairo_stroke (cr);
 | 
			
		||||
 | 
			
		||||
  cairo_rectangle (cr,
 | 
			
		||||
                   te->inner_rect.x - 0.5, te->inner_rect.y - 0.5,
 | 
			
		||||
                   te->inner_rect.width + 1,
 | 
			
		||||
                   te->inner_rect.height + 1);
 | 
			
		||||
  cairo_stroke (cr);
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GdkPixbuf*
 | 
			
		||||
dimm_icon (GdkPixbuf *pixbuf)
 | 
			
		||||
{
 | 
			
		||||
  int x, y, pixel_stride, row_stride;
 | 
			
		||||
  guchar *row, *pixels;
 | 
			
		||||
  int w, h;
 | 
			
		||||
  GdkPixbuf *dimmed_pixbuf;
 | 
			
		||||
 | 
			
		||||
  if (gdk_pixbuf_get_has_alpha (pixbuf))
 | 
			
		||||
    {
 | 
			
		||||
      dimmed_pixbuf = gdk_pixbuf_copy (pixbuf);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      dimmed_pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  w = gdk_pixbuf_get_width (dimmed_pixbuf);
 | 
			
		||||
  h = gdk_pixbuf_get_height (dimmed_pixbuf);      
 | 
			
		||||
 | 
			
		||||
  pixel_stride = 4;
 | 
			
		||||
 | 
			
		||||
  row = gdk_pixbuf_get_pixels (dimmed_pixbuf);
 | 
			
		||||
  row_stride = gdk_pixbuf_get_rowstride (dimmed_pixbuf);
 | 
			
		||||
 | 
			
		||||
  for (y = 0; y < h; y++)
 | 
			
		||||
    {
 | 
			
		||||
      pixels = row;                     
 | 
			
		||||
      for (x = 0; x < w; x++) 
 | 
			
		||||
        {
 | 
			
		||||
          pixels[3] /= 2;                               
 | 
			
		||||
          pixels += pixel_stride;
 | 
			
		||||
        }                       
 | 
			
		||||
      row += row_stride;
 | 
			
		||||
    }
 | 
			
		||||
  return dimmed_pixbuf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static TabEntry*  
 | 
			
		||||
tab_entry_new (const MetaTabEntry *entry, 
 | 
			
		||||
               gint                screen_width,
 | 
			
		||||
               gboolean            outline)
 | 
			
		||||
{
 | 
			
		||||
  TabEntry *te;
 | 
			
		||||
  
 | 
			
		||||
  te = g_new (TabEntry, 1);
 | 
			
		||||
  te->key = entry->key;
 | 
			
		||||
  te->title = NULL;
 | 
			
		||||
  if (entry->title)
 | 
			
		||||
    {
 | 
			
		||||
      gchar *str;
 | 
			
		||||
      gchar *tmp;
 | 
			
		||||
      gchar *formatter = "%s";
 | 
			
		||||
 | 
			
		||||
      str = meta_g_utf8_strndup (entry->title, 4096);
 | 
			
		||||
 | 
			
		||||
      if (entry->hidden)
 | 
			
		||||
        {
 | 
			
		||||
          formatter = "[%s]";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      tmp = g_markup_printf_escaped (formatter, str);
 | 
			
		||||
      g_free (str);
 | 
			
		||||
      str = tmp;
 | 
			
		||||
 | 
			
		||||
      if (entry->demands_attention) 
 | 
			
		||||
        {         
 | 
			
		||||
          /* Escape the whole line of text then markup the text and 
 | 
			
		||||
           * copy it back into the original buffer.
 | 
			
		||||
           */
 | 
			
		||||
          tmp = g_strdup_printf ("<b>%s</b>", str);
 | 
			
		||||
          g_free (str);
 | 
			
		||||
          str = tmp;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        te->title=g_strdup(str);
 | 
			
		||||
 | 
			
		||||
      g_free (str);
 | 
			
		||||
    }
 | 
			
		||||
  te->widget = NULL;
 | 
			
		||||
  te->icon = entry->icon;
 | 
			
		||||
  te->blank = entry->blank;
 | 
			
		||||
  te->dimmed_icon = NULL;
 | 
			
		||||
  if (te->icon)
 | 
			
		||||
    {
 | 
			
		||||
      g_object_ref (G_OBJECT (te->icon));
 | 
			
		||||
      if (entry->hidden)
 | 
			
		||||
        te->dimmed_icon = dimm_icon (entry->icon);
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  if (outline)
 | 
			
		||||
    {
 | 
			
		||||
      te->rect.x = entry->rect.x;
 | 
			
		||||
      te->rect.y = entry->rect.y;
 | 
			
		||||
      te->rect.width = entry->rect.width;
 | 
			
		||||
      te->rect.height = entry->rect.height;
 | 
			
		||||
 | 
			
		||||
      te->inner_rect.x = entry->inner_rect.x;
 | 
			
		||||
      te->inner_rect.y = entry->inner_rect.y;
 | 
			
		||||
      te->inner_rect.width = entry->inner_rect.width;
 | 
			
		||||
      te->inner_rect.height = entry->inner_rect.height;
 | 
			
		||||
    }
 | 
			
		||||
  return te;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaTabPopup*
 | 
			
		||||
meta_ui_tab_popup_new (const MetaTabEntry *entries,
 | 
			
		||||
                       int                 screen_number,
 | 
			
		||||
                       int                 entry_count,
 | 
			
		||||
                       int                 width,
 | 
			
		||||
                       gboolean            outline)
 | 
			
		||||
{
 | 
			
		||||
  MetaTabPopup *popup;
 | 
			
		||||
  int i, left, top;
 | 
			
		||||
  int height;
 | 
			
		||||
  GtkWidget *grid;
 | 
			
		||||
  GtkWidget *vbox;
 | 
			
		||||
  GtkWidget *align;
 | 
			
		||||
  GList *tmp;
 | 
			
		||||
  GtkWidget *frame;
 | 
			
		||||
  int max_label_width; /* the actual max width of the labels we create */
 | 
			
		||||
  AtkObject *obj;
 | 
			
		||||
  GdkScreen *screen;
 | 
			
		||||
  int screen_width;
 | 
			
		||||
  
 | 
			
		||||
  popup = g_new (MetaTabPopup, 1);
 | 
			
		||||
 | 
			
		||||
  popup->outline_window = gtk_window_new (GTK_WINDOW_POPUP);
 | 
			
		||||
 | 
			
		||||
  screen = gdk_display_get_screen (gdk_display_get_default (),
 | 
			
		||||
                                   screen_number);
 | 
			
		||||
  gtk_window_set_screen (GTK_WINDOW (popup->outline_window),
 | 
			
		||||
                         screen);
 | 
			
		||||
 | 
			
		||||
  gtk_widget_set_app_paintable (popup->outline_window, TRUE);
 | 
			
		||||
  gtk_widget_realize (popup->outline_window);
 | 
			
		||||
 | 
			
		||||
  g_signal_connect (G_OBJECT (popup->outline_window), "draw",
 | 
			
		||||
                    G_CALLBACK (outline_window_draw), popup);
 | 
			
		||||
  
 | 
			
		||||
  popup->window = gtk_window_new (GTK_WINDOW_POPUP);
 | 
			
		||||
 | 
			
		||||
  gtk_window_set_screen (GTK_WINDOW (popup->window),
 | 
			
		||||
                         screen);
 | 
			
		||||
 | 
			
		||||
  gtk_window_set_position (GTK_WINDOW (popup->window),
 | 
			
		||||
                           GTK_WIN_POS_CENTER_ALWAYS);
 | 
			
		||||
  /* enable resizing, to get never-shrink behavior */
 | 
			
		||||
  gtk_window_set_resizable (GTK_WINDOW (popup->window),
 | 
			
		||||
                            TRUE);
 | 
			
		||||
  popup->current = NULL;
 | 
			
		||||
  popup->entries = NULL;
 | 
			
		||||
  popup->current_selected_entry = NULL;
 | 
			
		||||
  popup->outline = outline;
 | 
			
		||||
 | 
			
		||||
  screen_width = gdk_screen_get_width (screen);
 | 
			
		||||
  for (i = 0; i < entry_count; ++i)
 | 
			
		||||
    {
 | 
			
		||||
      TabEntry* new_entry = tab_entry_new (&entries[i], screen_width, outline);
 | 
			
		||||
      popup->entries = g_list_prepend (popup->entries, new_entry);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  popup->entries = g_list_reverse (popup->entries);
 | 
			
		||||
    
 | 
			
		||||
  g_assert (width > 0);
 | 
			
		||||
  height = i / width;
 | 
			
		||||
  if (i % width)
 | 
			
		||||
    height += 1;
 | 
			
		||||
 | 
			
		||||
  grid = gtk_grid_new ();
 | 
			
		||||
  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
 | 
			
		||||
  
 | 
			
		||||
  frame = gtk_frame_new (NULL);
 | 
			
		||||
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
 | 
			
		||||
  gtk_container_set_border_width (GTK_CONTAINER (grid), 1);
 | 
			
		||||
  gtk_container_add (GTK_CONTAINER (popup->window),
 | 
			
		||||
                     frame);
 | 
			
		||||
  gtk_container_add (GTK_CONTAINER (frame),
 | 
			
		||||
                     vbox);
 | 
			
		||||
 | 
			
		||||
  align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
 | 
			
		||||
 | 
			
		||||
  gtk_box_pack_start (GTK_BOX (vbox), align, TRUE, TRUE, 0);
 | 
			
		||||
 | 
			
		||||
  gtk_container_add (GTK_CONTAINER (align),
 | 
			
		||||
                     grid);
 | 
			
		||||
 | 
			
		||||
  popup->label = gtk_label_new ("");
 | 
			
		||||
 | 
			
		||||
  /* Set the accessible role of the label to a status bar so it
 | 
			
		||||
   * will emit name changed events that can be used by screen
 | 
			
		||||
   * readers.
 | 
			
		||||
   */
 | 
			
		||||
  obj = gtk_widget_get_accessible (popup->label);
 | 
			
		||||
  atk_object_set_role (obj, ATK_ROLE_STATUSBAR);
 | 
			
		||||
 | 
			
		||||
  gtk_misc_set_padding (GTK_MISC (popup->label), 3, 3);
 | 
			
		||||
 | 
			
		||||
  gtk_box_pack_end (GTK_BOX (vbox), popup->label, FALSE, FALSE, 0);
 | 
			
		||||
 | 
			
		||||
  max_label_width = 0;
 | 
			
		||||
  top = 0;
 | 
			
		||||
  tmp = popup->entries;
 | 
			
		||||
 | 
			
		||||
  while (tmp && top < height)
 | 
			
		||||
    {      
 | 
			
		||||
      left = 0;
 | 
			
		||||
 | 
			
		||||
      while (tmp && left < width)
 | 
			
		||||
        {
 | 
			
		||||
          GtkWidget *image;
 | 
			
		||||
          GtkRequisition req;
 | 
			
		||||
 | 
			
		||||
          TabEntry *te;
 | 
			
		||||
 | 
			
		||||
          te = tmp->data;
 | 
			
		||||
 | 
			
		||||
          if (te->blank)
 | 
			
		||||
            {
 | 
			
		||||
              /* just stick a widget here to avoid special cases */
 | 
			
		||||
              image = gtk_alignment_new (0.0, 0.0, 0.0, 0.0);
 | 
			
		||||
            }
 | 
			
		||||
          else if (outline)
 | 
			
		||||
            {
 | 
			
		||||
              if (te->dimmed_icon)
 | 
			
		||||
                {
 | 
			
		||||
                  image = selectable_image_new (te->dimmed_icon);
 | 
			
		||||
                }
 | 
			
		||||
              else 
 | 
			
		||||
                {
 | 
			
		||||
                  image = selectable_image_new (te->icon);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
              gtk_misc_set_padding (GTK_MISC (image),
 | 
			
		||||
                                    INSIDE_SELECT_RECT + OUTSIDE_SELECT_RECT + 1,
 | 
			
		||||
                                    INSIDE_SELECT_RECT + OUTSIDE_SELECT_RECT + 1);
 | 
			
		||||
              gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.5);
 | 
			
		||||
            }   
 | 
			
		||||
          else
 | 
			
		||||
            {
 | 
			
		||||
              image = selectable_workspace_new ((MetaWorkspace *) te->key);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          te->widget = image;
 | 
			
		||||
 | 
			
		||||
          gtk_grid_attach (GTK_GRID (grid),
 | 
			
		||||
                           te->widget,
 | 
			
		||||
                           left, top, 1, 1);
 | 
			
		||||
 | 
			
		||||
          /* Efficiency rules! */
 | 
			
		||||
          gtk_label_set_markup (GTK_LABEL (popup->label),
 | 
			
		||||
                              te->title);
 | 
			
		||||
          gtk_widget_get_preferred_size (popup->label, &req, NULL);
 | 
			
		||||
          max_label_width = MAX (max_label_width, req.width);
 | 
			
		||||
          
 | 
			
		||||
          tmp = tmp->next;
 | 
			
		||||
          
 | 
			
		||||
          ++left;
 | 
			
		||||
        }
 | 
			
		||||
      
 | 
			
		||||
      ++top;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* remove all the temporary text */
 | 
			
		||||
  gtk_label_set_text (GTK_LABEL (popup->label), "");
 | 
			
		||||
  /* Make it so that we ellipsize if the text is too long */
 | 
			
		||||
  gtk_label_set_ellipsize (GTK_LABEL (popup->label), PANGO_ELLIPSIZE_END);
 | 
			
		||||
 | 
			
		||||
  /* Limit the window size to no bigger than screen_width/4 */
 | 
			
		||||
  if (max_label_width>(screen_width/4)) 
 | 
			
		||||
    {
 | 
			
		||||
      max_label_width = screen_width/4;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  max_label_width += 20; /* add random padding */
 | 
			
		||||
  
 | 
			
		||||
  gtk_window_set_default_size (GTK_WINDOW (popup->window),
 | 
			
		||||
                               max_label_width,
 | 
			
		||||
                               -1);
 | 
			
		||||
  
 | 
			
		||||
  return popup;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
free_tab_entry (gpointer data, gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
  TabEntry *te;
 | 
			
		||||
 | 
			
		||||
  te = data;
 | 
			
		||||
  
 | 
			
		||||
  g_free (te->title);
 | 
			
		||||
  if (te->icon)
 | 
			
		||||
    g_object_unref (G_OBJECT (te->icon));
 | 
			
		||||
  if (te->dimmed_icon)
 | 
			
		||||
    g_object_unref (G_OBJECT (te->dimmed_icon));
 | 
			
		||||
 | 
			
		||||
  g_free (te);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_ui_tab_popup_free (MetaTabPopup *popup)
 | 
			
		||||
{
 | 
			
		||||
  meta_verbose ("Destroying tab popup window\n");
 | 
			
		||||
 | 
			
		||||
  if (!popup)
 | 
			
		||||
    {
 | 
			
		||||
      meta_warning ("NULL passed to meta_ui_tab_popup_free\n");
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  gtk_widget_destroy (popup->outline_window);
 | 
			
		||||
  gtk_widget_destroy (popup->window);
 | 
			
		||||
  
 | 
			
		||||
  g_list_foreach (popup->entries, free_tab_entry, NULL);
 | 
			
		||||
 | 
			
		||||
  g_list_free (popup->entries);
 | 
			
		||||
  
 | 
			
		||||
  g_free (popup);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_ui_tab_popup_set_showing (MetaTabPopup *popup,
 | 
			
		||||
                               gboolean      showing)
 | 
			
		||||
{
 | 
			
		||||
  if (showing)
 | 
			
		||||
    {
 | 
			
		||||
      gtk_widget_show_all (popup->window);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      if (gtk_widget_get_visible (popup->window))
 | 
			
		||||
        {
 | 
			
		||||
          meta_verbose ("Hiding tab popup window\n");
 | 
			
		||||
          gtk_widget_hide (popup->window);
 | 
			
		||||
          meta_core_increment_event_serial (
 | 
			
		||||
              GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
display_entry (MetaTabPopup *popup,
 | 
			
		||||
               TabEntry     *te)
 | 
			
		||||
{
 | 
			
		||||
  GdkRectangle rect;
 | 
			
		||||
  GdkWindow *window;
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  if (popup->current_selected_entry)
 | 
			
		||||
  {
 | 
			
		||||
    if (popup->outline)
 | 
			
		||||
      unselect_image (popup->current_selected_entry->widget);
 | 
			
		||||
    else
 | 
			
		||||
      unselect_workspace (popup->current_selected_entry->widget);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  gtk_label_set_markup (GTK_LABEL (popup->label), te->title);
 | 
			
		||||
 | 
			
		||||
  if (popup->outline)
 | 
			
		||||
    select_image (te->widget);
 | 
			
		||||
  else
 | 
			
		||||
    select_workspace (te->widget);
 | 
			
		||||
 | 
			
		||||
  if (popup->outline)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_region_t *region;
 | 
			
		||||
      cairo_region_t *inner_region;
 | 
			
		||||
      GdkRGBA black = { 0.0, 0.0, 0.0, 1.0 };
 | 
			
		||||
 | 
			
		||||
      window = gtk_widget_get_window (popup->outline_window);
 | 
			
		||||
 | 
			
		||||
      /* Do stuff behind gtk's back */
 | 
			
		||||
      gdk_window_hide (window);
 | 
			
		||||
      meta_core_increment_event_serial (
 | 
			
		||||
          GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
 | 
			
		||||
  
 | 
			
		||||
      rect = te->rect;
 | 
			
		||||
      rect.x = 0;
 | 
			
		||||
      rect.y = 0;
 | 
			
		||||
 | 
			
		||||
      gdk_window_move_resize (window,
 | 
			
		||||
                              te->rect.x, te->rect.y,
 | 
			
		||||
                              te->rect.width, te->rect.height);
 | 
			
		||||
  
 | 
			
		||||
      gdk_window_set_background_rgba (window, &black);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      region = cairo_region_create_rectangle (&rect);
 | 
			
		||||
      inner_region = cairo_region_create_rectangle (&te->inner_rect);
 | 
			
		||||
      cairo_region_subtract (region, inner_region);
 | 
			
		||||
      cairo_region_destroy (inner_region);
 | 
			
		||||
 | 
			
		||||
      gdk_window_shape_combine_region (window,
 | 
			
		||||
                                       region,
 | 
			
		||||
                                       0, 0);
 | 
			
		||||
 | 
			
		||||
      cairo_region_destroy (region);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
      /* This should piss off gtk a bit, but we don't want to raise
 | 
			
		||||
       * above the tab popup.  So, instead of calling gtk_widget_show,
 | 
			
		||||
       * we manually set the window as mapped and then manually map it
 | 
			
		||||
       * with gdk functions.
 | 
			
		||||
       */
 | 
			
		||||
      gtk_widget_set_mapped (popup->outline_window, TRUE);
 | 
			
		||||
      gdk_window_show_unraised (window);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* Must be before we handle an expose for the outline window */
 | 
			
		||||
  popup->current_selected_entry = te;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_ui_tab_popup_forward (MetaTabPopup *popup)
 | 
			
		||||
{
 | 
			
		||||
  if (popup->current != NULL)
 | 
			
		||||
    popup->current = popup->current->next;
 | 
			
		||||
 | 
			
		||||
  if (popup->current == NULL)
 | 
			
		||||
    popup->current = popup->entries;
 | 
			
		||||
  
 | 
			
		||||
  if (popup->current != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      TabEntry *te;
 | 
			
		||||
 | 
			
		||||
      te = popup->current->data;
 | 
			
		||||
 | 
			
		||||
      display_entry (popup, te);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_ui_tab_popup_backward (MetaTabPopup *popup)
 | 
			
		||||
{
 | 
			
		||||
  if (popup->current != NULL)
 | 
			
		||||
    popup->current = popup->current->prev;
 | 
			
		||||
 | 
			
		||||
  if (popup->current == NULL)
 | 
			
		||||
    popup->current = g_list_last (popup->entries);
 | 
			
		||||
  
 | 
			
		||||
  if (popup->current != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      TabEntry *te;
 | 
			
		||||
 | 
			
		||||
      te = popup->current->data;
 | 
			
		||||
 | 
			
		||||
      display_entry (popup, te);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaTabEntryKey
 | 
			
		||||
meta_ui_tab_popup_get_selected (MetaTabPopup *popup)
 | 
			
		||||
{
 | 
			
		||||
  if (popup->current)
 | 
			
		||||
    {
 | 
			
		||||
      TabEntry *te;
 | 
			
		||||
 | 
			
		||||
      te = popup->current->data;
 | 
			
		||||
 | 
			
		||||
      return te->key;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    return (MetaTabEntryKey)None;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_ui_tab_popup_select (MetaTabPopup *popup,
 | 
			
		||||
                          MetaTabEntryKey key)
 | 
			
		||||
{
 | 
			
		||||
  GList *tmp;
 | 
			
		||||
 | 
			
		||||
  /* Note, "key" may not be in the list of entries; other code assumes
 | 
			
		||||
   * it's OK to pass in a key that isn't.
 | 
			
		||||
   */
 | 
			
		||||
  
 | 
			
		||||
  tmp = popup->entries;
 | 
			
		||||
  while (tmp != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      TabEntry *te;
 | 
			
		||||
 | 
			
		||||
      te = tmp->data;
 | 
			
		||||
 | 
			
		||||
      if (te->key == key)
 | 
			
		||||
        {
 | 
			
		||||
          popup->current = tmp;
 | 
			
		||||
          
 | 
			
		||||
          display_entry (popup, te);
 | 
			
		||||
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
      
 | 
			
		||||
      tmp = tmp->next;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_SELECT_IMAGE            (meta_select_image_get_type ())
 | 
			
		||||
#define META_SELECT_IMAGE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SELECT_IMAGE, MetaSelectImage))
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaSelectImage       MetaSelectImage;
 | 
			
		||||
typedef struct _MetaSelectImageClass  MetaSelectImageClass;
 | 
			
		||||
 | 
			
		||||
struct _MetaSelectImage
 | 
			
		||||
{
 | 
			
		||||
  GtkImage parent_instance;
 | 
			
		||||
  guint selected : 1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaSelectImageClass
 | 
			
		||||
{
 | 
			
		||||
  GtkImageClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static GType meta_select_image_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
static GtkWidget*
 | 
			
		||||
selectable_image_new (GdkPixbuf *pixbuf)
 | 
			
		||||
{
 | 
			
		||||
  GtkWidget *w;
 | 
			
		||||
 | 
			
		||||
  w = g_object_new (meta_select_image_get_type (), NULL);
 | 
			
		||||
  gtk_image_set_from_pixbuf (GTK_IMAGE (w), pixbuf); 
 | 
			
		||||
 | 
			
		||||
  return w;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
select_image (GtkWidget *widget)
 | 
			
		||||
{
 | 
			
		||||
  META_SELECT_IMAGE (widget)->selected = TRUE;
 | 
			
		||||
  gtk_widget_queue_draw (widget);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unselect_image (GtkWidget *widget)
 | 
			
		||||
{
 | 
			
		||||
  META_SELECT_IMAGE (widget)->selected = FALSE;
 | 
			
		||||
  gtk_widget_queue_draw (widget);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void     meta_select_image_class_init   (MetaSelectImageClass *klass);
 | 
			
		||||
static gboolean meta_select_image_draw         (GtkWidget            *widget,
 | 
			
		||||
                                                cairo_t              *cr);
 | 
			
		||||
 | 
			
		||||
static GtkImageClass *parent_class;
 | 
			
		||||
 | 
			
		||||
GType
 | 
			
		||||
meta_select_image_get_type (void)
 | 
			
		||||
{
 | 
			
		||||
  static GType image_type = 0;
 | 
			
		||||
 | 
			
		||||
  if (!image_type)
 | 
			
		||||
    {
 | 
			
		||||
      static const GTypeInfo image_info =
 | 
			
		||||
      {
 | 
			
		||||
        sizeof (MetaSelectImageClass),
 | 
			
		||||
        NULL,           /* base_init */
 | 
			
		||||
        NULL,           /* base_finalize */
 | 
			
		||||
        (GClassInitFunc) meta_select_image_class_init,
 | 
			
		||||
        NULL,           /* class_finalize */
 | 
			
		||||
        NULL,           /* class_data */
 | 
			
		||||
        sizeof (MetaSelectImage),
 | 
			
		||||
        16,             /* n_preallocs */
 | 
			
		||||
        (GInstanceInitFunc) NULL,
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      image_type = g_type_register_static (GTK_TYPE_IMAGE, "MetaSelectImage", &image_info, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return image_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_select_image_class_init (MetaSelectImageClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GtkWidgetClass *widget_class;
 | 
			
		||||
  
 | 
			
		||||
  parent_class = g_type_class_peek (gtk_image_get_type ());
 | 
			
		||||
 | 
			
		||||
  widget_class = GTK_WIDGET_CLASS (klass);
 | 
			
		||||
  
 | 
			
		||||
  widget_class->draw = meta_select_image_draw;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
meta_select_image_draw (GtkWidget *widget,
 | 
			
		||||
                        cairo_t   *cr)
 | 
			
		||||
{
 | 
			
		||||
  GtkAllocation allocation;
 | 
			
		||||
 | 
			
		||||
  gtk_widget_get_allocation (widget, &allocation);
 | 
			
		||||
 | 
			
		||||
  if (META_SELECT_IMAGE (widget)->selected)
 | 
			
		||||
    {
 | 
			
		||||
      GtkMisc *misc;
 | 
			
		||||
      GtkRequisition requisition;
 | 
			
		||||
      GtkStyleContext *context;
 | 
			
		||||
      GdkRGBA color;
 | 
			
		||||
      int x, y, w, h;
 | 
			
		||||
      gint xpad, ypad;
 | 
			
		||||
      gfloat xalign, yalign;
 | 
			
		||||
 | 
			
		||||
      misc = GTK_MISC (widget);
 | 
			
		||||
 | 
			
		||||
      gtk_widget_get_requisition (widget, &requisition);
 | 
			
		||||
      gtk_misc_get_alignment (misc, &xalign, &yalign);
 | 
			
		||||
      gtk_misc_get_padding (misc, &xpad, &ypad);
 | 
			
		||||
      
 | 
			
		||||
      x = (allocation.width - (requisition.width - xpad * 2)) * xalign + 0.5;
 | 
			
		||||
      y = (allocation.height - (requisition.height - ypad * 2)) * yalign + 0.5;
 | 
			
		||||
 | 
			
		||||
      x -= INSIDE_SELECT_RECT + 1;
 | 
			
		||||
      y -= INSIDE_SELECT_RECT + 1;      
 | 
			
		||||
      
 | 
			
		||||
      w = requisition.width - OUTSIDE_SELECT_RECT * 2 - 1;
 | 
			
		||||
      h = requisition.height - OUTSIDE_SELECT_RECT * 2 - 1;
 | 
			
		||||
 | 
			
		||||
      context = gtk_widget_get_style_context (widget);
 | 
			
		||||
 | 
			
		||||
      gtk_style_context_set_state (context,
 | 
			
		||||
                                   gtk_widget_get_state_flags (widget));
 | 
			
		||||
 | 
			
		||||
      gtk_style_context_lookup_color (context, "color", &color);
 | 
			
		||||
 | 
			
		||||
      cairo_set_line_width (cr, 2.0);
 | 
			
		||||
      cairo_set_source_rgb (cr, color.red, color.green, color.blue);
 | 
			
		||||
 | 
			
		||||
      cairo_rectangle (cr, x, y, w + 1, h + 1);
 | 
			
		||||
      cairo_stroke (cr);
 | 
			
		||||
 | 
			
		||||
      cairo_set_line_width (cr, 1.0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return GTK_WIDGET_CLASS (parent_class)->draw (widget, cr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_SELECT_WORKSPACE   (meta_select_workspace_get_type ())
 | 
			
		||||
#define META_SELECT_WORKSPACE(obj)   (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SELECT_WORKSPACE, MetaSelectWorkspace))
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaSelectWorkspace       MetaSelectWorkspace;
 | 
			
		||||
typedef struct _MetaSelectWorkspaceClass  MetaSelectWorkspaceClass;
 | 
			
		||||
 | 
			
		||||
struct _MetaSelectWorkspace
 | 
			
		||||
{
 | 
			
		||||
  GtkDrawingArea parent_instance;
 | 
			
		||||
  MetaWorkspace *workspace;
 | 
			
		||||
  guint selected : 1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaSelectWorkspaceClass
 | 
			
		||||
{
 | 
			
		||||
  GtkDrawingAreaClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static GType meta_select_workspace_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
#define SELECT_OUTLINE_WIDTH 2
 | 
			
		||||
#define MINI_WORKSPACE_WIDTH 48
 | 
			
		||||
 | 
			
		||||
static GtkWidget*
 | 
			
		||||
selectable_workspace_new (MetaWorkspace *workspace)
 | 
			
		||||
{
 | 
			
		||||
  GtkWidget *widget;
 | 
			
		||||
  double screen_aspect;
 | 
			
		||||
  
 | 
			
		||||
  widget = g_object_new (meta_select_workspace_get_type (), NULL);
 | 
			
		||||
 | 
			
		||||
  screen_aspect = (double) workspace->screen->rect.height /
 | 
			
		||||
                  (double) workspace->screen->rect.width;
 | 
			
		||||
  
 | 
			
		||||
  /* account for select rect */ 
 | 
			
		||||
  gtk_widget_set_size_request (widget,
 | 
			
		||||
                               MINI_WORKSPACE_WIDTH + SELECT_OUTLINE_WIDTH * 2,
 | 
			
		||||
                               MINI_WORKSPACE_WIDTH * screen_aspect + SELECT_OUTLINE_WIDTH * 2);
 | 
			
		||||
 | 
			
		||||
  META_SELECT_WORKSPACE (widget)->workspace = workspace;
 | 
			
		||||
 | 
			
		||||
  return widget;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
select_workspace (GtkWidget *widget)
 | 
			
		||||
{
 | 
			
		||||
  META_SELECT_WORKSPACE(widget)->selected = TRUE;
 | 
			
		||||
  gtk_widget_queue_draw (widget);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unselect_workspace (GtkWidget *widget)
 | 
			
		||||
{
 | 
			
		||||
  META_SELECT_WORKSPACE (widget)->selected = FALSE;
 | 
			
		||||
  gtk_widget_queue_draw (widget);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void meta_select_workspace_class_init (MetaSelectWorkspaceClass *klass);
 | 
			
		||||
 | 
			
		||||
static gboolean meta_select_workspace_draw         (GtkWidget      *widget,
 | 
			
		||||
                                                    cairo_t        *cr);
 | 
			
		||||
 | 
			
		||||
GType
 | 
			
		||||
meta_select_workspace_get_type (void)
 | 
			
		||||
{
 | 
			
		||||
  static GType workspace_type = 0;
 | 
			
		||||
 | 
			
		||||
  if (!workspace_type)
 | 
			
		||||
    {
 | 
			
		||||
      static const GTypeInfo workspace_info =
 | 
			
		||||
      {
 | 
			
		||||
        sizeof (MetaSelectWorkspaceClass),
 | 
			
		||||
        NULL,           /* base_init */
 | 
			
		||||
        NULL,           /* base_finalize */
 | 
			
		||||
        (GClassInitFunc) meta_select_workspace_class_init,
 | 
			
		||||
        NULL,           /* class_finalize */
 | 
			
		||||
        NULL,           /* class_data */
 | 
			
		||||
        sizeof (MetaSelectWorkspace),
 | 
			
		||||
        16,             /* n_preallocs */
 | 
			
		||||
        (GInstanceInitFunc) NULL,
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      workspace_type = g_type_register_static (GTK_TYPE_DRAWING_AREA, 
 | 
			
		||||
                                               "MetaSelectWorkspace", 
 | 
			
		||||
                                               &workspace_info, 
 | 
			
		||||
                                               0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return workspace_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_select_workspace_class_init (MetaSelectWorkspaceClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GtkWidgetClass *widget_class;
 | 
			
		||||
  
 | 
			
		||||
  widget_class = GTK_WIDGET_CLASS (klass);
 | 
			
		||||
  
 | 
			
		||||
  widget_class->draw = meta_select_workspace_draw;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_convert_meta_to_wnck:
 | 
			
		||||
 * @window: the #MetaWindow
 | 
			
		||||
 * @screen: the #MetaScreen the window is on
 | 
			
		||||
 *
 | 
			
		||||
 * Converts a #MetaWindow to a #WnckWindowDisplayInfo window
 | 
			
		||||
 * that is used to build a thumbnail of a workspace.
 | 
			
		||||
 **/
 | 
			
		||||
static WnckWindowDisplayInfo
 | 
			
		||||
meta_convert_meta_to_wnck (MetaWindow *window, MetaScreen *screen)
 | 
			
		||||
{
 | 
			
		||||
  WnckWindowDisplayInfo wnck_window;
 | 
			
		||||
  wnck_window.icon = window->icon;
 | 
			
		||||
  wnck_window.mini_icon = window->mini_icon;
 | 
			
		||||
  wnck_window.is_active = window->has_focus;
 | 
			
		||||
 | 
			
		||||
  if (window->frame)
 | 
			
		||||
    {
 | 
			
		||||
      wnck_window.x = window->frame->rect.x;
 | 
			
		||||
      wnck_window.y = window->frame->rect.y;
 | 
			
		||||
      wnck_window.width = window->frame->rect.width;
 | 
			
		||||
      wnck_window.height = window->frame->rect.height;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      wnck_window.x = window->rect.x;
 | 
			
		||||
      wnck_window.y = window->rect.y;
 | 
			
		||||
      wnck_window.width = window->rect.width;
 | 
			
		||||
      wnck_window.height = window->rect.height;
 | 
			
		||||
    }
 | 
			
		||||
  return wnck_window;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
meta_select_workspace_draw (GtkWidget *widget,
 | 
			
		||||
                            cairo_t   *cr)
 | 
			
		||||
{
 | 
			
		||||
  MetaWorkspace *workspace;
 | 
			
		||||
  WnckWindowDisplayInfo *windows;
 | 
			
		||||
  GtkAllocation allocation;
 | 
			
		||||
  int i, n_windows;
 | 
			
		||||
  GList *tmp, *list;
 | 
			
		||||
 | 
			
		||||
  workspace = META_SELECT_WORKSPACE (widget)->workspace;
 | 
			
		||||
              
 | 
			
		||||
  list = meta_stack_list_windows (workspace->screen->stack, workspace);
 | 
			
		||||
  n_windows = g_list_length (list);
 | 
			
		||||
  windows = g_new (WnckWindowDisplayInfo, n_windows);
 | 
			
		||||
 | 
			
		||||
  tmp = list;
 | 
			
		||||
  i = 0;
 | 
			
		||||
  while (tmp != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      MetaWindow *window;
 | 
			
		||||
      gboolean ignoreable_sticky;
 | 
			
		||||
 | 
			
		||||
      window = tmp->data;
 | 
			
		||||
 | 
			
		||||
      ignoreable_sticky = window->on_all_workspaces &&
 | 
			
		||||
                          workspace != workspace->screen->active_workspace;
 | 
			
		||||
 | 
			
		||||
      if (window->skip_pager || 
 | 
			
		||||
          !meta_window_showing_on_its_workspace (window) ||
 | 
			
		||||
          window->unmaps_pending ||
 | 
			
		||||
          ignoreable_sticky)
 | 
			
		||||
        {
 | 
			
		||||
          --n_windows;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          windows[i] = meta_convert_meta_to_wnck (window, workspace->screen);
 | 
			
		||||
          i++;
 | 
			
		||||
        }
 | 
			
		||||
      tmp = tmp->next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_list_free (list);
 | 
			
		||||
 | 
			
		||||
  gtk_widget_get_allocation (widget, &allocation);
 | 
			
		||||
 | 
			
		||||
  wnck_draw_workspace (widget,
 | 
			
		||||
                       cr,
 | 
			
		||||
                       SELECT_OUTLINE_WIDTH,
 | 
			
		||||
                       SELECT_OUTLINE_WIDTH,
 | 
			
		||||
                       allocation.width - SELECT_OUTLINE_WIDTH * 2,
 | 
			
		||||
                       allocation.height - SELECT_OUTLINE_WIDTH * 2,
 | 
			
		||||
                       workspace->screen->rect.width,
 | 
			
		||||
                       workspace->screen->rect.height,
 | 
			
		||||
                       NULL,
 | 
			
		||||
                       (workspace->screen->active_workspace == workspace),
 | 
			
		||||
                       windows,
 | 
			
		||||
                       n_windows);
 | 
			
		||||
 | 
			
		||||
  g_free (windows);
 | 
			
		||||
  
 | 
			
		||||
  if (META_SELECT_WORKSPACE (widget)->selected)
 | 
			
		||||
    {
 | 
			
		||||
      GtkStyleContext *context;
 | 
			
		||||
      GdkRGBA color;
 | 
			
		||||
 | 
			
		||||
      context = gtk_widget_get_style_context (widget);
 | 
			
		||||
 | 
			
		||||
      gtk_style_context_set_state (context,
 | 
			
		||||
                                   gtk_widget_get_state_flags (widget));
 | 
			
		||||
 | 
			
		||||
      gtk_style_context_lookup_color (context, "color", &color);
 | 
			
		||||
 | 
			
		||||
      cairo_set_line_width (cr, SELECT_OUTLINE_WIDTH);
 | 
			
		||||
      cairo_set_source_rgb (cr, color.red, color.green, color.blue);
 | 
			
		||||
 | 
			
		||||
      cairo_rectangle (cr,
 | 
			
		||||
                       SELECT_OUTLINE_WIDTH / 2.0, SELECT_OUTLINE_WIDTH / 2.0,
 | 
			
		||||
                       allocation.width - SELECT_OUTLINE_WIDTH,
 | 
			
		||||
                       allocation.height - SELECT_OUTLINE_WIDTH);
 | 
			
		||||
      cairo_stroke (cr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,65 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/* Mutter tab popup window */
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2001 Havoc Pennington
 | 
			
		||||
 * Copyright (C) 2005 Elijah Newren
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_TABPOPUP_H
 | 
			
		||||
#define META_TABPOPUP_H
 | 
			
		||||
 | 
			
		||||
/* Don't include gtk.h or gdk.h here */
 | 
			
		||||
#include <meta/common.h>
 | 
			
		||||
#include <meta/boxes.h>
 | 
			
		||||
#include <X11/Xlib.h>
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include <gdk-pixbuf/gdk-pixbuf.h>
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaTabEntry MetaTabEntry;
 | 
			
		||||
typedef struct _MetaTabPopup MetaTabPopup;
 | 
			
		||||
typedef void *MetaTabEntryKey;
 | 
			
		||||
 | 
			
		||||
struct _MetaTabEntry
 | 
			
		||||
{
 | 
			
		||||
  MetaTabEntryKey  key;  
 | 
			
		||||
  const char      *title;
 | 
			
		||||
  GdkPixbuf       *icon;
 | 
			
		||||
  MetaRectangle    rect;
 | 
			
		||||
  MetaRectangle    inner_rect;
 | 
			
		||||
  guint            blank : 1;
 | 
			
		||||
  guint            hidden : 1;
 | 
			
		||||
  guint            demands_attention : 1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MetaTabPopup*   meta_ui_tab_popup_new          (const MetaTabEntry *entries,
 | 
			
		||||
                                                int                 screen_number,
 | 
			
		||||
                                                int                 entry_count,
 | 
			
		||||
                                                int                 width,
 | 
			
		||||
                                                gboolean            outline);
 | 
			
		||||
void            meta_ui_tab_popup_free         (MetaTabPopup       *popup);
 | 
			
		||||
void            meta_ui_tab_popup_set_showing  (MetaTabPopup       *popup,
 | 
			
		||||
                                                gboolean            showing);
 | 
			
		||||
void            meta_ui_tab_popup_forward      (MetaTabPopup       *popup);
 | 
			
		||||
void            meta_ui_tab_popup_backward     (MetaTabPopup       *popup);
 | 
			
		||||
MetaTabEntryKey meta_ui_tab_popup_get_selected (MetaTabPopup      *popup);
 | 
			
		||||
void            meta_ui_tab_popup_select       (MetaTabPopup       *popup,
 | 
			
		||||
                                                MetaTabEntryKey     key);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -1,315 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/* Mutter gradient test program */
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2002 Havoc Pennington
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.  */
 | 
			
		||||
 | 
			
		||||
#include <meta/gradient.h>
 | 
			
		||||
#include <gtk/gtk.h>
 | 
			
		||||
 | 
			
		||||
typedef void (* RenderGradientFunc) (cairo_t     *cr,
 | 
			
		||||
                                     int          width,
 | 
			
		||||
                                     int          height);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
draw_checkerboard (cairo_t *cr,
 | 
			
		||||
                   int      width,
 | 
			
		||||
                   int      height)
 | 
			
		||||
{
 | 
			
		||||
  gint i, j, xcount, ycount;
 | 
			
		||||
  GdkRGBA color1, color2;
 | 
			
		||||
  
 | 
			
		||||
#define CHECK_SIZE 10
 | 
			
		||||
#define SPACING 2  
 | 
			
		||||
 | 
			
		||||
  color1.red = 30000. / 65535.;
 | 
			
		||||
  color1.green = 30000. / 65535.;
 | 
			
		||||
  color1.blue = 30000. / 65535.;
 | 
			
		||||
  color1.alpha = 1.0;
 | 
			
		||||
 | 
			
		||||
  color2.red = 50000. / 65535.;
 | 
			
		||||
  color2.green = 50000. / 65535.;
 | 
			
		||||
  color2.blue = 50000. / 65535.;
 | 
			
		||||
  color2.alpha = 1.0;
 | 
			
		||||
 | 
			
		||||
  xcount = 0;
 | 
			
		||||
  i = SPACING;
 | 
			
		||||
  while (i < width)
 | 
			
		||||
    {
 | 
			
		||||
      j = SPACING;
 | 
			
		||||
      ycount = xcount % 2; /* start with even/odd depending on row */
 | 
			
		||||
      while (j < height)
 | 
			
		||||
	{
 | 
			
		||||
	  if (ycount % 2)
 | 
			
		||||
	    gdk_cairo_set_source_rgba (cr, &color1);
 | 
			
		||||
	  else
 | 
			
		||||
	    gdk_cairo_set_source_rgba (cr, &color2);
 | 
			
		||||
 | 
			
		||||
	  /* If we're outside event->area, this will do nothing.
 | 
			
		||||
	   * It might be mildly more efficient if we handled
 | 
			
		||||
	   * the clipping ourselves, but again we're feeling lazy.
 | 
			
		||||
	   */
 | 
			
		||||
          cairo_rectangle (cr, i, j, CHECK_SIZE, CHECK_SIZE);
 | 
			
		||||
          cairo_fill (cr);
 | 
			
		||||
 | 
			
		||||
	  j += CHECK_SIZE + SPACING;
 | 
			
		||||
	  ++ycount;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      i += CHECK_SIZE + SPACING;
 | 
			
		||||
      ++xcount;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
render_simple (cairo_t     *cr,
 | 
			
		||||
               int width, int height,
 | 
			
		||||
               MetaGradientType type,
 | 
			
		||||
               gboolean    with_alpha)
 | 
			
		||||
{
 | 
			
		||||
  GdkPixbuf *pixbuf;
 | 
			
		||||
  GdkRGBA from, to;
 | 
			
		||||
  
 | 
			
		||||
  gdk_rgba_parse (&from, "blue");
 | 
			
		||||
  gdk_rgba_parse (&to, "green");
 | 
			
		||||
 | 
			
		||||
  pixbuf = meta_gradient_create_simple (width, height,
 | 
			
		||||
                                        &from, &to,
 | 
			
		||||
                                        type);
 | 
			
		||||
 | 
			
		||||
  if (with_alpha)
 | 
			
		||||
    {
 | 
			
		||||
      const unsigned char alphas[] = { 0xff, 0xaa, 0x2f, 0x0, 0xcc, 0xff, 0xff };
 | 
			
		||||
      
 | 
			
		||||
      if (!gdk_pixbuf_get_has_alpha (pixbuf))
 | 
			
		||||
        {
 | 
			
		||||
          GdkPixbuf *new_pixbuf;
 | 
			
		||||
          
 | 
			
		||||
          new_pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
 | 
			
		||||
          g_object_unref (G_OBJECT (pixbuf));
 | 
			
		||||
          pixbuf = new_pixbuf;
 | 
			
		||||
        }
 | 
			
		||||
      
 | 
			
		||||
      meta_gradient_add_alpha (pixbuf,
 | 
			
		||||
                               alphas, G_N_ELEMENTS (alphas),
 | 
			
		||||
                               META_GRADIENT_HORIZONTAL);
 | 
			
		||||
      
 | 
			
		||||
      draw_checkerboard (cr , width, height);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
  gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
 | 
			
		||||
  cairo_rectangle (cr, 0, 0, width, height);
 | 
			
		||||
  cairo_fill (cr);
 | 
			
		||||
 | 
			
		||||
  g_object_unref (G_OBJECT (pixbuf));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
render_vertical_func (cairo_t *cr,
 | 
			
		||||
                      int width, int height)
 | 
			
		||||
{
 | 
			
		||||
  render_simple (cr, width, height, META_GRADIENT_VERTICAL, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
render_horizontal_func (cairo_t *cr,
 | 
			
		||||
                        int width, int height)
 | 
			
		||||
{
 | 
			
		||||
  render_simple (cr, width, height, META_GRADIENT_HORIZONTAL, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
render_diagonal_func (cairo_t *cr,
 | 
			
		||||
                      int width, int height)
 | 
			
		||||
{
 | 
			
		||||
  render_simple (cr, width, height, META_GRADIENT_DIAGONAL, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
render_diagonal_alpha_func (cairo_t *cr,
 | 
			
		||||
                            int width, int height)
 | 
			
		||||
{
 | 
			
		||||
  render_simple (cr, width, height, META_GRADIENT_DIAGONAL, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
render_multi (cairo_t     *cr,
 | 
			
		||||
              int width, int height,
 | 
			
		||||
              MetaGradientType type)
 | 
			
		||||
{
 | 
			
		||||
  GdkPixbuf *pixbuf;
 | 
			
		||||
#define N_COLORS 5
 | 
			
		||||
  GdkRGBA colors[N_COLORS];
 | 
			
		||||
 | 
			
		||||
  gdk_rgba_parse (&colors[0], "red");
 | 
			
		||||
  gdk_rgba_parse (&colors[1], "blue");
 | 
			
		||||
  gdk_rgba_parse (&colors[2], "orange");
 | 
			
		||||
  gdk_rgba_parse (&colors[3], "pink");
 | 
			
		||||
  gdk_rgba_parse (&colors[4], "green");
 | 
			
		||||
 | 
			
		||||
  pixbuf = meta_gradient_create_multi (width, height,
 | 
			
		||||
                                       colors, N_COLORS,
 | 
			
		||||
                                       type);
 | 
			
		||||
 | 
			
		||||
  gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
 | 
			
		||||
  cairo_rectangle (cr, 0, 0, width, height);
 | 
			
		||||
  cairo_fill (cr);
 | 
			
		||||
 | 
			
		||||
  g_object_unref (G_OBJECT (pixbuf));
 | 
			
		||||
#undef N_COLORS
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
render_vertical_multi_func (cairo_t *cr,
 | 
			
		||||
                            int width, int height)
 | 
			
		||||
{
 | 
			
		||||
  render_multi (cr, width, height, META_GRADIENT_VERTICAL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
render_horizontal_multi_func (cairo_t *cr,
 | 
			
		||||
                              int width, int height)
 | 
			
		||||
{
 | 
			
		||||
  render_multi (cr, width, height, META_GRADIENT_HORIZONTAL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
render_diagonal_multi_func (cairo_t *cr,
 | 
			
		||||
                            int width, int height)
 | 
			
		||||
{
 | 
			
		||||
  render_multi (cr, width, height, META_GRADIENT_DIAGONAL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
render_interwoven_func (cairo_t *cr,
 | 
			
		||||
                        int width, int height)
 | 
			
		||||
{
 | 
			
		||||
  GdkPixbuf *pixbuf;
 | 
			
		||||
#define N_COLORS 4
 | 
			
		||||
  GdkRGBA colors[N_COLORS];
 | 
			
		||||
 | 
			
		||||
  gdk_rgba_parse (&colors[0], "red");
 | 
			
		||||
  gdk_rgba_parse (&colors[1], "blue");
 | 
			
		||||
  gdk_rgba_parse (&colors[2], "pink");
 | 
			
		||||
  gdk_rgba_parse (&colors[3], "green");
 | 
			
		||||
 | 
			
		||||
  pixbuf = meta_gradient_create_interwoven (width, height,
 | 
			
		||||
                                            colors, height / 10,
 | 
			
		||||
                                            colors + 2, height / 14);
 | 
			
		||||
 | 
			
		||||
  gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
 | 
			
		||||
  cairo_rectangle (cr, 0, 0, width, height);
 | 
			
		||||
  cairo_fill (cr);
 | 
			
		||||
 | 
			
		||||
  g_object_unref (G_OBJECT (pixbuf));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
draw_callback (GtkWidget *widget,
 | 
			
		||||
               cairo_t   *cr,
 | 
			
		||||
               gpointer   data)
 | 
			
		||||
{
 | 
			
		||||
  RenderGradientFunc func = data;
 | 
			
		||||
  GtkStyleContext *style;
 | 
			
		||||
  GdkRGBA color;
 | 
			
		||||
 | 
			
		||||
  style = gtk_widget_get_style_context (widget);
 | 
			
		||||
 | 
			
		||||
  gtk_style_context_save (style);
 | 
			
		||||
  gtk_style_context_set_state (style, gtk_widget_get_state_flags (widget));
 | 
			
		||||
  gtk_style_context_lookup_color (style, "foreground-color", &color);
 | 
			
		||||
  gtk_style_context_restore (style);
 | 
			
		||||
 | 
			
		||||
  gdk_cairo_set_source_rgba (cr, &color);
 | 
			
		||||
 | 
			
		||||
  (* func) (cr,
 | 
			
		||||
            gtk_widget_get_allocated_width (widget),
 | 
			
		||||
            gtk_widget_get_allocated_height (widget));
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GtkWidget*
 | 
			
		||||
create_gradient_window (const char *title,
 | 
			
		||||
                        RenderGradientFunc func)
 | 
			
		||||
{
 | 
			
		||||
  GtkWidget *window;
 | 
			
		||||
  GtkWidget *drawing_area;
 | 
			
		||||
 | 
			
		||||
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 | 
			
		||||
 | 
			
		||||
  gtk_window_set_title (GTK_WINDOW (window), title);
 | 
			
		||||
  
 | 
			
		||||
  drawing_area = gtk_drawing_area_new ();
 | 
			
		||||
 | 
			
		||||
  gtk_widget_set_size_request (drawing_area, 1, 1);
 | 
			
		||||
 | 
			
		||||
  gtk_window_set_default_size (GTK_WINDOW (window), 175, 175);
 | 
			
		||||
  
 | 
			
		||||
  g_signal_connect (G_OBJECT (drawing_area),
 | 
			
		||||
                    "draw",
 | 
			
		||||
                    G_CALLBACK (draw_callback),
 | 
			
		||||
                    func);
 | 
			
		||||
 | 
			
		||||
  gtk_container_add (GTK_CONTAINER (window), drawing_area);
 | 
			
		||||
 | 
			
		||||
  gtk_widget_show_all (window);
 | 
			
		||||
  
 | 
			
		||||
  return window;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_gradient_test (void)
 | 
			
		||||
{
 | 
			
		||||
  create_gradient_window ("Simple vertical",
 | 
			
		||||
                          render_vertical_func);
 | 
			
		||||
 | 
			
		||||
  create_gradient_window ("Simple horizontal",
 | 
			
		||||
                          render_horizontal_func);
 | 
			
		||||
 | 
			
		||||
  create_gradient_window ("Simple diagonal",
 | 
			
		||||
                          render_diagonal_func);
 | 
			
		||||
 | 
			
		||||
  create_gradient_window ("Multi vertical",
 | 
			
		||||
                          render_vertical_multi_func);
 | 
			
		||||
 | 
			
		||||
  create_gradient_window ("Multi horizontal",
 | 
			
		||||
                          render_horizontal_multi_func);
 | 
			
		||||
 | 
			
		||||
  create_gradient_window ("Multi diagonal",
 | 
			
		||||
                          render_diagonal_multi_func);
 | 
			
		||||
 | 
			
		||||
  create_gradient_window ("Interwoven",
 | 
			
		||||
                          render_interwoven_func);
 | 
			
		||||
 | 
			
		||||
  create_gradient_window ("Simple diagonal with horizontal multi alpha",
 | 
			
		||||
                          render_diagonal_alpha_func);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main (int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
  gtk_init (&argc, &argv);
 | 
			
		||||
 | 
			
		||||
  meta_gradient_test ();
 | 
			
		||||
 | 
			
		||||
  gtk_main ();
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										6802
									
								
								src/ui/theme.c
									
									
									
									
									
								
							
							
						
						
									
										6802
									
								
								src/ui/theme.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										446
									
								
								src/ui/ui.c
									
									
									
									
									
								
							
							
						
						
									
										446
									
								
								src/ui/ui.c
									
									
									
									
									
								
							@@ -22,11 +22,8 @@
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include <meta/prefs.h>
 | 
			
		||||
#include "ui.h"
 | 
			
		||||
#include "frames.h"
 | 
			
		||||
#include <meta/util.h>
 | 
			
		||||
#include "menu.h"
 | 
			
		||||
#include "core.h"
 | 
			
		||||
#include "theme-private.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
@@ -41,7 +38,6 @@ struct _MetaUI
 | 
			
		||||
{
 | 
			
		||||
  Display *xdisplay;
 | 
			
		||||
  Screen *xscreen;
 | 
			
		||||
  MetaFrames *frames;
 | 
			
		||||
 | 
			
		||||
  /* For double-click tracking */
 | 
			
		||||
  gint button_click_number;
 | 
			
		||||
@@ -56,11 +52,6 @@ meta_ui_init (void)
 | 
			
		||||
{
 | 
			
		||||
  if (!gtk_init_check (NULL, NULL))
 | 
			
		||||
    meta_fatal ("Unable to open X display %s\n", XDisplayName (NULL));
 | 
			
		||||
 | 
			
		||||
  /* We need to be able to fully trust that the window and monitor sizes
 | 
			
		||||
     that Gdk reports corresponds to the X ones, so we disable the automatic
 | 
			
		||||
     scale handling */
 | 
			
		||||
  gdk_x11_display_set_window_scale (gdk_display_get_default (), 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Display*
 | 
			
		||||
@@ -75,162 +66,6 @@ meta_ui_get_screen_number (void)
 | 
			
		||||
  return gdk_screen_get_number (gdk_screen_get_default ());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* For XInput2 */
 | 
			
		||||
#include "display-private.h"
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
is_input_event (XEvent *event)
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay *display = meta_get_display ();
 | 
			
		||||
 | 
			
		||||
  return (event->type == GenericEvent &&
 | 
			
		||||
          event->xcookie.extension == display->xinput_opcode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* We do some of our event handling in frames.c, which expects
 | 
			
		||||
 * GDK events delivered by GTK+.  However, since the transition to
 | 
			
		||||
 * client side windows, we can't let GDK see button events, since the
 | 
			
		||||
 * client-side tracking of implicit and explicit grabs it does will
 | 
			
		||||
 * get confused by our direct use of X grabs in the core code.
 | 
			
		||||
 *
 | 
			
		||||
 * So we do a very minimal GDK => GTK event conversion here and send on the
 | 
			
		||||
 * events we care about, and then filter them out so they don't go
 | 
			
		||||
 * through the normal GDK event handling.
 | 
			
		||||
 *
 | 
			
		||||
 * To reduce the amount of code, the only events fields filled out
 | 
			
		||||
 * below are the ones that frames.c uses. If frames.c is modified to
 | 
			
		||||
 * use more fields, more fields need to be filled out below.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
maybe_redirect_mouse_event (XEvent *xevent)
 | 
			
		||||
{
 | 
			
		||||
  GdkDisplay *gdisplay;
 | 
			
		||||
  GdkDeviceManager *gmanager;
 | 
			
		||||
  GdkDevice *gdevice;
 | 
			
		||||
  MetaUI *ui;
 | 
			
		||||
  GdkEvent *gevent;
 | 
			
		||||
  GdkWindow *gdk_window;
 | 
			
		||||
  Window window;
 | 
			
		||||
  XIEvent *xev;
 | 
			
		||||
  XIDeviceEvent *xev_d = NULL;
 | 
			
		||||
  XIEnterEvent *xev_e = NULL;
 | 
			
		||||
 | 
			
		||||
  if (!is_input_event (xevent))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  xev = (XIEvent *) xevent->xcookie.data;
 | 
			
		||||
 | 
			
		||||
  switch (xev->evtype)
 | 
			
		||||
    {
 | 
			
		||||
    case XI_ButtonPress:
 | 
			
		||||
    case XI_ButtonRelease:
 | 
			
		||||
    case XI_Motion:
 | 
			
		||||
      xev_d = (XIDeviceEvent *) xev;
 | 
			
		||||
      window = xev_d->event;
 | 
			
		||||
      break;
 | 
			
		||||
    case XI_Enter:
 | 
			
		||||
    case XI_Leave:
 | 
			
		||||
      xev_e = (XIEnterEvent *) xev;
 | 
			
		||||
      window = xev_e->event;
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  gdisplay = gdk_x11_lookup_xdisplay (xev->display);
 | 
			
		||||
  ui = g_object_get_data (G_OBJECT (gdisplay), "meta-ui");
 | 
			
		||||
  if (!ui)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  gdk_window = gdk_x11_window_lookup_for_display (gdisplay, window);
 | 
			
		||||
  if (gdk_window == NULL)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  gmanager = gdk_display_get_device_manager (gdisplay);
 | 
			
		||||
  gdevice = gdk_x11_device_manager_lookup (gmanager, META_VIRTUAL_CORE_POINTER_ID);
 | 
			
		||||
 | 
			
		||||
  /* If GDK already thinks it has a grab, we better let it see events; this
 | 
			
		||||
   * is the menu-navigation case and events need to get sent to the appropriate
 | 
			
		||||
   * (client-side) subwindow for individual menu items.
 | 
			
		||||
   */
 | 
			
		||||
  if (gdk_display_device_is_grabbed (gdisplay, gdevice))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  switch (xev->evtype)
 | 
			
		||||
    {
 | 
			
		||||
    case XI_ButtonPress:
 | 
			
		||||
    case XI_ButtonRelease:
 | 
			
		||||
      if (xev_d->evtype == XI_ButtonPress)
 | 
			
		||||
        {
 | 
			
		||||
          GtkSettings *settings = gtk_settings_get_default ();
 | 
			
		||||
          int double_click_time;
 | 
			
		||||
          int double_click_distance;
 | 
			
		||||
 | 
			
		||||
          g_object_get (settings,
 | 
			
		||||
                        "gtk-double-click-time", &double_click_time,
 | 
			
		||||
                        "gtk-double-click-distance", &double_click_distance,
 | 
			
		||||
                        NULL);
 | 
			
		||||
 | 
			
		||||
          if (xev_d->detail == ui->button_click_number &&
 | 
			
		||||
              xev_d->event == ui->button_click_window &&
 | 
			
		||||
              xev_d->time < ui->button_click_time + double_click_time &&
 | 
			
		||||
              ABS (xev_d->event_x - ui->button_click_x) <= double_click_distance &&
 | 
			
		||||
              ABS (xev_d->event_y - ui->button_click_y) <= double_click_distance)
 | 
			
		||||
            {
 | 
			
		||||
              gevent = gdk_event_new (GDK_2BUTTON_PRESS);
 | 
			
		||||
 | 
			
		||||
              ui->button_click_number = 0;
 | 
			
		||||
            }
 | 
			
		||||
          else
 | 
			
		||||
            {
 | 
			
		||||
              gevent = gdk_event_new (GDK_BUTTON_PRESS);
 | 
			
		||||
              ui->button_click_number = xev_d->detail;
 | 
			
		||||
              ui->button_click_window = xev_d->event;
 | 
			
		||||
              ui->button_click_time = xev_d->time;
 | 
			
		||||
              ui->button_click_x = xev_d->event_x;
 | 
			
		||||
              ui->button_click_y = xev_d->event_y;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          gevent = gdk_event_new (GDK_BUTTON_RELEASE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      gevent->button.window = g_object_ref (gdk_window);
 | 
			
		||||
      gevent->button.button = xev_d->detail;
 | 
			
		||||
      gevent->button.time = xev_d->time;
 | 
			
		||||
      gevent->button.x = xev_d->event_x;
 | 
			
		||||
      gevent->button.y = xev_d->event_y;
 | 
			
		||||
      gevent->button.x_root = xev_d->root_x;
 | 
			
		||||
      gevent->button.y_root = xev_d->root_y;
 | 
			
		||||
 | 
			
		||||
      break;
 | 
			
		||||
    case XI_Motion:
 | 
			
		||||
      gevent = gdk_event_new (GDK_MOTION_NOTIFY);
 | 
			
		||||
      gevent->motion.type = GDK_MOTION_NOTIFY;
 | 
			
		||||
      gevent->motion.window = g_object_ref (gdk_window);
 | 
			
		||||
      break;
 | 
			
		||||
    case XI_Enter:
 | 
			
		||||
    case XI_Leave:
 | 
			
		||||
      gevent = gdk_event_new (xev_e->evtype == XI_Enter ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY);
 | 
			
		||||
      gevent->crossing.window = g_object_ref (gdk_window);
 | 
			
		||||
      gevent->crossing.x = xev_e->event_x;
 | 
			
		||||
      gevent->crossing.y = xev_e->event_y;
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      g_assert_not_reached ();
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* If we've gotten here, we've created the gdk_event and should send it on */
 | 
			
		||||
  gdk_event_set_device (gevent, gdevice);
 | 
			
		||||
  gtk_main_do_event (gevent);
 | 
			
		||||
  gdk_event_free (gevent);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct _EventFunc EventFunc;
 | 
			
		||||
 | 
			
		||||
struct _EventFunc
 | 
			
		||||
@@ -248,8 +83,7 @@ filter_func (GdkXEvent *xevent,
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (ef != NULL, GDK_FILTER_CONTINUE);
 | 
			
		||||
 | 
			
		||||
  if ((* ef->func) (xevent, ef->data) ||
 | 
			
		||||
      maybe_redirect_mouse_event (xevent))
 | 
			
		||||
  if ((* ef->func) (xevent, ef->data))
 | 
			
		||||
    return GDK_FILTER_REMOVE;
 | 
			
		||||
  else
 | 
			
		||||
    return GDK_FILTER_CONTINUE;
 | 
			
		||||
@@ -297,12 +131,6 @@ meta_ui_new (Display *xdisplay,
 | 
			
		||||
  gdisplay = gdk_x11_lookup_xdisplay (xdisplay);
 | 
			
		||||
  g_assert (gdisplay == gdk_display_get_default ());
 | 
			
		||||
 | 
			
		||||
  ui->frames = meta_frames_new (XScreenNumberOfScreen (screen));
 | 
			
		||||
  /* This does not actually show any widget. MetaFrames has been hacked so
 | 
			
		||||
   * that showing it doesn't actually do anything. But we need the flags
 | 
			
		||||
   * set for GTK to deliver events properly. */
 | 
			
		||||
  gtk_widget_show (GTK_WIDGET (ui->frames));
 | 
			
		||||
 | 
			
		||||
  g_object_set_data (G_OBJECT (gdisplay), "meta-ui", ui);
 | 
			
		||||
 | 
			
		||||
  return ui;
 | 
			
		||||
@@ -313,33 +141,12 @@ meta_ui_free (MetaUI *ui)
 | 
			
		||||
{
 | 
			
		||||
  GdkDisplay *gdisplay;
 | 
			
		||||
 | 
			
		||||
  gtk_widget_destroy (GTK_WIDGET (ui->frames));
 | 
			
		||||
 | 
			
		||||
  gdisplay = gdk_x11_lookup_xdisplay (ui->xdisplay);
 | 
			
		||||
  g_object_set_data (G_OBJECT (gdisplay), "meta-ui", NULL);
 | 
			
		||||
 | 
			
		||||
  g_free (ui);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_ui_get_frame_mask (MetaUI  *ui,
 | 
			
		||||
                        Window   frame_xwindow,
 | 
			
		||||
                        guint    width,
 | 
			
		||||
                        guint    height,
 | 
			
		||||
                        cairo_t *cr)
 | 
			
		||||
{
 | 
			
		||||
  meta_frames_get_mask (ui->frames, frame_xwindow, width, height, cr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_ui_get_frame_borders (MetaUI *ui,
 | 
			
		||||
                           Window frame_xwindow,
 | 
			
		||||
                           MetaFrameBorders *borders)
 | 
			
		||||
{
 | 
			
		||||
  meta_frames_get_borders (ui->frames, frame_xwindow,
 | 
			
		||||
                           borders);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Window
 | 
			
		||||
meta_ui_create_frame_window (MetaUI *ui,
 | 
			
		||||
                             Display *xdisplay,
 | 
			
		||||
@@ -351,72 +158,13 @@ meta_ui_create_frame_window (MetaUI *ui,
 | 
			
		||||
			     gint screen_no,
 | 
			
		||||
                             gulong *create_serial)
 | 
			
		||||
{
 | 
			
		||||
  GdkDisplay *display = gdk_x11_lookup_xdisplay (xdisplay);
 | 
			
		||||
  GdkScreen *screen = gdk_display_get_screen (display, screen_no);
 | 
			
		||||
  GdkWindowAttr attrs;
 | 
			
		||||
  gint attributes_mask;
 | 
			
		||||
  GdkWindow *window;
 | 
			
		||||
  GdkVisual *visual;
 | 
			
		||||
  
 | 
			
		||||
  /* 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.
 | 
			
		||||
   */
 | 
			
		||||
  if (!xvisual)
 | 
			
		||||
    visual = gdk_screen_get_system_visual (screen);
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      visual = gdk_x11_screen_lookup_visual (screen,
 | 
			
		||||
                                             XVisualIDFromVisual (xvisual));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  attrs.title = NULL;
 | 
			
		||||
 | 
			
		||||
  /* frame.c is going to replace the event mask immediately, but
 | 
			
		||||
   * we still have to set it here to let GDK know what it is.
 | 
			
		||||
   */
 | 
			
		||||
  attrs.event_mask =
 | 
			
		||||
    GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
 | 
			
		||||
    GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK |
 | 
			
		||||
    GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK;
 | 
			
		||||
  attrs.x = x;
 | 
			
		||||
  attrs.y = y;
 | 
			
		||||
  attrs.wclass = GDK_INPUT_OUTPUT;
 | 
			
		||||
  attrs.visual = visual;
 | 
			
		||||
  attrs.window_type = GDK_WINDOW_CHILD;
 | 
			
		||||
  attrs.cursor = NULL;
 | 
			
		||||
  attrs.wmclass_name = NULL;
 | 
			
		||||
  attrs.wmclass_class = NULL;
 | 
			
		||||
  attrs.override_redirect = FALSE;
 | 
			
		||||
 | 
			
		||||
  attrs.width  = width;
 | 
			
		||||
  attrs.height = height;
 | 
			
		||||
 | 
			
		||||
  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
 | 
			
		||||
 | 
			
		||||
  /* We make an assumption that gdk_window_new() is going to call
 | 
			
		||||
   * XCreateWindow as it's first operation; this seems to be true currently
 | 
			
		||||
   * as long as you pass in a colormap.
 | 
			
		||||
   */
 | 
			
		||||
  if (create_serial)
 | 
			
		||||
    *create_serial = XNextRequest (xdisplay);
 | 
			
		||||
  window =
 | 
			
		||||
    gdk_window_new (gdk_screen_get_root_window(screen),
 | 
			
		||||
		    &attrs, attributes_mask);
 | 
			
		||||
 | 
			
		||||
  gdk_window_resize (window, width, height);
 | 
			
		||||
  
 | 
			
		||||
  meta_frames_manage_window (ui->frames, GDK_WINDOW_XID (window), window);
 | 
			
		||||
 | 
			
		||||
  return GDK_WINDOW_XID (window);
 | 
			
		||||
  return None;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_ui_destroy_frame_window (MetaUI *ui,
 | 
			
		||||
			      Window  xwindow)
 | 
			
		||||
{
 | 
			
		||||
  meta_frames_unmanage_window (ui->frames, xwindow);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -427,83 +175,6 @@ meta_ui_move_resize_frame (MetaUI *ui,
 | 
			
		||||
			   int width,
 | 
			
		||||
			   int height)
 | 
			
		||||
{
 | 
			
		||||
  meta_frames_move_resize_frame (ui->frames, frame, x, y, width, height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_ui_map_frame   (MetaUI *ui,
 | 
			
		||||
                     Window  xwindow)
 | 
			
		||||
{
 | 
			
		||||
  GdkWindow *window;
 | 
			
		||||
  GdkDisplay *display;
 | 
			
		||||
 | 
			
		||||
  display = gdk_x11_lookup_xdisplay (ui->xdisplay);
 | 
			
		||||
  window = gdk_x11_window_lookup_for_display (display, xwindow);
 | 
			
		||||
 | 
			
		||||
  if (window)
 | 
			
		||||
    gdk_window_show_unraised (window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_ui_unmap_frame (MetaUI *ui,
 | 
			
		||||
                     Window  xwindow)
 | 
			
		||||
{
 | 
			
		||||
  GdkWindow *window;
 | 
			
		||||
  GdkDisplay *display;
 | 
			
		||||
 | 
			
		||||
  display = gdk_x11_lookup_xdisplay (ui->xdisplay);
 | 
			
		||||
  window = gdk_x11_window_lookup_for_display (display, xwindow);
 | 
			
		||||
 | 
			
		||||
  if (window)
 | 
			
		||||
    gdk_window_hide (window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_ui_unflicker_frame_bg (MetaUI *ui,
 | 
			
		||||
                            Window  xwindow,
 | 
			
		||||
                            int     target_width,
 | 
			
		||||
                            int     target_height)
 | 
			
		||||
{
 | 
			
		||||
  meta_frames_unflicker_bg (ui->frames, xwindow,
 | 
			
		||||
                            target_width, target_height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_ui_update_frame_style (MetaUI  *ui,
 | 
			
		||||
                            Window   xwindow)
 | 
			
		||||
{
 | 
			
		||||
  meta_frames_update_frame_style (ui->frames, xwindow);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_ui_repaint_frame (MetaUI *ui,
 | 
			
		||||
                       Window xwindow)
 | 
			
		||||
{
 | 
			
		||||
  meta_frames_repaint_frame (ui->frames, xwindow);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_ui_reset_frame_bg (MetaUI *ui,
 | 
			
		||||
                        Window xwindow)
 | 
			
		||||
{
 | 
			
		||||
  meta_frames_reset_bg (ui->frames, xwindow);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cairo_region_t *
 | 
			
		||||
meta_ui_get_frame_bounds (MetaUI  *ui,
 | 
			
		||||
                          Window   xwindow,
 | 
			
		||||
                          int      window_width,
 | 
			
		||||
                          int      window_height)
 | 
			
		||||
{
 | 
			
		||||
  return meta_frames_get_frame_bounds (ui->frames, xwindow,
 | 
			
		||||
                                       window_width, window_height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_ui_queue_frame_draw (MetaUI *ui,
 | 
			
		||||
                          Window xwindow)
 | 
			
		||||
{
 | 
			
		||||
  meta_frames_queue_draw (ui->frames, xwindow);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -511,41 +182,12 @@ meta_ui_set_frame_title (MetaUI     *ui,
 | 
			
		||||
                         Window      xwindow,
 | 
			
		||||
                         const char *title)
 | 
			
		||||
{
 | 
			
		||||
  meta_frames_set_title (ui->frames, xwindow, title);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaWindowMenu*
 | 
			
		||||
meta_ui_window_menu_new  (MetaUI             *ui,
 | 
			
		||||
                          Window              client_xwindow,
 | 
			
		||||
                          MetaMenuOp          ops,
 | 
			
		||||
                          MetaMenuOp          insensitive,
 | 
			
		||||
                          unsigned long       active_workspace,
 | 
			
		||||
                          int                 n_workspaces,
 | 
			
		||||
                          MetaWindowMenuFunc  func,
 | 
			
		||||
                          gpointer            data)
 | 
			
		||||
{
 | 
			
		||||
  return meta_window_menu_new (ui->frames,
 | 
			
		||||
                               ops, insensitive,
 | 
			
		||||
                               client_xwindow,
 | 
			
		||||
                               active_workspace,
 | 
			
		||||
                               n_workspaces,
 | 
			
		||||
                               func, data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_ui_window_menu_popup (MetaWindowMenu     *menu,
 | 
			
		||||
                           int                 root_x,
 | 
			
		||||
                           int                 root_y,
 | 
			
		||||
                           int                 button,
 | 
			
		||||
                           guint32             timestamp)
 | 
			
		||||
meta_ui_update_frame_style (MetaUI  *ui,
 | 
			
		||||
                            Window   xwindow)
 | 
			
		||||
{
 | 
			
		||||
  meta_window_menu_popup (menu, root_x, root_y, button, timestamp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_ui_window_menu_free (MetaWindowMenu *menu)
 | 
			
		||||
{
 | 
			
		||||
  meta_window_menu_free (menu);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GdkPixbuf*
 | 
			
		||||
@@ -725,63 +367,7 @@ meta_ui_theme_get_frame_borders (MetaUI *ui,
 | 
			
		||||
                                 MetaFrameFlags     flags,
 | 
			
		||||
                                 MetaFrameBorders  *borders)
 | 
			
		||||
{
 | 
			
		||||
  int text_height;
 | 
			
		||||
  GtkStyleContext *style = NULL;
 | 
			
		||||
  PangoContext *context;
 | 
			
		||||
  const PangoFontDescription *font_desc;
 | 
			
		||||
  PangoFontDescription *free_font_desc = NULL;
 | 
			
		||||
 | 
			
		||||
  if (meta_ui_have_a_theme ())
 | 
			
		||||
    {
 | 
			
		||||
      context = gtk_widget_get_pango_context (GTK_WIDGET (ui->frames));
 | 
			
		||||
      font_desc = meta_prefs_get_titlebar_font ();
 | 
			
		||||
 | 
			
		||||
      if (!font_desc)
 | 
			
		||||
        {
 | 
			
		||||
          GdkDisplay *display = gdk_x11_lookup_xdisplay (ui->xdisplay);
 | 
			
		||||
          GdkScreen *screen = gdk_display_get_screen (display, XScreenNumberOfScreen (ui->xscreen));
 | 
			
		||||
          GtkWidgetPath *widget_path;
 | 
			
		||||
 | 
			
		||||
          style = gtk_style_context_new ();
 | 
			
		||||
          gtk_style_context_set_screen (style, screen);
 | 
			
		||||
          widget_path = gtk_widget_path_new ();
 | 
			
		||||
          gtk_widget_path_append_type (widget_path, GTK_TYPE_WINDOW);
 | 
			
		||||
          gtk_style_context_set_path (style, widget_path);
 | 
			
		||||
          gtk_widget_path_free (widget_path);
 | 
			
		||||
 | 
			
		||||
          gtk_style_context_get (style, GTK_STATE_FLAG_NORMAL, "font", &free_font_desc, NULL);
 | 
			
		||||
          font_desc = (const PangoFontDescription *) free_font_desc;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      text_height = meta_pango_font_desc_get_text_height (font_desc, context);
 | 
			
		||||
 | 
			
		||||
      meta_theme_get_frame_borders (meta_theme_get_current (),
 | 
			
		||||
                                    type, text_height, flags,
 | 
			
		||||
                                    borders);
 | 
			
		||||
 | 
			
		||||
      if (free_font_desc)
 | 
			
		||||
        pango_font_description_free (free_font_desc);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      meta_frame_borders_clear (borders);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (style != NULL)
 | 
			
		||||
    g_object_unref (style);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_ui_set_current_theme (const char *name)
 | 
			
		||||
{
 | 
			
		||||
  meta_theme_set_current (name);
 | 
			
		||||
  meta_invalidate_default_icons ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_ui_have_a_theme (void)
 | 
			
		||||
{
 | 
			
		||||
  return meta_theme_get_current () != NULL;
 | 
			
		||||
  meta_frame_borders_clear (borders);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -974,33 +560,13 @@ meta_ui_parse_modifier (const char          *accel,
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_ui_window_is_widget (MetaUI *ui,
 | 
			
		||||
                          Window  xwindow)
 | 
			
		||||
{
 | 
			
		||||
  GdkDisplay *display;
 | 
			
		||||
  GdkWindow *window;
 | 
			
		||||
 | 
			
		||||
  display = gdk_x11_lookup_xdisplay (ui->xdisplay);
 | 
			
		||||
  window = gdk_x11_window_lookup_for_display (display, xwindow);
 | 
			
		||||
 | 
			
		||||
  if (window)
 | 
			
		||||
    {
 | 
			
		||||
      void *user_data = NULL;
 | 
			
		||||
      gdk_window_get_user_data (window, &user_data);
 | 
			
		||||
      return user_data != NULL && user_data != ui->frames;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
meta_ui_get_drag_threshold (MetaUI *ui)
 | 
			
		||||
{
 | 
			
		||||
  GtkSettings *settings;
 | 
			
		||||
  int threshold;
 | 
			
		||||
 | 
			
		||||
  settings = gtk_widget_get_settings (GTK_WIDGET (ui->frames));
 | 
			
		||||
  settings = gtk_settings_get_default ();
 | 
			
		||||
 | 
			
		||||
  threshold = 8;
 | 
			
		||||
  g_object_get (G_OBJECT (settings), "gtk-dnd-drag-threshold", &threshold, NULL);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										59
									
								
								src/ui/ui.h
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								src/ui/ui.h
									
									
									
									
									
								
							@@ -61,16 +61,6 @@ void meta_ui_theme_get_frame_borders (MetaUI *ui,
 | 
			
		||||
                                      MetaFrameType      type,
 | 
			
		||||
                                      MetaFrameFlags     flags,
 | 
			
		||||
                                      MetaFrameBorders *borders);
 | 
			
		||||
void meta_ui_get_frame_borders (MetaUI *ui,
 | 
			
		||||
                                Window frame_xwindow,
 | 
			
		||||
                                MetaFrameBorders *borders);
 | 
			
		||||
 | 
			
		||||
void meta_ui_get_frame_mask (MetaUI *ui,
 | 
			
		||||
                             Window frame_xwindow,
 | 
			
		||||
                             guint width,
 | 
			
		||||
                             guint height,
 | 
			
		||||
                             cairo_t *cr);
 | 
			
		||||
 | 
			
		||||
Window meta_ui_create_frame_window (MetaUI *ui,
 | 
			
		||||
                                    Display *xdisplay,
 | 
			
		||||
                                    Visual *xvisual,
 | 
			
		||||
@@ -88,54 +78,12 @@ void meta_ui_move_resize_frame (MetaUI *ui,
 | 
			
		||||
				int y,
 | 
			
		||||
				int width,
 | 
			
		||||
				int height);
 | 
			
		||||
 | 
			
		||||
/* GDK insists on tracking map/unmap */
 | 
			
		||||
void meta_ui_map_frame   (MetaUI *ui,
 | 
			
		||||
                          Window  xwindow);
 | 
			
		||||
void meta_ui_unmap_frame (MetaUI *ui,
 | 
			
		||||
                          Window  xwindow);
 | 
			
		||||
 | 
			
		||||
void meta_ui_unflicker_frame_bg (MetaUI *ui,
 | 
			
		||||
                                 Window  xwindow,
 | 
			
		||||
                                 int     target_width,
 | 
			
		||||
                                 int     target_height);
 | 
			
		||||
void meta_ui_reset_frame_bg     (MetaUI *ui,
 | 
			
		||||
                                 Window  xwindow);
 | 
			
		||||
 | 
			
		||||
cairo_region_t *meta_ui_get_frame_bounds (MetaUI  *ui,
 | 
			
		||||
                                          Window   xwindow,
 | 
			
		||||
                                          int      window_width,
 | 
			
		||||
                                          int      window_height);
 | 
			
		||||
 | 
			
		||||
void meta_ui_queue_frame_draw (MetaUI *ui,
 | 
			
		||||
                               Window xwindow);
 | 
			
		||||
 | 
			
		||||
void meta_ui_set_frame_title (MetaUI *ui,
 | 
			
		||||
                              Window xwindow,
 | 
			
		||||
                              const char *title);
 | 
			
		||||
 | 
			
		||||
void meta_ui_update_frame_style (MetaUI  *ui,
 | 
			
		||||
                                 Window   window);
 | 
			
		||||
 | 
			
		||||
void meta_ui_repaint_frame (MetaUI *ui,
 | 
			
		||||
                            Window xwindow);
 | 
			
		||||
 | 
			
		||||
MetaWindowMenu* meta_ui_window_menu_new   (MetaUI             *ui,
 | 
			
		||||
                                           Window              client_xwindow,
 | 
			
		||||
                                           MetaMenuOp          ops,
 | 
			
		||||
                                           MetaMenuOp          insensitive,
 | 
			
		||||
                                           unsigned long       active_workspace,
 | 
			
		||||
                                           int                 n_workspaces,
 | 
			
		||||
                                           MetaWindowMenuFunc  func,
 | 
			
		||||
                                           gpointer            data);
 | 
			
		||||
void            meta_ui_window_menu_popup (MetaWindowMenu     *menu,
 | 
			
		||||
                                           int                 root_x,
 | 
			
		||||
                                           int                 root_y,
 | 
			
		||||
                                           int                 button,
 | 
			
		||||
                                           guint32             timestamp);
 | 
			
		||||
void            meta_ui_window_menu_free  (MetaWindowMenu     *menu);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* FIXME these lack a display arg */
 | 
			
		||||
GdkPixbuf* meta_gdk_pixbuf_get_from_pixmap (Pixmap       xpixmap,
 | 
			
		||||
                                            int          src_x,
 | 
			
		||||
@@ -152,9 +100,6 @@ gboolean  meta_ui_window_should_not_cause_focus (Display *xdisplay,
 | 
			
		||||
char*     meta_text_property_to_utf8 (Display             *xdisplay,
 | 
			
		||||
                                      const XTextProperty *prop);
 | 
			
		||||
 | 
			
		||||
void     meta_ui_set_current_theme (const char *name);
 | 
			
		||||
gboolean meta_ui_have_a_theme      (void);
 | 
			
		||||
 | 
			
		||||
/* Not a real key symbol but means "key above the tab key"; this is
 | 
			
		||||
 * used as the default keybinding for cycle_group.
 | 
			
		||||
 * 0x2xxxxxxx is a range not used by GDK or X. the remaining digits are
 | 
			
		||||
@@ -171,13 +116,9 @@ gboolean meta_ui_parse_modifier    (const char          *accel,
 | 
			
		||||
/* Caller responsible for freeing return string of meta_ui_accelerator_name! */
 | 
			
		||||
gchar*   meta_ui_accelerator_name  (unsigned int        keysym,
 | 
			
		||||
                                    MetaVirtualModifier mask);
 | 
			
		||||
gboolean meta_ui_window_is_widget (MetaUI *ui,
 | 
			
		||||
                                   Window  xwindow);
 | 
			
		||||
 | 
			
		||||
int      meta_ui_get_drag_threshold       (MetaUI *ui);
 | 
			
		||||
 | 
			
		||||
MetaUIDirection meta_ui_get_direction (void);
 | 
			
		||||
 | 
			
		||||
#include "tabpopup.h"
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user