~ubuntu-branches/ubuntu/saucy/mutter/saucy

« back to all changes in this revision

Viewing changes to src/ui/frames.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2010-10-01 11:39:17 UTC
  • mfrom: (1.2.1 upstream) (10.1.20 maverick)
  • Revision ID: james.westby@ubuntu.com-20101001113917-d1c9zswwaehyn07e
Tags: 2.31.5-0ubuntu9
* debian/patches/20_unity_no_3D_detection.patch:
  - add an extra string in fallback mode to guide user in live session
    (LP: #651085)

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
#include <math.h>
28
28
#include "boxes.h"
29
29
#include "frames.h"
 
30
#include "region.h"
30
31
#include "util.h"
31
32
#include "core.h"
32
33
#include "menu.h"
35
36
#include "prefs.h"
36
37
#include "ui.h"
37
38
 
 
39
#include "gtk-compat.h"
 
40
#include "gdk-compat.h"
 
41
 
38
42
#ifdef HAVE_SHAPE
39
43
#include <X11/extensions/shape.h>
40
44
#endif
41
45
 
42
46
#define DEFAULT_INNER_BUTTON_BORDER 3
43
47
 
44
 
static void meta_frames_class_init (MetaFramesClass *klass);
45
 
static void meta_frames_init       (MetaFrames      *frames);
46
48
static void meta_frames_destroy    (GtkObject       *object);
47
49
static void meta_frames_finalize   (GObject         *object);
48
50
static void meta_frames_style_set  (GtkWidget       *widget,
74
76
static void meta_frames_paint_to_drawable (MetaFrames   *frames,
75
77
                                           MetaUIFrame  *frame,
76
78
                                           GdkDrawable  *drawable,
77
 
                                           GdkRegion    *region,
 
79
                                           MetaRegion   *region,
78
80
                                           int           x_offset,
79
81
                                           int           y_offset);
80
82
 
106
108
static void invalidate_whole_window (MetaFrames *frames,
107
109
                                     MetaUIFrame *frame);
108
110
 
109
 
static GtkWidgetClass *parent_class = NULL;
 
111
G_DEFINE_TYPE (MetaFrames, meta_frames, GTK_TYPE_WINDOW);
110
112
 
111
 
GType
112
 
meta_frames_get_type (void)
 
113
static GObject *
 
114
meta_frames_constructor (GType                  gtype,
 
115
                         guint                  n_properties,
 
116
                         GObjectConstructParam *properties)
113
117
{
114
 
  static GType frames_type = 0;
115
 
 
116
 
  if (!frames_type)
117
 
    {
118
 
      static const GtkTypeInfo frames_info =
119
 
      {
120
 
        "MetaFrames",
121
 
        sizeof (MetaFrames),
122
 
        sizeof (MetaFramesClass),
123
 
        (GtkClassInitFunc) meta_frames_class_init,
124
 
        (GtkObjectInitFunc) meta_frames_init,
125
 
        /* reserved_1 */ NULL,
126
 
        /* reserved_2 */ NULL,
127
 
        (GtkClassInitFunc) NULL,
128
 
      };
129
 
 
130
 
      frames_type = gtk_type_unique (GTK_TYPE_WINDOW, &frames_info);
131
 
    }
132
 
 
133
 
  return frames_type;
 
118
  GObject *object;
 
119
  GObjectClass *gobject_class;
 
120
 
 
121
  gobject_class = G_OBJECT_CLASS (meta_frames_parent_class);
 
122
  object = gobject_class->constructor (gtype, n_properties, properties);
 
123
 
 
124
  g_object_set (object,
 
125
                "type", GTK_WINDOW_POPUP,
 
126
                NULL);
 
127
 
 
128
  return object;
134
129
}
135
130
 
136
131
static void
144
139
  object_class = (GtkObjectClass*) class;
145
140
  widget_class = (GtkWidgetClass*) class;
146
141
 
147
 
  parent_class = g_type_class_peek_parent (class);
148
 
 
 
142
  gobject_class->constructor = meta_frames_constructor;
149
143
  gobject_class->finalize = meta_frames_finalize;
150
144
  object_class->destroy = meta_frames_destroy;
151
145
 
203
197
static void
204
198
meta_frames_init (MetaFrames *frames)
205
199
{
206
 
  GTK_WINDOW (frames)->type = GTK_WINDOW_POPUP;
207
 
 
208
200
  frames->text_heights = g_hash_table_new (NULL, NULL);
209
201
  
210
202
  frames->frames = g_hash_table_new (unsigned_long_hash, unsigned_long_equal);
256
248
    }
257
249
  g_slist_free (winlist);
258
250
 
259
 
  GTK_OBJECT_CLASS (parent_class)->destroy (object);
 
251
  GTK_OBJECT_CLASS (meta_frames_parent_class)->destroy (object);
260
252
}
261
253
 
262
254
static void
278
270
  g_hash_table_destroy (frames->frames);
279
271
  g_hash_table_destroy (frames->cache);
280
272
 
281
 
  G_OBJECT_CLASS (parent_class)->finalize (object);
 
273
  G_OBJECT_CLASS (meta_frames_parent_class)->finalize (object);
282
274
}
283
275
 
284
276
typedef struct
448
440
  g_hash_table_foreach (frames->frames,
449
441
                        reattach_style_func, frames);
450
442
 
451
 
  GTK_WIDGET_CLASS (parent_class)->style_set (widget, prev_style);
 
443
  GTK_WIDGET_CLASS (meta_frames_parent_class)->style_set (widget, prev_style);
452
444
}
453
445
 
454
446
static void
459
451
  MetaFrameFlags flags;
460
452
  MetaFrameType type;
461
453
  MetaFrameStyle *style;
462
 
  
463
 
  g_return_if_fail (GTK_WIDGET_REALIZED (frames));
464
454
 
465
455
  widget = GTK_WIDGET (frames);
 
456
 
 
457
  g_return_if_fail (gtk_widget_get_realized (widget));
466
458
      
467
459
  meta_core_get (gdk_display, frame->xwindow,
468
460
                 META_CORE_GET_FRAME_FLAGS, &flags,
501
493
      
502
494
      frame->layout = gtk_widget_create_pango_layout (widget, frame->title);
503
495
 
 
496
      pango_layout_set_ellipsize (frame->layout, PANGO_ELLIPSIZE_END);
504
497
      pango_layout_set_auto_dir (frame->layout, FALSE);
505
498
      
506
499
      font_desc = meta_gtk_widget_get_font_desc (widget, scale,
593
586
    gtk_style_detach (frame->style);
594
587
 
595
588
  /* Weirdly, gtk_style_attach() steals a reference count from the style passed in */
596
 
  g_object_ref (GTK_WIDGET (frames)->style);
597
 
  frame->style = gtk_style_attach (GTK_WIDGET (frames)->style, frame->window);
 
589
  g_object_ref (gtk_widget_get_style (GTK_WIDGET (frames)));
 
590
  frame->style = gtk_style_attach (gtk_widget_get_style (GTK_WIDGET (frames)),
 
591
                                   frame->window);
598
592
}
599
593
 
600
594
void
684
678
static void
685
679
meta_frames_realize (GtkWidget *widget)
686
680
{
687
 
  if (GTK_WIDGET_CLASS (parent_class)->realize)
688
 
    GTK_WIDGET_CLASS (parent_class)->realize (widget);
 
681
  if (GTK_WIDGET_CLASS (meta_frames_parent_class)->realize)
 
682
    GTK_WIDGET_CLASS (meta_frames_parent_class)->realize (widget);
689
683
}
690
684
 
691
685
static void
692
686
meta_frames_unrealize (GtkWidget *widget)
693
687
{
694
 
  if (GTK_WIDGET_CLASS (parent_class)->unrealize)
695
 
    GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
 
688
  if (GTK_WIDGET_CLASS (meta_frames_parent_class)->unrealize)
 
689
    GTK_WIDGET_CLASS (meta_frames_parent_class)->unrealize (widget);
696
690
}
697
691
 
698
692
static MetaUIFrame*
2014
2008
static GdkGC *
2015
2009
get_bg_gc (GdkWindow *window, int x_offset, int y_offset)
2016
2010
{
2017
 
  GdkWindowObject *private = (GdkWindowObject *)window;
 
2011
  GdkWindow *parent = gdk_window_get_parent (window);
 
2012
  GdkPixmap *back_pixmap;
 
2013
  gboolean parent_relative;
2018
2014
  guint gc_mask = 0;
2019
2015
  GdkGCValues gc_values;
2020
2016
 
2021
 
  if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG && private->parent)
 
2017
  gdk_window_get_back_pixmap (window, &back_pixmap, &parent_relative);
 
2018
  if (parent_relative && parent)
2022
2019
    {
2023
 
      return get_bg_gc (GDK_WINDOW (private->parent),
2024
 
                        x_offset + private->x,
2025
 
                        y_offset + private->y);
 
2020
      gint window_x, window_y;
 
2021
 
 
2022
      gdk_window_get_position (window, &window_x, &window_y);
 
2023
      return get_bg_gc (parent,
 
2024
                        x_offset + window_x,
 
2025
                        y_offset + window_y);
2026
2026
    }
2027
 
  else if (private->bg_pixmap && 
2028
 
           private->bg_pixmap != GDK_PARENT_RELATIVE_BG && 
2029
 
           private->bg_pixmap != GDK_NO_BG)
 
2027
  else if (back_pixmap)
2030
2028
    {
2031
2029
      gc_values.fill = GDK_TILED;
2032
 
      gc_values.tile = private->bg_pixmap;
 
2030
      gc_values.tile = back_pixmap;
2033
2031
      gc_values.ts_x_origin = x_offset;
2034
2032
      gc_values.ts_y_origin = y_offset;
2035
2033
      
2039
2037
    }
2040
2038
  else
2041
2039
    {
 
2040
      GdkColor bg_color;
2042
2041
      GdkGC *gc = gdk_gc_new (window);
2043
2042
 
2044
 
      gdk_gc_set_foreground (gc, &(private->bg_color));
 
2043
      gdk_window_get_background (window, &bg_color);
 
2044
      gdk_gc_set_foreground (gc, &bg_color);
2045
2045
 
2046
2046
      return gc;
2047
2047
    }
2069
2069
                 MetaRectangle rect)
2070
2070
{
2071
2071
  GdkRectangle rectangle;
2072
 
  GdkRegion *region;
 
2072
  MetaRegion *region;
2073
2073
  GdkPixmap *result;
2074
2074
 
2075
2075
  rectangle.x = rect.x;
2082
2082
  
2083
2083
  clear_backing (result, frame->window, rectangle.x, rectangle.y);
2084
2084
 
2085
 
  region = gdk_region_rectangle (&rectangle);
 
2085
  region = meta_region_new_from_rectangle (&rectangle);
2086
2086
 
2087
2087
  meta_frames_paint_to_drawable (frames, frame, result, region,
2088
2088
                                 -rectangle.x, -rectangle.y);
2089
2089
 
2090
 
  gdk_region_destroy (region);
 
2090
  meta_region_destroy (region);
2091
2091
 
2092
2092
  return result;
2093
2093
}
2171
2171
}
2172
2172
 
2173
2173
static void
2174
 
clip_to_screen (GdkRegion *region, MetaUIFrame *frame)
 
2174
clip_to_screen (MetaRegion *region, MetaUIFrame *frame)
2175
2175
{
2176
2176
  GdkRectangle frame_area;
2177
2177
  GdkRectangle screen_area = { 0, 0, 0, 0 };
2178
 
  GdkRegion *tmp_region;
 
2178
  MetaRegion *tmp_region;
2179
2179
  
2180
2180
  /* Chop off stuff outside the screen; this optimization
2181
2181
   * is crucial to handle huge client windows,
2190
2190
                 META_CORE_GET_SCREEN_HEIGHT, &screen_area.height,
2191
2191
                 META_CORE_GET_END);
2192
2192
 
2193
 
  gdk_region_offset (region, frame_area.x, frame_area.y);
2194
 
 
2195
 
  tmp_region = gdk_region_rectangle (&frame_area);
2196
 
  gdk_region_intersect (region, tmp_region);
2197
 
  gdk_region_destroy (tmp_region);
2198
 
 
2199
 
  gdk_region_offset (region, - frame_area.x, - frame_area.y);
 
2193
  meta_region_translate (region, frame_area.x, frame_area.y);
 
2194
 
 
2195
  tmp_region = meta_region_new_from_rectangle (&frame_area);
 
2196
  meta_region_intersect (region, tmp_region);
 
2197
  meta_region_destroy (tmp_region);
 
2198
 
 
2199
  meta_region_translate (region, - frame_area.x, - frame_area.y);
2200
2200
}
2201
2201
 
2202
2202
static void
2203
 
subtract_from_region (GdkRegion *region, GdkDrawable *drawable,
 
2203
subtract_from_region (MetaRegion *region, GdkDrawable *drawable,
2204
2204
                      gint x, gint y)
2205
2205
{
2206
2206
  GdkRectangle rect;
2207
 
  GdkRegion *reg_rect;
 
2207
  MetaRegion *reg_rect;
2208
2208
 
2209
2209
  gdk_drawable_get_size (drawable, &rect.width, &rect.height);
2210
2210
  rect.x = x;
2211
2211
  rect.y = y;
2212
2212
 
2213
 
  reg_rect = gdk_region_rectangle (&rect);
2214
 
  gdk_region_subtract (region, reg_rect);
2215
 
  gdk_region_destroy (reg_rect);
 
2213
  reg_rect = meta_region_new_from_rectangle (&rect);
 
2214
  meta_region_subtract (region, reg_rect);
 
2215
  meta_region_destroy (reg_rect);
2216
2216
}
2217
2217
 
2218
2218
static void
2219
2219
cached_pixels_draw (CachedPixels *pixels,
2220
 
                    GdkWindow *window,
2221
 
                    GdkRegion *region)
 
2220
                    GdkWindow    *window,
 
2221
                    MetaRegion   *region)
2222
2222
{
2223
2223
  GdkGC *gc;
2224
2224
  int i;
2250
2250
{
2251
2251
  MetaUIFrame *frame;
2252
2252
  MetaFrames *frames;
2253
 
  GdkRegion *region;
2254
2253
  CachedPixels *pixels;
 
2254
  MetaRegion *region;
2255
2255
 
2256
2256
  frames = META_FRAMES (widget);
2257
2257
 
2268
2268
 
2269
2269
  populate_cache (frames, frame);
2270
2270
 
2271
 
  region = gdk_region_copy (event->region);
 
2271
  region = meta_region_copy (event->region);
2272
2272
  
2273
2273
  pixels = get_cache (frames, frame);
2274
2274
 
2277
2277
  clip_to_screen (region, frame);
2278
2278
  meta_frames_paint_to_drawable (frames, frame, frame->window, region, 0, 0);
2279
2279
 
2280
 
  gdk_region_destroy (region);
 
2280
  meta_region_destroy (region);
2281
2281
  
2282
2282
  return TRUE;
2283
2283
}
2291
2291
meta_frames_paint_to_drawable (MetaFrames   *frames,
2292
2292
                               MetaUIFrame  *frame,
2293
2293
                               GdkDrawable  *drawable,
2294
 
                               GdkRegion    *region,
 
2294
                               MetaRegion   *region,
2295
2295
                               int           x_offset,
2296
2296
                               int           y_offset)
2297
2297
{
2424
2424
      GdkRectangle area, *areas;
2425
2425
      int n_areas;
2426
2426
      int screen_width, screen_height;
2427
 
      GdkRegion *edges, *tmp_region;
 
2427
      MetaRegion *edges, *tmp_region;
2428
2428
      int top, bottom, left, right;
2429
2429
 
2430
2430
      /* Repaint each side of the frame */
2438
2438
                     META_CORE_GET_SCREEN_HEIGHT, &screen_height,
2439
2439
                     META_CORE_GET_END);
2440
2440
 
2441
 
      edges = gdk_region_copy (region);
 
2441
      edges = meta_region_copy (region);
2442
2442
 
2443
2443
      /* Punch out the client area */
2444
2444
 
2446
2446
      area.y = top;
2447
2447
      area.width = w;
2448
2448
      area.height = h;
2449
 
      tmp_region = gdk_region_rectangle (&area);
2450
 
      gdk_region_subtract (edges, tmp_region);
2451
 
      gdk_region_destroy (tmp_region);
 
2449
      tmp_region = meta_region_new_from_rectangle (&area);
 
2450
      meta_region_subtract (edges, tmp_region);
 
2451
      meta_region_destroy (tmp_region);
2452
2452
 
2453
2453
      /* Now draw remaining portion of region */
2454
2454
 
2455
 
      gdk_region_get_rectangles (edges, &areas, &n_areas);
 
2455
      meta_region_get_rectangles (edges, &areas, &n_areas);
2456
2456
 
2457
2457
      for (i = 0; i < n_areas; i++)
2458
2458
        {
2495
2495
        }
2496
2496
 
2497
2497
      g_free (areas);
2498
 
      gdk_region_destroy (edges);
 
2498
      meta_region_destroy (edges);
2499
2499
 
2500
2500
    }
2501
2501
  else
2558
2558
      /* Set A in ARGB to window_background_alpha, if we have ARGB */
2559
2559
 
2560
2560
      visual = gtk_widget_get_visual (GTK_WIDGET (frames));
2561
 
      if (visual->depth == 32) /* we have ARGB */
 
2561
      if (gdk_visual_get_depth (visual) == 32) /* we have ARGB */
2562
2562
        {
2563
2563
          color.pixel = (color.pixel & 0xffffff) &
2564
2564
            style->window_background_alpha << 24;