summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorSam Spilsbury <smspillaz@gmail.com>2010-03-09 10:48:25 +0800
committerSam Spilsbury <smspillaz@gmail.com>2010-03-09 10:48:25 +0800
commit9370c5e532abffbe40d7a07b8cdb0833e12e04ba (patch)
treef3a275c0218b6d1674af66498311d5a3e5de0b3c /gtk
parentf75014fed82d030bc7611f09fda49fcfc068d391 (diff)
downloadzcomp-9370c5e532abffbe40d7a07b8cdb0833e12e04ba.tar.gz
zcomp-9370c5e532abffbe40d7a07b8cdb0833e12e04ba.tar.bz2
Cairo mode almost done. Fixed crash to do with incorrect iterator usage
Diffstat (limited to 'gtk')
-rw-r--r--gtk/window-decorator/gtk-window-decorator.c2400
1 files changed, 1645 insertions, 755 deletions
diff --git a/gtk/window-decorator/gtk-window-decorator.c b/gtk/window-decorator/gtk-window-decorator.c
index 0c2002f..9edb3dd 100644
--- a/gtk/window-decorator/gtk-window-decorator.c
+++ b/gtk/window-decorator/gtk-window-decorator.c
@@ -242,9 +242,9 @@ static double decoration_alpha = 0.5;
#define SWITCHER_SPACE 40
static decor_extents_t _shadow_extents = { 0, 0, 0, 0 };
-static decor_extents_t _win_extents = { 6, 6, 4, 6 };
+static decor_extents_t _win_extents = { 6, 6, 6, 6 };
static decor_extents_t _max_win_extents = { 6, 6, 4, 6 };
-static decor_extents_t _default_win_extents = { 6, 6, 4, 6 };
+static decor_extents_t _default_win_extents = { 6, 6, 6, 6 };
static decor_extents_t _switcher_extents = { 6, 6, 6, 6 + SWITCHER_SPACE };
static int titlebar_height = 17;
@@ -322,6 +322,8 @@ static Atom toolkit_action_force_quit_dialog_atom;
static Time dm_sn_timestamp;
+int file_inc = 0;
+
#define C(name) { 0, XC_ ## name }
static struct _cursor {
@@ -379,12 +381,19 @@ typedef struct _decor_color {
#define PRESSED_EVENT_WINDOW (1 << 1)
typedef struct _decor {
+ WnckWindow *win;
Window event_windows[3][3];
Window button_windows[BUTTON_NUM];
+ Box event_window_pos[3][3];
+ Box button_window_pos[BUTTON_NUM];
+ Box *last_pos_entered;
guint button_states[BUTTON_NUM];
GdkPixmap *pixmap;
GdkPixmap *buffer_pixmap;
GdkWindow *frame_window;
+ GtkWidget *decor_window;
+ GtkWidget *decor_event_box;
+ GtkWidget *decor_image;
GdkGC *gc;
decor_layout_t border_layout;
decor_context_t *context;
@@ -409,6 +418,24 @@ typedef struct _decor {
void (*draw) (struct _decor *d);
} decor_t;
+typedef struct _GTKWDButtonEvent {
+ guint time;
+ guint window;
+ guint x;
+ guint y;
+ guint x_root;
+ guint y_root;
+ guint button;
+} GTKWDButtonEvent;
+
+typedef enum _GTKWDEventType {
+ GButtonPress = 1,
+ GButtonRelease,
+ GEnterNotify,
+ GLeaveNotify,
+ GMotionNotify
+} GTKWDEventType;
+
void (*theme_draw_window_decoration) (decor_t *d);
gboolean (*theme_calc_decoration_size) (decor_t *d,
int client_width,
@@ -435,7 +462,7 @@ gboolean (*theme_get_button_position) (decor_t *d,
gint *w,
gint *h);
-typedef void (*event_callback) (WnckWindow *win, XEvent *event);
+typedef void (*event_callback) (WnckWindow *win, GTKWDButtonEvent *bevent, GTKWDEventType gType);
static char *program_name;
@@ -443,6 +470,7 @@ static GtkWidget *style_window;
static GtkWidget *switcher_label;
static GHashTable *frame_table;
+static GHashTable *frame_window_table;
static GtkWidget *action_menu = NULL;
static gboolean action_menu_mapped = FALSE;
static decor_color_t _title_color[2];
@@ -571,11 +599,18 @@ decor_update_window_property (decor_t *d)
extents.top += titlebar_height;
- decor_quads_to_property (data, GDK_PIXMAP_XID (d->pixmap),
+ if (d->frame_window)
+ {
+ decor_gen_window_property (data, &extents, &extents, 20, 20);
+ }
+ else
+ {
+ decor_quads_to_property (data, GDK_PIXMAP_XID (d->pixmap),
&extents, &extents,
ICON_SPACE + d->button_width,
0,
quads, nQuad);
+ }
gdk_error_trap_push ();
XChangeProperty (xdisplay, d->prop_xid,
@@ -642,17 +677,22 @@ static inline GdkWindow *
create_gdk_window (Window xframe)
{
GdkWindow *window = gdk_window_foreign_new (xframe);
+ GdkScreen *screen = gdk_display_get_default_screen (gdk_display_get_default ());
+ GdkColormap *cmap = gdk_screen_get_rgb_colormap (screen);
+
+ gdk_drawable_set_colormap (GDK_DRAWABLE (window), cmap);
return window;
}
static GdkPixmap *
create_pixmap (int w,
- int h)
+ int h,
+ int depth)
{
if (w == 0 || h ==0)
abort ();
- return gdk_pixmap_new (GDK_DRAWABLE (style_window->window), w, h, 32);
+ return gdk_pixmap_new (GDK_DRAWABLE (style_window->window), w, h, depth);
}
#define CORNER_TOPLEFT (1 << 0)
@@ -934,6 +974,7 @@ draw_window_decoration (decor_t *d)
{
cairo_t *cr;
GtkStyle *style;
+ GdkDrawable *drawable;
decor_color_t color;
double alpha;
double x1, y1, x2, y2, x, y, h;
@@ -945,6 +986,7 @@ draw_window_decoration (decor_t *d)
return;
style = gtk_widget_get_style (style_window);
+
if (d->state & (WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY |
WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY))
@@ -954,10 +996,30 @@ draw_window_decoration (decor_t *d)
color.g = style->bg[GTK_STATE_NORMAL].green / 65535.0;
color.b = style->bg[GTK_STATE_NORMAL].blue / 65535.0;
- if (d->buffer_pixmap)
- cr = gdk_cairo_create (GDK_DRAWABLE (d->buffer_pixmap));
+ if (d->frame_window)
+ {
+ GdkScreen *screen = gdk_display_get_default_screen (gdk_display_get_default ());
+ GdkColormap *cmap;
+
+ if (gdk_drawable_get_depth (GDK_DRAWABLE (d->pixmap)) == 32)
+ cmap = gdk_screen_get_rgba_colormap (screen);
+ else
+ cmap = gdk_screen_get_rgb_colormap (screen);
+
+ gdk_drawable_set_colormap (GDK_DRAWABLE (d->pixmap), cmap);
+ gdk_drawable_set_colormap (GDK_DRAWABLE (d->buffer_pixmap), cmap);
+
+ drawable = GDK_DRAWABLE (d->buffer_pixmap);
+ }
+ else if (d->buffer_pixmap)
+ drawable = GDK_DRAWABLE (d->buffer_pixmap);
else
- cr = gdk_cairo_create (GDK_DRAWABLE (d->pixmap));
+ drawable = GDK_DRAWABLE (d->pixmap);
+
+ cr = gdk_cairo_create (GDK_DRAWABLE (drawable));
+
+ if (!cr)
+ return;
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
@@ -972,7 +1034,8 @@ draw_window_decoration (decor_t *d)
cairo_set_line_width (cr, 1.0);
- draw_shadow_background (d, cr, d->shadow, d->context);
+ if (!d->frame_window)
+ draw_shadow_background (d, cr, d->shadow, d->context);
if (d->active)
{
@@ -1130,6 +1193,7 @@ draw_window_decoration (decor_t *d)
CORNER_BOTTOMRIGHT) & corners);
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.4);
+
cairo_stroke (cr);
cairo_translate (cr, -2.0, -2.0);
@@ -1142,6 +1206,7 @@ draw_window_decoration (decor_t *d)
CORNER_BOTTOMRIGHT) & corners);
cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.1);
+
cairo_stroke (cr);
cairo_translate (cr, 1.0, 1.0);
@@ -1185,6 +1250,7 @@ draw_window_decoration (decor_t *d)
gdk_cairo_set_source_color_alpha (cr,
&style->fg[GTK_STATE_NORMAL],
alpha * 0.75);
+
cairo_move_to (cr, x, y);
draw_close_button (d, cr, 3.0);
cairo_fill (cr);
@@ -1206,6 +1272,7 @@ draw_window_decoration (decor_t *d)
gdk_cairo_set_source_color_alpha (cr,
&style->fg[GTK_STATE_NORMAL],
STROKE_ALPHA);
+
cairo_move_to (cr, x, y);
if (d->state & (WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY |
@@ -1222,6 +1289,7 @@ draw_window_decoration (decor_t *d)
gdk_cairo_set_source_color_alpha (cr,
&style->fg[GTK_STATE_NORMAL],
alpha * 0.75);
+
cairo_move_to (cr, x, y);
if (d->state & (WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY |
@@ -1247,6 +1315,8 @@ draw_window_decoration (decor_t *d)
gdk_cairo_set_source_color_alpha (cr,
&style->fg[GTK_STATE_NORMAL],
STROKE_ALPHA);
+
+
cairo_move_to (cr, x, y);
draw_min_button (d, cr, 4.0);
button_state_paint (cr, style, &color,
@@ -1257,6 +1327,7 @@ draw_window_decoration (decor_t *d)
gdk_cairo_set_source_color_alpha (cr,
&style->fg[GTK_STATE_NORMAL],
alpha * 0.75);
+
cairo_move_to (cr, x, y);
draw_min_button (d, cr, 4.0);
cairo_fill (cr);
@@ -1321,6 +1392,12 @@ draw_window_decoration (decor_t *d)
d->width,
d->height);
+ if (d->frame_window)
+ {
+ gtk_image_set_from_pixmap (GTK_IMAGE (d->decor_image), d->pixmap, NULL);
+ gtk_window_resize (GTK_WINDOW (d->decor_window), d->width, d->height);
+ }
+
if (d->prop_xid)
{
decor_update_window_property (d);
@@ -1383,12 +1460,19 @@ decor_update_meta_window_property (decor_t *d,
extents.top += titlebar_height;
max_extents.top += max_titlebar_height;
-
- decor_quads_to_property (data, GDK_PIXMAP_XID (d->pixmap),
- &extents, &max_extents,
- ICON_SPACE + d->button_width,
- 0,
- quads, nQuad);
+
+ if (d->frame_window)
+ {
+ decor_gen_window_property (data, &extents, &max_extents, 20, 20);
+ }
+ else
+ {
+ decor_quads_to_property (data, GDK_PIXMAP_XID (d->pixmap),
+ &extents, &max_extents,
+ ICON_SPACE + d->button_width,
+ 0,
+ quads, nQuad);
+ }
gdk_error_trap_push ();
XChangeProperty (xdisplay, d->prop_xid,
@@ -1864,6 +1948,20 @@ meta_draw_window_decoration (decor_t *d)
if (!d->pixmap || !d->picture)
return;
+ if (d->frame_window)
+ {
+ GdkScreen *screen = gdk_display_get_default_screen (gdk_display_get_default ());
+ GdkColormap *cmap;
+
+ if (gdk_drawable_get_depth (GDK_DRAWABLE (d->pixmap)) == 32)
+ cmap = gdk_screen_get_rgba_colormap (screen);
+ else
+ cmap = gdk_screen_get_rgb_colormap (screen);
+
+ gdk_drawable_set_colormap (GDK_DRAWABLE (d->pixmap), cmap);
+ gdk_drawable_set_colormap (GDK_DRAWABLE (d->buffer_pixmap), cmap);
+ }
+
if (decoration_alpha == 1.0)
alpha = 1.0;
@@ -1882,7 +1980,7 @@ meta_draw_window_decoration (decor_t *d)
/* we only have to redraw the shadow background when decoration
changed size */
- if (d->prop_xid || !d->buffer_pixmap)
+ if ((d->prop_xid || !d->buffer_pixmap) && !d->frame_window)
draw_shadow_background (d, cr, d->shadow, d->context);
for (i = 0; i < META_BUTTON_TYPE_LAST; i++)
@@ -1916,7 +2014,10 @@ meta_draw_window_decoration (decor_t *d)
if (rect.width && size)
{
- pixmap = create_pixmap (rect.width, size);
+ if (d->frame_window)
+ pixmap = create_pixmap (rect.width, size, gdk_drawable_get_depth (GDK_DRAWABLE (d->frame_window)));
+ else
+ pixmap = create_pixmap (rect.width, size, 32);
cr = gdk_cairo_create (GDK_DRAWABLE (pixmap));
gdk_cairo_set_source_color_alpha (cr, &bg_color, bg_alpha);
@@ -2018,7 +2119,10 @@ meta_draw_window_decoration (decor_t *d)
if (size && rect.height)
{
- pixmap = create_pixmap (size, rect.height);
+ if (d->frame_window)
+ pixmap = create_pixmap (size, rect.height, gdk_drawable_get_depth (GDK_DRAWABLE (d->frame_window)));
+ else
+ pixmap = create_pixmap (size, rect.height, 32);
cr = gdk_cairo_create (GDK_DRAWABLE (pixmap));
gdk_cairo_set_source_color_alpha (cr, &bg_color, bg_alpha);
@@ -2134,8 +2238,8 @@ meta_draw_window_decoration (decor_t *d)
0,
0,
0,
- d->width,
- d->height);
+ -1,
+ -1);
if (d->prop_xid)
{
@@ -2515,7 +2619,7 @@ queue_decor_draw (decor_t *d)
}
static GdkPixmap *
-pixmap_new_from_pixbuf (GdkPixbuf *pixbuf)
+pixmap_new_from_pixbuf (GdkPixbuf *pixbuf, Bool alpha)
{
GdkPixmap *pixmap;
guint width, height;
@@ -2524,7 +2628,7 @@ pixmap_new_from_pixbuf (GdkPixbuf *pixbuf)
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
- pixmap = create_pixmap (width, height);
+ pixmap = create_pixmap (width, height, alpha ? 32 : 24);
if (!pixmap)
return NULL;
@@ -2624,7 +2728,8 @@ update_default_decorations (GdkScreen *screen)
nQuad = decor_set_lSrStSbS_window_quads (quads, d.context,
&d.border_layout);
- decor_normal_pixmap = create_pixmap (d.width, d.height);
+ decor_normal_pixmap = create_pixmap (d.width, d.height, 32);
+
if (decor_normal_pixmap)
{
d.pixmap = decor_normal_pixmap;
@@ -2650,7 +2755,8 @@ update_default_decorations (GdkScreen *screen)
if (decor_active_pixmap)
g_object_unref (G_OBJECT (decor_active_pixmap));
- decor_active_pixmap = create_pixmap (d.width, d.height);
+ decor_active_pixmap = create_pixmap (d.width, d.height, 32);
+
if (decor_active_pixmap)
{
d.pixmap = decor_active_pixmap;
@@ -3083,6 +3189,8 @@ meta_get_button_position (decor_t *d,
#endif
+ // TODO: put region handlers here
+
static void
update_event_windows (WnckWindow *win)
{
@@ -3136,13 +3244,20 @@ update_event_windows (WnckWindow *win)
(*theme_get_event_window_position) (d, i, j, width, height,
&x, &y, &w, &h);
- if (w != 0 && h != 0)
+ if (d->frame_window)
+ {
+ d->event_window_pos[i][j].x1 = x;
+ d->event_window_pos[i][j].x2 = x + w;
+ d->event_window_pos[i][j].y1 = y;
+ d->event_window_pos[i][j].y2 = y + h;
+ }
+ else if (!d->frame_window && w != 0 && h != 0)
{
XMapWindow (xdisplay, d->event_windows[i][j]);
XMoveResizeWindow (xdisplay, d->event_windows[i][j],
x, y, w, h);
}
- else
+ else if (!d->frame_window)
{
XUnmapWindow (xdisplay, d->event_windows[i][j]);
}
@@ -3178,18 +3293,36 @@ update_event_windows (WnckWindow *win)
};
- if (button_actions[i] && !(actions & button_actions[i]))
+ if (d->frame_window &&
+ button_actions[i] && !(actions & button_actions[i]))
+ {
+ d->button_window_pos[i].x1 = 0;
+ d->button_window_pos[i].y1 = 0;
+ d->button_window_pos[i].x2 = 0;
+ d->button_window_pos[i].y2 = 0;
+ }
+ else if (!d->frame_window &&
+ button_actions[i] && !(actions & button_actions[i]))
{
XUnmapWindow (xdisplay, d->button_windows[i]);
continue;
}
- if ((*theme_get_button_position) (d, i, width, height, &x, &y, &w, &h))
+ if (d->frame_window &&
+ (*theme_get_button_position) (d, i, width, height, &x, &y, &w, &h))
+ {
+ d->button_window_pos[i].x1 = x;
+ d->button_window_pos[i].y1 = y;
+ d->button_window_pos[i].x2 = x + w;
+ d->button_window_pos[i].y2 = y + h;
+ }
+ else if (!d->frame_window &&
+ (*theme_get_button_position) (d, i, width, height, &x, &y, &w, &h))
{
XMapWindow (xdisplay, d->button_windows[i]);
XMoveResizeWindow (xdisplay, d->button_windows[i], x, y, w, h);
}
- else
+ else if (!d->frame_window)
{
XUnmapWindow (xdisplay, d->button_windows[i]);
}
@@ -3326,7 +3459,8 @@ update_window_decoration_icon (WnckWindow *win)
g_object_ref (G_OBJECT (d->icon_pixbuf));
- d->icon_pixmap = pixmap_new_from_pixbuf (d->icon_pixbuf);
+ d->icon_pixmap = pixmap_new_from_pixbuf (d->icon_pixbuf,
+ TRUE);
cr = gdk_cairo_create (GDK_DRAWABLE (d->icon_pixmap));
d->icon = cairo_pattern_create_for_surface (cairo_get_target (cr));
cairo_destroy (cr);
@@ -3386,27 +3520,59 @@ calc_decoration_size (decor_t *d,
decor_layout_t layout;
int top_width;
- calc_button_size (d);
+ /* To avoid wasting texture memory, we only calculate the minimal
+ * required decoration size then clip and stretch the texture where
+ * appropriate
+ */
+
+ if (!d->frame_window)
+ {
+ calc_button_size (d);
- if (w < ICON_SPACE + d->button_width)
- return FALSE;
+ if (w < ICON_SPACE + d->button_width)
+ return FALSE;
- top_width = name_width + d->button_width + ICON_SPACE;
- if (w < top_width)
- top_width = MAX (ICON_SPACE + d->button_width, w);
+ top_width = name_width + d->button_width + ICON_SPACE;
+ if (w < top_width)
+ top_width = MAX (ICON_SPACE + d->button_width, w);
- decor_get_default_layout (&window_context, top_width, 1, &layout);
+ decor_get_default_layout (&window_context, top_width, 1, &layout);
- if (!d->context || memcmp (&layout, &d->border_layout, sizeof (layout)))
- {
- *width = layout.width;
- *height = layout.height;
+ if (!d->context || memcmp (&layout, &d->border_layout, sizeof (layout)))
+ {
+ *width = layout.width;
+ *height = layout.height;
- d->border_layout = layout;
- d->context = &window_context;
- d->shadow = border_shadow;
+ d->border_layout = layout;
+ d->context = &window_context;
+ d->shadow = border_shadow;
- return TRUE;
+ return TRUE;
+ }
+ }
+ else
+ {
+ calc_button_size (d);
+
+ /* _default_win_extents + top height */
+
+ top_width = name_width + d->button_width + ICON_SPACE;
+ if (w < top_width)
+ top_width = MAX (ICON_SPACE + d->button_width, w);
+
+ decor_get_default_layout (&window_context, top_width, 1, &layout);
+
+ if (TRUE)
+ {
+ *width = d->client_width + _win_extents.left + _win_extents.right + 2;
+ *height = d->client_height + _win_extents.top + _win_extents.bottom + layout.height - 2;
+
+ d->border_layout = layout;
+ d->context = &window_context;
+ d->shadow = border_shadow;
+
+ return TRUE;
+ }
}
return FALSE;
@@ -3473,21 +3639,39 @@ meta_calc_decoration_size (decor_t *d,
decor_get_best_layout (context, w, h, &layout);
- if (context != d->context ||
- memcmp (&layout, &d->border_layout, sizeof (layout)))
+ if (!d->frame_window)
{
- *width = layout.width;
- *height = layout.height;
+ if (context != d->context ||
+ memcmp (&layout, &d->border_layout, sizeof (layout)))
+ {
+ *width = layout.width;
+ *height = layout.height;
- d->border_layout = layout;
- d->context = context;
- d->shadow = shadow;
+ d->border_layout = layout;
+ d->context = context;
+ d->shadow = shadow;
- meta_calc_button_size (d);
+ meta_calc_button_size (d);
- return TRUE;
+ return TRUE;
+ }
}
+ else
+ {
+ if (TRUE)
+ {
+ *width = layout.width + _win_extents.left + _win_extents.right + 2;
+ *height = layout.height + _win_extents.top + _win_extents.bottom - 2;
+
+ d->border_layout = layout;
+ d->context = context;
+ //d->shadow = shadow;
+ meta_calc_button_size (d);
+
+ return TRUE;
+ }
+ }
return FALSE;
}
@@ -3516,289 +3700,40 @@ update_window_decoration_size (WnckWindow *win)
return FALSE;
}
- pixmap = create_pixmap (width, height);
- if (!pixmap)
- return FALSE;
-
- buffer_pixmap = create_pixmap (width, height);
- if (!buffer_pixmap)
- {
- g_object_unref (G_OBJECT (pixmap));
- return FALSE;
- }
-
- picture = XRenderCreatePicture (xdisplay, GDK_PIXMAP_XID (buffer_pixmap),
- xformat, 0, NULL);
-
- if (d->pixmap)
- g_object_unref (G_OBJECT (d->pixmap));
-
- if (d->buffer_pixmap)
- g_object_unref (G_OBJECT (d->buffer_pixmap));
-
- if (d->gc)
- g_object_unref (G_OBJECT (d->gc));
-
- if (d->picture)
- XRenderFreePicture (xdisplay, d->picture);
-
- d->pixmap = pixmap;
- d->buffer_pixmap = buffer_pixmap;
- d->gc = gdk_gc_new (pixmap);
-
- d->picture = picture;
-
- d->width = width;
- d->height = height;
-
- d->prop_xid = wnck_window_get_xid (win);
-
- if (d->frame_window && width != 0 && height != 0)
- {
- gdk_window_show (d->frame_window);
- }
-
- update_window_decoration_name (win);
-
- queue_decor_draw (d);
-
- return TRUE;
-}
-
-static void
-add_frame_window (WnckWindow *win,
- Window frame,
- Bool mode)
-{
- Display *xdisplay;
- XSetWindowAttributes attr;
- gulong xid = wnck_window_get_xid (win);
- decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
- gint i, j;
-
- xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
-
- d->active = wnck_window_is_active (win);
-
- attr.event_mask = ButtonPressMask | EnterWindowMask | LeaveWindowMask;
- attr.override_redirect = TRUE;
-
gdk_error_trap_push ();
- for (i = 0; i < 3; i++)
- {
- for (j = 0; j < 3; j++)
- {
- d->event_windows[i][j] =
- XCreateWindow (xdisplay,
- frame,
- 0, 0, 1, 1, 0,
- CopyFromParent, CopyFromParent, CopyFromParent,
- CWOverrideRedirect | CWEventMask, &attr);
-
- if (cursor[i][j].cursor)
- XDefineCursor (xdisplay, d->event_windows[i][j],
- cursor[i][j].cursor);
- }
- }
-
- attr.event_mask |= ButtonReleaseMask;
-
- for (i = 0; i < BUTTON_NUM; i++)
- {
- d->button_windows[i] =
- XCreateWindow (xdisplay,
- frame,
- 0, 0, 1, 1, 0,
- CopyFromParent, CopyFromParent, CopyFromParent,
- CWOverrideRedirect | CWEventMask, &attr);
-
- d->button_states[i] = 0;
- }
-
- /* 2D Mode is on */
-
- fprintf (stderr, "2D Mode?\n");
-
- if (mode == TRUE)
- {
- d->frame_window = create_gdk_window (frame);
- }
- else
- d->frame_window = NULL;
-
- gdk_display_sync (gdk_display_get_default ());
- if (!gdk_error_trap_pop ())
- {
- if (get_mwm_prop (xid) & (MWM_DECOR_ALL | MWM_DECOR_TITLE))
- d->decorated = TRUE;
-
- for (i = 0; i < 3; i++)
- for (j = 0; j < 3; j++)
- g_hash_table_insert (frame_table,
- GINT_TO_POINTER (d->event_windows[i][j]),
- GINT_TO_POINTER (xid));
-
- for (i = 0; i < BUTTON_NUM; i++)
- g_hash_table_insert (frame_table,
- GINT_TO_POINTER (d->button_windows[i]),
- GINT_TO_POINTER (xid));
-
- update_window_decoration_state (win);
- update_window_decoration_actions (win);
- update_window_decoration_icon (win);
- update_window_decoration_size (win);
- update_event_windows (win);
- }
+ if (d->frame_window)
+ pixmap = create_pixmap (width, height, gdk_drawable_get_depth (GDK_DRAWABLE (d->frame_window)));
else
- {
- memset (d->event_windows, 0, sizeof (d->event_windows));
- }
-}
+ pixmap = create_pixmap (width, height, 32);
-static gboolean
-update_switcher_window (WnckWindow *win,
- Window selected)
-{
- decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
- GdkPixmap *pixmap, *buffer_pixmap = NULL;
- gint height, width = 0;
- WnckWindow *selected_win;
- Display *xdisplay;
-
- xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
-
- wnck_window_get_client_window_geometry (win, NULL, NULL, &width, NULL);
-
- decor_get_default_layout (&switcher_context, width, 1, &d->border_layout);
+ gdk_flush ();
- width = d->border_layout.width;
- height = d->border_layout.height;
-
- d->decorated = FALSE;
- d->draw = draw_switcher_decoration;
-
- if (!d->pixmap && switcher_pixmap)
+ if (!pixmap || gdk_error_trap_pop ())
{
- g_object_ref (G_OBJECT (switcher_pixmap));
- d->pixmap = switcher_pixmap;
- }
-
- if (!d->buffer_pixmap && switcher_buffer_pixmap)
- {
- g_object_ref (G_OBJECT (switcher_buffer_pixmap));
- d->buffer_pixmap = switcher_buffer_pixmap;
- }
-
- if (!d->width)
- d->width = switcher_width;
-
- if (!d->height)
- d->height = switcher_height;
-
- selected_win = wnck_window_get (selected);
- if (selected_win)
- {
- glong name_length;
- PangoLayoutLine *line;
- const gchar *name;
-
- if (d->name)
- {
- g_free (d->name);
- d->name = NULL;
- }
-
- name = wnck_window_get_name (selected_win);
- if (name && (name_length = strlen (name)))
- {
- if (!d->layout)
- {
- d->layout = pango_layout_new (pango_context);
- if (d->layout)
- pango_layout_set_wrap (d->layout, PANGO_WRAP_CHAR);
- }
-
- if (d->layout)
- {
- int tw;
-
- tw = width - switcher_context.left_space -
- switcher_context.right_space - 64;
- pango_layout_set_auto_dir (d->layout, FALSE);
- pango_layout_set_width (d->layout, tw * PANGO_SCALE);
- pango_layout_set_text (d->layout, name, name_length);
-
- line = pango_layout_get_line (d->layout, 0);
-
- name_length = line->length;
- if (pango_layout_get_line_count (d->layout) > 1)
- {
- if (name_length < 4)
- {
- g_object_unref (G_OBJECT (d->layout));
- d->layout = NULL;
- }
- else
- {
- d->name = g_strndup (name, name_length);
- strcpy (d->name + name_length - 3, "...");
- }
- }
- else
- d->name = g_strndup (name, name_length);
-
- if (d->layout)
- pango_layout_set_text (d->layout, d->name, name_length);
- }
- }
- else if (d->layout)
- {
- g_object_unref (G_OBJECT (d->layout));
- d->layout = NULL;
- }
- }
-
- if (selected != switcher_selected_window)
- {
- gtk_label_set_text (GTK_LABEL (switcher_label), "");
- if (selected_win && d->name)
- gtk_label_set_text (GTK_LABEL (switcher_label), d->name);
- switcher_selected_window = selected;
+ memset (pixmap, 0, sizeof (pixmap));
+ return FALSE;
}
- if (width == d->width && height == d->height)
- {
- if (!d->gc)
- d->gc = gdk_gc_new (d->pixmap);
-
- if (!d->picture)
- d->picture =
- XRenderCreatePicture (xdisplay,
- GDK_PIXMAP_XID (d->buffer_pixmap),
- xformat, 0, NULL);
+ gdk_error_trap_push ();
- queue_decor_draw (d);
- return FALSE;
- }
+ if (d->frame_window)
+ buffer_pixmap = create_pixmap (width, height, gdk_drawable_get_depth (GDK_DRAWABLE (d->frame_window)));
+ else
+ buffer_pixmap = create_pixmap (width, height, 32);
- pixmap = create_pixmap (width, height);
- if (!pixmap)
- return FALSE;
+ gdk_flush ();
- buffer_pixmap = create_pixmap (width, height);
- if (!buffer_pixmap)
+ if (!buffer_pixmap || gdk_error_trap_pop ())
{
+ memset (buffer_pixmap, 0, sizeof (buffer_pixmap));
g_object_unref (G_OBJECT (pixmap));
return FALSE;
}
- if (switcher_pixmap)
- g_object_unref (G_OBJECT (switcher_pixmap));
-
- if (switcher_buffer_pixmap)
- g_object_unref (G_OBJECT (switcher_buffer_pixmap));
+ picture = XRenderCreatePicture (xdisplay, GDK_PIXMAP_XID (buffer_pixmap),
+ xformat, 0, NULL);
if (d->pixmap)
g_object_unref (G_OBJECT (d->pixmap));
@@ -3812,336 +3747,36 @@ update_switcher_window (WnckWindow *win,
if (d->picture)
XRenderFreePicture (xdisplay, d->picture);
- switcher_pixmap = pixmap;
- switcher_buffer_pixmap = buffer_pixmap;
-
- switcher_width = width;
- switcher_height = height;
-
- g_object_ref (G_OBJECT (pixmap));
- g_object_ref (G_OBJECT (buffer_pixmap));
-
d->pixmap = pixmap;
d->buffer_pixmap = buffer_pixmap;
d->gc = gdk_gc_new (pixmap);
- d->picture = XRenderCreatePicture (xdisplay, GDK_PIXMAP_XID (buffer_pixmap),
- xformat, 0, NULL);
+ d->picture = picture;
d->width = width;
d->height = height;
d->prop_xid = wnck_window_get_xid (win);
- queue_decor_draw (d);
-
- return TRUE;
-}
-
-static void
-remove_frame_window (WnckWindow *win)
-{
- decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
- Display *xdisplay;
-
- xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
-
- if (d->pixmap)
- {
- g_object_unref (G_OBJECT (d->pixmap));
- d->pixmap = NULL;
- }
-
- if (d->buffer_pixmap)
- {
- g_object_unref (G_OBJECT (d->buffer_pixmap));
- d->buffer_pixmap = NULL;
- }
-
- if (d->gc)
- {
- g_object_unref (G_OBJECT (d->gc));
- d->gc = NULL;
- }
-
- if (d->picture)
- {
- XRenderFreePicture (xdisplay, d->picture);
- d->picture = 0;
- }
-
- if (d->name)
- {
- g_free (d->name);
- d->name = NULL;
- }
-
- if (d->layout)
- {
- g_object_unref (G_OBJECT (d->layout));
- d->layout = NULL;
- }
-
- if (d->icon)
- {
- cairo_pattern_destroy (d->icon);
- d->icon = NULL;
- }
-
- if (d->icon_pixmap)
- {
- g_object_unref (G_OBJECT (d->icon_pixmap));
- d->icon_pixmap = NULL;
- }
-
- if (d->icon_pixbuf)
- {
- g_object_unref (G_OBJECT (d->icon_pixbuf));
- d->icon_pixbuf = NULL;
- }
-
- if (d->force_quit_dialog)
- {
- GtkWidget *dialog = d->force_quit_dialog;
-
- d->force_quit_dialog = NULL;
- gtk_widget_destroy (dialog);
- }
-
- if (d->frame_window)
- {
- g_object_unref (G_OBJECT (d->frame_window));
- gdk_window_destroy (d->frame_window);
- d->frame_window = NULL;
- }
-
- d->width = 0;
- d->height = 0;
-
- d->decorated = FALSE;
-
- d->state = 0;
- d->actions = 0;
-
- d->context = NULL;
- d->shadow = NULL;
-
- draw_list = g_slist_remove (draw_list, d);
-}
-
-static void
-window_name_changed (WnckWindow *win)
-{
- decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
-
- if (d->decorated)
- {
- if (!update_window_decoration_size (win))
- queue_decor_draw (d);
- }
-}
-
-static void
-window_geometry_changed (WnckWindow *win)
-{
- decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
-
- if (d->decorated)
- {
- int width, height;
-
- wnck_window_get_client_window_geometry (win, NULL, NULL, &width,
- &height);
-
- if (width != d->client_width || height != d->client_height)
- {
- d->client_width = width;
- d->client_height = height;
-
- update_window_decoration_size (win);
- update_event_windows (win);
- }
- }
-}
-
-static void
-window_icon_changed (WnckWindow *win)
-{
- decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
-
- if (d->decorated)
- {
- update_window_decoration_icon (win);
- queue_decor_draw (d);
- }
-}
-
-static void
-window_state_changed (WnckWindow *win)
-{
- decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
-
- if (d->decorated)
- {
- update_window_decoration_state (win);
- if (!update_window_decoration_size (win))
- queue_decor_draw (d);
-
- update_event_windows (win);
- }
-}
-
-static void
-window_actions_changed (WnckWindow *win)
-{
- decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
-
- if (d->decorated)
- {
- update_window_decoration_actions (win);
- if (!update_window_decoration_size (win))
- queue_decor_draw (d);
-
- update_event_windows (win);
- }
-}
-
-static void
-connect_window (WnckWindow *win)
-{
- g_signal_connect_object (win, "name_changed",
- G_CALLBACK (window_name_changed),
- 0, 0);
- g_signal_connect_object (win, "geometry_changed",
- G_CALLBACK (window_geometry_changed),
- 0, 0);
- g_signal_connect_object (win, "icon_changed",
- G_CALLBACK (window_icon_changed),
- 0, 0);
- g_signal_connect_object (win, "state_changed",
- G_CALLBACK (window_state_changed),
- 0, 0);
- g_signal_connect_object (win, "actions_changed",
- G_CALLBACK (window_actions_changed),
- 0, 0);
-}
-
-static void
-active_window_changed (WnckScreen *screen)
-{
- WnckWindow *win;
- decor_t *d;
-
- win = wnck_screen_get_previously_active_window (screen);
- if (win)
- {
- d = g_object_get_data (G_OBJECT (win), "decor");
- if (d && d->pixmap)
- {
- d->active = wnck_window_is_active (win);
- queue_decor_draw (d);
- }
- }
-
- win = wnck_screen_get_active_window (screen);
- if (win)
- {
- d = g_object_get_data (G_OBJECT (win), "decor");
- if (d && d->pixmap)
- {
- d->active = wnck_window_is_active (win);
- queue_decor_draw (d);
- }
- }
-}
-
-static void
-window_opened (WnckScreen *screen,
- WnckWindow *win)
-{
- decor_t *d;
- Window window;
- gulong xid;
-
- d = calloc (1, sizeof (decor_t));
- if (!d)
- return;
-
- wnck_window_get_client_window_geometry (win, NULL, NULL,
- &d->client_width,
- &d->client_height);
-
- d->draw = theme_draw_window_decoration;
-
- g_object_set_data (G_OBJECT (win), "decor", d);
-
- connect_window (win);
-
- xid = wnck_window_get_xid (win);
-
- fprintf (stderr, "add_frame_window called\n");
-
- if (get_window_prop (xid, select_window_atom, &window))
+ if (d->frame_window && width != 0 && height != 0)
{
- d->prop_xid = wnck_window_get_xid (win);
- update_switcher_window (win, window);
}
- else if (get_window_prop (xid, frame_input_window_atom, &window))
+ else if (d->frame_window)
{
- add_frame_window (win, window, FALSE);
+ gdk_window_hide (d->frame_window);
}
- else if (get_window_prop (xid, frame_output_window_atom, &window))
- {
- add_frame_window (win, window, TRUE);
- }
-}
-
-static void
-window_closed (WnckScreen *screen,
- WnckWindow *win)
-{
- Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
- decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
-
- remove_frame_window (win);
-
- g_object_set_data (G_OBJECT (win), "decor", NULL);
-
- gdk_error_trap_push ();
- XDeleteProperty (xdisplay, wnck_window_get_xid (win), win_decor_atom);
- gdk_display_sync (gdk_display_get_default ());
- gdk_error_trap_pop ();
-
- g_free (d);
-}
-static void
-connect_screen (WnckScreen *screen)
-{
- GList *windows;
+ update_window_decoration_name (win);
- g_signal_connect_object (G_OBJECT (screen), "active_window_changed",
- G_CALLBACK (active_window_changed),
- 0, 0);
- g_signal_connect_object (G_OBJECT (screen), "window_opened",
- G_CALLBACK (window_opened),
- 0, 0);
- g_signal_connect_object (G_OBJECT (screen), "window_closed",
- G_CALLBACK (window_closed),
- 0, 0);
+ queue_decor_draw (d);
- windows = wnck_screen_get_windows (screen);
- while (windows != NULL)
- {
- window_opened (screen, windows->data);
- windows = windows->next;
- }
+ return TRUE;
}
static void
move_resize_window (WnckWindow *win,
int direction,
- XEvent *xevent)
+ GTKWDButtonEvent *bevent)
{
Display *xdisplay;
GdkDisplay *gdkdisplay;
@@ -4172,14 +3807,14 @@ move_resize_window (WnckWindow *win,
ev.xclient.message_type = wm_move_resize_atom;
ev.xclient.format = 32;
- ev.xclient.data.l[0] = xevent->xbutton.x_root;
- ev.xclient.data.l[1] = xevent->xbutton.y_root;
+ ev.xclient.data.l[0] = bevent->x_root;
+ ev.xclient.data.l[1] = bevent->y_root;
ev.xclient.data.l[2] = direction;
- ev.xclient.data.l[3] = xevent->xbutton.button;
+ ev.xclient.data.l[3] = bevent->button;
ev.xclient.data.l[4] = 1;
- XUngrabPointer (xdisplay, xevent->xbutton.time);
- XUngrabKeyboard (xdisplay, xevent->xbutton.time);
+ XUngrabPointer (xdisplay, bevent->time);
+ XUngrabKeyboard (xdisplay, bevent->time);
XSendEvent (xdisplay, xroot, FALSE,
SubstructureRedirectMask | SubstructureNotifyMask,
@@ -4391,32 +4026,36 @@ create_tooltip_window (void)
static void
handle_tooltip_event (WnckWindow *win,
- XEvent *xevent,
+ GTKWDButtonEvent *bevent,
+ GTKWDEventType gType,
guint state,
const char *tip)
{
- switch (xevent->type) {
- case ButtonPress:
+ switch (gType) {
+ case GButtonPress:
hide_tooltip ();
break;
- case ButtonRelease:
+ case GButtonRelease:
break;
- case EnterNotify:
+ case GEnterNotify:
if (!(state & PRESSED_EVENT_WINDOW))
{
if (wnck_window_is_active (win))
tooltip_start_delay (tip);
}
break;
- case LeaveNotify:
+ case GLeaveNotify:
hide_tooltip ();
break;
+ default:
+ break;
}
}
static void
common_button_event (WnckWindow *win,
- XEvent *xevent,
+ GTKWDButtonEvent *bevent,
+ GTKWDEventType gType,
int button,
int max,
char *tooltip)
@@ -4424,79 +4063,92 @@ common_button_event (WnckWindow *win,
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
guint state = d->button_states[button];
- handle_tooltip_event (win, xevent, state, tooltip);
+ handle_tooltip_event (win, bevent, gType, state, tooltip);
- switch (xevent->type) {
- case ButtonPress:
- if (xevent->xbutton.button <= max)
+ switch (gType) {
+ case GButtonPress:
+ if (bevent->button <= max)
d->button_states[button] |= PRESSED_EVENT_WINDOW;
break;
- case ButtonRelease:
- if (xevent->xbutton.button <= max)
+ case GButtonRelease:
+ if (bevent->button <= max)
d->button_states[button] &= ~PRESSED_EVENT_WINDOW;
break;
- case EnterNotify:
+ case GEnterNotify:
+ fprintf (stderr, "I haz enter notify\n");
d->button_states[button] |= IN_EVENT_WINDOW;
break;
- case LeaveNotify:
+ case GLeaveNotify:
+ fprintf (stderr, "I haz leave notify\n");
d->button_states[button] &= ~IN_EVENT_WINDOW;
break;
+ default:
+ break;
}
if (state != d->button_states[button])
+ {
queue_decor_draw (d);
+ }
}
#define BUTTON_EVENT_ACTION_STATE (PRESSED_EVENT_WINDOW | IN_EVENT_WINDOW)
static void
close_button_event (WnckWindow *win,
- XEvent *xevent)
+ GTKWDButtonEvent *bevent,
+ GTKWDEventType gType)
{
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
guint state = d->button_states[BUTTON_CLOSE];
- common_button_event (win, xevent, BUTTON_CLOSE, 1, _("Close Window"));
+ common_button_event (win, bevent, gType,
+ BUTTON_CLOSE, 1, _("Close Window"));
- switch (xevent->type) {
- case ButtonRelease:
- if (xevent->xbutton.button == 1)
+ switch (gType) {
+ case GButtonRelease:
+ if (bevent->button == 1)
{
if (state == BUTTON_EVENT_ACTION_STATE)
- wnck_window_close (win, xevent->xbutton.time);
+ {
+ wnck_window_close (win, bevent->time);
+ }
}
break;
+ default:
+ break;
}
}
static void
max_button_event (WnckWindow *win,
- XEvent *xevent)
+ GTKWDButtonEvent *bevent,
+ GTKWDEventType gType)
{
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
guint state = d->button_states[BUTTON_MAX];
if (wnck_window_is_maximized (win))
- common_button_event (win, xevent, BUTTON_MAX,
+ common_button_event (win, bevent, gType, BUTTON_MAX,
3, _("Unmaximize Window"));
else
- common_button_event (win, xevent, BUTTON_MAX,
+ common_button_event (win, bevent, gType, BUTTON_MAX,
3, _("Maximize Window"));
- switch (xevent->type) {
- case ButtonRelease:
- if (xevent->xbutton.button <= 3)
+ switch (gType) {
+ case GButtonRelease:
+ if (bevent->button <= 3)
{
if (state == BUTTON_EVENT_ACTION_STATE)
{
- if (xevent->xbutton.button == 2)
+ if (bevent->button == 2)
{
if (wnck_window_is_maximized_vertically (win))
wnck_window_unmaximize_vertically (win);
else
wnck_window_maximize_vertically (win);
}
- else if (xevent->xbutton.button == 3)
+ else if (bevent->button == 3)
{
if (wnck_window_is_maximized_horizontally (win))
wnck_window_unmaximize_horizontally (win);
@@ -4513,26 +4165,32 @@ max_button_event (WnckWindow *win,
}
}
break;
+ default:
+ break;
}
}
static void
min_button_event (WnckWindow *win,
- XEvent *xevent)
+ GTKWDButtonEvent *bevent,
+ GTKWDEventType gType)
{
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
guint state = d->button_states[BUTTON_MIN];
- common_button_event (win, xevent, BUTTON_MIN, 1, _("Minimize Window"));
+ common_button_event (win, bevent, gType,
+ BUTTON_MIN, 1, _("Minimize Window"));
- switch (xevent->type) {
- case ButtonRelease:
- if (xevent->xbutton.button == 1)
+ switch (gType) {
+ case GButtonRelease:
+ if (bevent->button == 1)
{
if (state == BUTTON_EVENT_ACTION_STATE)
wnck_window_minimize (win);
}
break;
+ default:
+ break;
}
}
@@ -4646,52 +4304,62 @@ action_menu_map (WnckWindow *win,
static void
menu_button_event (WnckWindow *win,
- XEvent *xevent)
+ GTKWDButtonEvent *bevent,
+ GTKWDEventType gType)
{
- common_button_event (win, xevent, BUTTON_MENU, 1, _("Window Menu"));
+ common_button_event (win, bevent, gType,
+ BUTTON_MENU, 1, _("Window Menu"));
- switch (xevent->type) {
- case ButtonPress:
- if (xevent->xbutton.button == 1)
+ switch (gType) {
+ case GButtonPress:
+ if (bevent->button == 1)
action_menu_map (win,
- xevent->xbutton.button,
- xevent->xbutton.time);
+ bevent->button,
+ bevent->time);
+ break;
+ default:
break;
}
}
static void
shade_button_event (WnckWindow *win,
- XEvent *xevent)
+ GTKWDButtonEvent *bevent,
+ GTKWDEventType gType)
{
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
guint state = d->button_states[BUTTON_SHADE];
- common_button_event (win, xevent, BUTTON_SHADE, 1, _("Shade"));
+ common_button_event (win, bevent, gType,
+ BUTTON_SHADE, 1, _("Shade"));
- switch (xevent->type) {
- case ButtonRelease:
- if (xevent->xbutton.button == 1)
+ switch (gType) {
+ case GButtonRelease:
+ if (bevent->button == 1)
{
if (state == BUTTON_EVENT_ACTION_STATE)
wnck_window_shade (win);
}
break;
+ default:
+ break;
}
}
static void
above_button_event (WnckWindow *win,
- XEvent *xevent)
+ GTKWDButtonEvent *bevent,
+ GTKWDEventType gType)
{
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
guint state = d->button_states[BUTTON_ABOVE];
- common_button_event (win, xevent, BUTTON_ABOVE, 1, _("Make Above"));
+ common_button_event (win, bevent, gType,
+ BUTTON_ABOVE, 1, _("Make Above"));
- switch (xevent->type) {
- case ButtonRelease:
- if (xevent->xbutton.button == 1)
+ switch (gType) {
+ case GButtonRelease:
+ if (bevent->button == 1)
{
if (state == BUTTON_EVENT_ACTION_STATE)
{
@@ -4703,61 +4371,73 @@ above_button_event (WnckWindow *win,
}
}
break;
+ default:
+ break;
}
}
static void
stick_button_event (WnckWindow *win,
- XEvent *xevent)
+ GTKWDButtonEvent *bevent,
+ GTKWDEventType gType)
{
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
guint state = d->button_states[BUTTON_STICK];
- common_button_event (win, xevent, BUTTON_STICK, 1, _("Stick"));
+ common_button_event (win, bevent, gType,
+ BUTTON_STICK, 1, _("Stick"));
- switch (xevent->type) {
- case ButtonRelease:
- if (xevent->xbutton.button == 1)
+ switch (gType) {
+ case GButtonRelease:
+ if (bevent->button == 1)
{
if (state == BUTTON_EVENT_ACTION_STATE)
wnck_window_stick (win);
}
break;
+ default:
+ break;
}
}
static void
unshade_button_event (WnckWindow *win,
- XEvent *xevent)
+ GTKWDButtonEvent *bevent,
+ GTKWDEventType gType)
{
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
guint state = d->button_states[BUTTON_UNSHADE];
- common_button_event (win, xevent, BUTTON_UNSHADE, 1, _("Unshade"));
+ common_button_event (win, bevent, gType,
+ BUTTON_UNSHADE, 1, _("Unshade"));
- switch (xevent->type) {
- case ButtonRelease:
- if (xevent->xbutton.button == 1)
+ switch (gType) {
+ case GButtonRelease:
+ if (bevent->button == 1)
{
if (state == BUTTON_EVENT_ACTION_STATE)
wnck_window_unshade (win);
}
break;
+ default:
+ break;
}
}
static void
unabove_button_event (WnckWindow *win,
- XEvent *xevent)
+ GTKWDButtonEvent *bevent,
+ GTKWDEventType gType)
{
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
guint state = d->button_states[BUTTON_UNABOVE];
- common_button_event (win, xevent, BUTTON_UNABOVE, 1, _("Unmake Above"));
+ common_button_event (win, bevent, gType,
+ BUTTON_UNABOVE, 1, _("Unmake Above"));
- switch (xevent->type) {
- case ButtonRelease:
- if (xevent->xbutton.button == 1)
+ switch (gType) {
+ case GButtonRelease:
+ if (bevent->button == 1)
{
if (state == BUTTON_EVENT_ACTION_STATE)
{
@@ -4769,33 +4449,39 @@ unabove_button_event (WnckWindow *win,
}
}
break;
+ default:
+ break;
}
}
static void
unstick_button_event (WnckWindow *win,
- XEvent *xevent)
+ GTKWDButtonEvent *bevent,
+ GTKWDEventType gType)
{
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
guint state = d->button_states[BUTTON_UNSTICK];
- common_button_event (win, xevent, BUTTON_UNSTICK, 1, _("Unstick"));
+ common_button_event (win, bevent, gType,
+ BUTTON_UNSTICK, 1, _("Unstick"));
- switch (xevent->type) {
- case ButtonRelease:
- if (xevent->xbutton.button == 1)
+ switch (gType) {
+ case GButtonRelease:
+ if (bevent->button == 1)
{
if (state == BUTTON_EVENT_ACTION_STATE)
wnck_window_unstick (win);
}
break;
+ default:
+ break;
}
}
static void
handle_title_button_event (WnckWindow *win,
int action,
- XButtonEvent *event)
+ GTKWDButtonEvent *bevent)
{
switch (action) {
case CLICK_ACTION_SHADE:
@@ -4821,7 +4507,7 @@ handle_title_button_event (WnckWindow *win,
restack_window (win, Below);
break;
case CLICK_ACTION_MENU:
- action_menu_map (win, event->button, event->time);
+ action_menu_map (win, bevent->button, bevent->time);
break;
}
}
@@ -4863,7 +4549,8 @@ dist (double x1, double y1,
static void
title_event (WnckWindow *win,
- XEvent *xevent)
+ GTKWDButtonEvent *bevent,
+ GTKWDEventType gType)
{
static int last_button_num = 0;
static Window last_button_xwindow = None;
@@ -4871,19 +4558,19 @@ title_event (WnckWindow *win,
static int last_button_x = 0;
static int last_button_y = 0;
- if (xevent->type != ButtonPress)
+ if (gType != GButtonPress)
return;
- if (xevent->xbutton.button == 1)
+ if (bevent->button == 1)
{
- if (xevent->xbutton.button == last_button_num &&
- xevent->xbutton.window == last_button_xwindow &&
- xevent->xbutton.time < last_button_time + double_click_timeout &&
- dist (xevent->xbutton.x, xevent->xbutton.y,
+ if (bevent->button == last_button_num &&
+ bevent->window == last_button_xwindow &&
+ bevent->time < last_button_time + double_click_timeout &&
+ dist (bevent->x, bevent->y,
last_button_x, last_button_y) < DOUBLE_CLICK_DISTANCE)
{
handle_title_button_event (win, double_click_action,
- &xevent->xbutton);
+ bevent);
last_button_num = 0;
last_button_xwindow = None;
@@ -4893,115 +4580,1268 @@ title_event (WnckWindow *win,
}
else
{
- last_button_num = xevent->xbutton.button;
- last_button_xwindow = xevent->xbutton.window;
- last_button_time = xevent->xbutton.time;
- last_button_x = xevent->xbutton.x;
- last_button_y = xevent->xbutton.y;
+ last_button_num = bevent->button;
+ last_button_xwindow = bevent->window;
+ last_button_time = bevent->time;
+ last_button_x = bevent->x;
+ last_button_y = bevent->y;
restack_window (win, Above);
- move_resize_window (win, WM_MOVERESIZE_MOVE, xevent);
+ move_resize_window (win, WM_MOVERESIZE_MOVE, bevent);
}
}
- else if (xevent->xbutton.button == 2)
+ else if (bevent->button == 2)
{
handle_title_button_event (win, middle_click_action,
- &xevent->xbutton);
+ bevent);
}
- else if (xevent->xbutton.button == 3)
+ else if (bevent->button == 3)
{
handle_title_button_event (win, right_click_action,
- &xevent->xbutton);
+ bevent);
}
- else if (xevent->xbutton.button == 4 ||
- xevent->xbutton.button == 5)
+ else if (bevent->button == 4 ||
+ bevent->button == 5)
{
- handle_mouse_wheel_title_event (win, xevent->xbutton.button);
+ handle_mouse_wheel_title_event (win, bevent->button);
}
}
static void
frame_common_event (WnckWindow *win,
int direction,
- XEvent *xevent)
+ GTKWDButtonEvent *bevent,
+ GTKWDEventType gType)
{
- if (xevent->type != ButtonPress)
+ if (gType != GButtonPress)
return;
- switch (xevent->xbutton.button) {
+ switch (bevent->button) {
case 1:
- move_resize_window (win, direction, xevent);
+ move_resize_window (win, direction, bevent);
restack_window (win, Above);
break;
case 2:
handle_title_button_event (win, middle_click_action,
- &xevent->xbutton);
+ bevent);
break;
case 3:
handle_title_button_event (win, right_click_action,
- &xevent->xbutton);
+ bevent);
break;
}
}
static void
top_left_event (WnckWindow *win,
- XEvent *xevent)
+ GTKWDButtonEvent *bevent,
+ GTKWDEventType gType)
{
- frame_common_event (win, WM_MOVERESIZE_SIZE_TOPLEFT, xevent);
+ frame_common_event (win, WM_MOVERESIZE_SIZE_TOPLEFT, bevent, gType);
}
static void
top_event (WnckWindow *win,
- XEvent *xevent)
+ GTKWDButtonEvent *bevent,
+ GTKWDEventType gType)
{
- frame_common_event (win, WM_MOVERESIZE_SIZE_TOP, xevent);
+ frame_common_event (win, WM_MOVERESIZE_SIZE_TOP, bevent, gType);
}
static void
top_right_event (WnckWindow *win,
- XEvent *xevent)
+ GTKWDButtonEvent *bevent,
+ GTKWDEventType gType)
{
- frame_common_event (win, WM_MOVERESIZE_SIZE_TOPRIGHT, xevent);
+ frame_common_event (win, WM_MOVERESIZE_SIZE_TOPRIGHT, bevent, gType);
}
static void
left_event (WnckWindow *win,
- XEvent *xevent)
+ GTKWDButtonEvent *bevent,
+ GTKWDEventType gType)
{
- frame_common_event (win, WM_MOVERESIZE_SIZE_LEFT, xevent);
+ frame_common_event (win, WM_MOVERESIZE_SIZE_LEFT, bevent, gType);
}
static void
right_event (WnckWindow *win,
- XEvent *xevent)
+ GTKWDButtonEvent *bevent,
+ GTKWDEventType gType)
{
- frame_common_event (win, WM_MOVERESIZE_SIZE_RIGHT, xevent);
+ frame_common_event (win, WM_MOVERESIZE_SIZE_RIGHT, bevent, gType);
}
static void
bottom_left_event (WnckWindow *win,
- XEvent *xevent)
+ GTKWDButtonEvent *bevent,
+ GTKWDEventType gType)
{
- frame_common_event (win, WM_MOVERESIZE_SIZE_BOTTOMLEFT, xevent);
+ frame_common_event (win, WM_MOVERESIZE_SIZE_BOTTOMLEFT, bevent, gType);
}
static void
bottom_event (WnckWindow *win,
- XEvent *xevent)
+ GTKWDButtonEvent *bevent,
+ GTKWDEventType gType)
{
- frame_common_event (win, WM_MOVERESIZE_SIZE_BOTTOM, xevent);
+ frame_common_event (win, WM_MOVERESIZE_SIZE_BOTTOM, bevent, gType);
}
static void
bottom_right_event (WnckWindow *win,
- XEvent *xevent)
+ GTKWDButtonEvent *bevent,
+ GTKWDEventType gType)
+{
+ frame_common_event (win, WM_MOVERESIZE_SIZE_BOTTOMRIGHT, bevent, gType);
+}
+
+void
+frame_window_realized (GtkWidget *widget,
+ gpointer data)
+{
+ decor_t *d = (decor_t *) data;
+
+ if (d)
+ {
+ GdkWindow *gdk_frame_window = gtk_widget_get_window (d->decor_window);
+ gdk_window_reparent (gdk_frame_window, d->frame_window, 0, 0);
+ gdk_window_lower (gdk_frame_window);
+
+ }
+}
+
+static void
+frame_handle_button_press (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data)
+{
+ decor_t *d = (decor_t *) user_data;
+
+ if (d)
+ {
+ /* Check to see where the event happened and fill out an appropriate
+ * struct
+ */
+
+ int i, j;
+ Bool found = FALSE;
+ Bool event_area = FALSE;
+ Bool exit = FALSE;
+
+ for (i = 0; i < BUTTON_NUM; i++)
+ {
+ /* Hit */
+ if (event->x >= d->button_window_pos[i].x1 &&
+ event->x <= d->button_window_pos[i].x2 &&
+ event->y >= d->button_window_pos[i].y1 &&
+ event->y <= d->button_window_pos[i].y2)
+ {
+ found = TRUE;
+
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ for (i = 0; i < 3; i++)
+ {
+ for (j = 0; j < 3; j++)
+ {
+ if (event->x >= d->event_window_pos[i][j].x1 &&
+ event->x <= d->event_window_pos[i][j].x2 &&
+ event->y >= d->event_window_pos[i][j].y1 &&
+ event->y <= d->event_window_pos[i][j].y2)
+ {
+ found = TRUE;
+ event_area = TRUE;
+
+ exit = TRUE;
+
+ break;
+ }
+ }
+
+ if (exit)
+ break;
+ }
+ }
+
+ if (found)
+ {
+ static event_callback callback[3][3] = {
+ { top_left_event, top_event, top_right_event },
+ { left_event, title_event, right_event },
+ { bottom_left_event, bottom_event, bottom_right_event }
+ };
+ static event_callback button_callback[BUTTON_NUM] = {
+ close_button_event,
+ max_button_event,
+ min_button_event,
+ menu_button_event,
+ shade_button_event,
+ above_button_event,
+ stick_button_event,
+ unshade_button_event,
+ unabove_button_event,
+ unstick_button_event
+ };
+
+ if (d->decorated)
+ {
+ GTKWDButtonEvent bevent;
+ GTKWDEventType gType;
+
+ gType = GButtonPress;
+
+ bevent.window = GDK_WINDOW_XID (d->frame_window);
+ bevent.button = event->button;
+ bevent.x = event->x;
+ bevent.y = event->y;
+ bevent.x_root = event->x_root;
+ bevent.y_root = event->y_root;
+ bevent.time = event->time;
+
+ if (event_area)
+ (*(callback[i][j])) (d->win, &bevent, gType);
+ else
+ (*button_callback[i]) (d->win, &bevent, gType);
+ }
+ }
+ }
+}
+
+static void
+frame_handle_button_release (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer user_data)
+{
+ decor_t *d = (decor_t *) user_data;
+
+ if (d)
+ {
+ /* Check to see where the event happened and fill out an appropriate
+ * struct
+ */
+
+ int i, j;
+ Bool found = FALSE;
+ Bool event_area = FALSE;
+ Bool exit = FALSE;
+
+ for (i = 0; i < BUTTON_NUM; i++)
+ {
+ /* Hit */
+ if (event->x >= d->button_window_pos[i].x1 &&
+ event->x <= d->button_window_pos[i].x2 &&
+ event->y >= d->button_window_pos[i].y1 &&
+ event->y <= d->button_window_pos[i].y2)
+ {
+ found = TRUE;
+
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ for (i = 0; i < 3; i++)
+ {
+ for (j = 0; j < 3; j++)
+ {
+ if (event->x >= d->event_window_pos[i][j].x1 &&
+ event->x <= d->event_window_pos[i][j].x2 &&
+ event->y >= d->event_window_pos[i][j].y1 &&
+ event->y <= d->event_window_pos[i][j].y2)
+ {
+ found = TRUE;
+ event_area = TRUE;
+
+ exit = TRUE;
+
+ break;
+ }
+ }
+
+ if (exit)
+ break;
+
+ }
+ }
+
+ if (found)
+ {
+ static event_callback callback[3][3] = {
+ { top_left_event, top_event, top_right_event },
+ { left_event, title_event, right_event },
+ { bottom_left_event, bottom_event, bottom_right_event }
+ };
+ static event_callback button_callback[BUTTON_NUM] = {
+ close_button_event,
+ max_button_event,
+ min_button_event,
+ menu_button_event,
+ shade_button_event,
+ above_button_event,
+ stick_button_event,
+ unshade_button_event,
+ unabove_button_event,
+ unstick_button_event
+ };
+
+ if (d->decorated)
+ {
+ GTKWDButtonEvent bevent;
+ GTKWDEventType gType;
+
+ gType = GButtonRelease;
+
+ bevent.window = GDK_WINDOW_XID (d->frame_window);
+ bevent.button = event->button;
+ bevent.x = event->x;
+ bevent.y = event->y;
+ bevent.x_root = event->x_root;
+ bevent.y_root = event->y_root;
+ bevent.time = event->time;
+
+ if (event_area)
+ (*callback[i][j]) (d->win, &bevent, gType);
+ else
+ (*button_callback[i]) (d->win, &bevent, gType);
+ }
+ }
+ }
+}
+
+static void
+frame_handle_motion (GtkWidget *widget,
+ GdkEventMotion *event,
+ gpointer user_data)
+{
+ decor_t *d = (decor_t *) user_data;
+
+ static event_callback callback[3][3] = {
+ { top_left_event, top_event, top_right_event },
+ { left_event, title_event, right_event },
+ { bottom_left_event, bottom_event, bottom_right_event }
+ };
+ static event_callback button_callback[BUTTON_NUM] = {
+ close_button_event,
+ max_button_event,
+ min_button_event,
+ menu_button_event,
+ shade_button_event,
+ above_button_event,
+ stick_button_event,
+ unshade_button_event,
+ unabove_button_event,
+ unstick_button_event
+ };
+
+ if (d)
+ {
+ /* Check to see where the event happened and fill out an appropriate
+ * struct
+ */
+
+ int i, j;
+ Bool found = FALSE;
+ Bool event_area = FALSE;
+ Bool send_enter = FALSE;
+ Bool send_leave = FALSE;
+ Bool exit = FALSE;
+
+ /* Check buttons */
+
+ for (i = 0; i < BUTTON_NUM; i++)
+ {
+ /* Hit */
+ if (event->x >= d->button_window_pos[i].x1 &&
+ event->x <= d->button_window_pos[i].x2 &&
+ event->y >= d->button_window_pos[i].y1 &&
+ event->y <= d->button_window_pos[i].y2)
+ {
+ found = TRUE;
+
+ fprintf (stderr, "pointer is in %i\n", i);
+
+ if (d->last_pos_entered != &(d->button_window_pos[i]))
+ {
+ fprintf (stderr, "newly entered area\n");
+ send_enter = TRUE;
+ }
+ if (d->last_pos_entered)
+ {
+ send_leave = TRUE;
+ }
+
+ break;
+ }
+ }
+
+ /* Check event windows */
+
+ exit = FALSE;
+
+ if (!found)
+ {
+ for (i = 0; i < 3; i++)
+ {
+ for (j = 0; j < 3; j++)
+ {
+
+ fprintf (stderr, "event is %f %f pos is %i %i %i %i\n", event->x_root, event->y_root, d->event_window_pos[i][j].x1, d->event_window_pos[i][j].x2, d->event_window_pos[i][j].y1, d->event_window_pos[i][j].y2);
+
+ if (event->x >= d->event_window_pos[i][j].x1 &&
+ event->x <= d->event_window_pos[i][j].x2 &&
+ event->y >= d->event_window_pos[i][j].y1 &&
+ event->y <= d->event_window_pos[i][j].y2)
+ {
+ found = TRUE;
+ event_area = TRUE;
+
+ fprintf (stderr, "pointer is in %i\n", i);
+
+ if (d->last_pos_entered != &(d->button_window_pos[i]))
+ {
+ fprintf (stderr, "newly entered area\n");
+ send_enter = TRUE;
+ }
+ if (d->last_pos_entered)
+ {
+ send_leave = TRUE;
+ }
+
+ exit = TRUE;
+
+ break;
+ }
+ }
+
+ if (exit)
+ break;
+ }
+ }
+
+ if (found)
+ {
+ if (d->decorated)
+ {
+ GTKWDButtonEvent bevent;
+ GTKWDEventType gType;
+
+ bevent.window = GDK_WINDOW_XID (d->frame_window);
+ bevent.x = event->x;
+ bevent.y = event->y;
+ bevent.x_root = event->x_root;
+ bevent.y_root = event->y_root;
+ bevent.time = event->time;
+
+ if (send_enter)
+ {
+ gType = GEnterNotify;
+
+ fprintf (stderr, "sending enter notify\n");
+
+ fprintf (stderr, "i and j are %i %i\n", i, j);
+
+ if (event_area)
+ (*callback[i][j]) (d->win, &bevent, gType);
+ else
+ (*button_callback[i]) (d->win, &bevent, gType);
+
+ }
+
+ if (send_leave)
+ {
+ guint k, l;
+ Bool l_event_area = FALSE;
+ Bool l_found = FALSE;
+
+ gType = GLeaveNotify;
+
+ fprintf (stderr, "sending leave notify\n");
+
+ for (k = 0; k < 3; k++)
+ {
+ if (d->last_pos_entered == &(d->button_window_pos[k]))
+ {
+ l_found = TRUE;
+ break;
+ }
+ }
+
+ exit = FALSE;
+
+ if (!l_found)
+ {
+ for (k = 0; k < 3; k++)
+ {
+ for (l = 0; l < 3; l++)
+ {
+ if (d->last_pos_entered == &(d->event_window_pos[k][l]))
+ {
+ l_found = TRUE;
+ l_event_area = TRUE;
+
+ exit = TRUE;
+
+ break;
+ }
+
+ if (exit)
+ break;
+ }
+ }
+ }
+
+ if (l_found)
+ {
+ if (l_event_area)
+ (*callback[k][l]) (d->win, &bevent, gType);
+ else
+ (*button_callback[k]) (d->win, &bevent, gType);
+ }
+ }
+
+ if (send_enter)
+ {
+ if (event_area)
+ d->last_pos_entered = &d->button_window_pos[i];
+ else
+ d->last_pos_entered = &d->event_window_pos[i][j];
+ }
+ }
+ }
+ else if (d->last_pos_entered && d->decorated)
+ {
+ /* We are not in an event / button window but last_pos_entered
+ * is still set, so send a GLeaveNotify to last_pos_entered
+ * and set it to NULL
+ */
+
+ GTKWDButtonEvent bevent;
+ GTKWDEventType gType;
+
+ bevent.window = GDK_WINDOW_XID (d->frame_window);
+ bevent.x = event->x;
+ bevent.y = event->y;
+ bevent.x_root = event->x_root;
+ bevent.y_root = event->y_root;
+ bevent.time = event->time;
+
+ guint k, l;
+ Bool l_event_area = FALSE;
+ Bool l_found = FALSE;
+
+ gType = GLeaveNotify;
+
+ for (k = 0; k < 3; k++)
+ {
+ if (d->last_pos_entered == &(d->button_window_pos[k]))
+ {
+ l_found = TRUE;
+ break;
+ }
+ }
+
+ exit = FALSE;
+
+ if (!l_found)
+ {
+ for (k = 0; k < 3; k++)
+ {
+ for (l = 0; l < 3; l++)
+ {
+ if (d->last_pos_entered == &(d->event_window_pos[k][l]))
+ {
+ l_found = TRUE;
+ l_event_area = TRUE;
+
+ exit = TRUE;
+
+ break;
+ }
+
+ if (exit)
+ break;
+ }
+ }
+ }
+
+ if (l_found)
+ {
+ if (l_event_area)
+ (*callback[k][l]) (d->win, &bevent, gType);
+ else
+ (*button_callback[k]) (d->win, &bevent, gType);
+ }
+
+ d->last_pos_entered = NULL;
+ }
+
+ }
+}
+
+static void
+window_name_changed (WnckWindow *win)
+{
+ decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+
+ if (d->decorated)
+ {
+ if (!update_window_decoration_size (win))
+ queue_decor_draw (d);
+ }
+}
+
+static void
+window_geometry_changed (WnckWindow *win)
+{
+ decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+
+ if (d->decorated)
+ {
+ int width, height;
+
+ wnck_window_get_client_window_geometry (win, NULL, NULL, &width,
+ &height);
+
+ if (width != d->client_width || height != d->client_height)
+ {
+ d->client_width = width;
+ d->client_height = height;
+
+ update_window_decoration_size (win);
+ update_event_windows (win);
+
+ //if (!d->frame_window)
+ //queue_decor_draw (d);
+ }
+ }
+}
+
+static void
+window_icon_changed (WnckWindow *win)
+{
+ decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+
+ if (d->decorated)
+ {
+ update_window_decoration_icon (win);
+ queue_decor_draw (d);
+ }
+}
+
+static void
+window_state_changed (WnckWindow *win)
+{
+ decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+
+ if (d->decorated)
+ {
+ update_window_decoration_state (win);
+ if (!update_window_decoration_size (win))
+ queue_decor_draw (d);
+
+ update_event_windows (win);
+ }
+}
+
+static void
+window_actions_changed (WnckWindow *win)
+{
+ decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+
+ if (d->decorated)
+ {
+ update_window_decoration_actions (win);
+ if (!update_window_decoration_size (win))
+ queue_decor_draw (d);
+
+ update_event_windows (win);
+ }
+}
+
+static void
+connect_window (WnckWindow *win)
+{
+ g_signal_connect_object (win, "name_changed",
+ G_CALLBACK (window_name_changed),
+ 0, 0);
+ g_signal_connect_object (win, "geometry_changed",
+ G_CALLBACK (window_geometry_changed),
+ 0, 0);
+ g_signal_connect_object (win, "icon_changed",
+ G_CALLBACK (window_icon_changed),
+ 0, 0);
+ g_signal_connect_object (win, "state_changed",
+ G_CALLBACK (window_state_changed),
+ 0, 0);
+ g_signal_connect_object (win, "actions_changed",
+ G_CALLBACK (window_actions_changed),
+ 0, 0);
+}
+
+static void
+add_frame_window (WnckWindow *win,
+ Window frame,
+ Bool mode)
+{
+ Display *xdisplay;
+ XSetWindowAttributes attr;
+ gulong xid = wnck_window_get_xid (win);
+ decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+ gint i, j;
+
+ xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+
+ d->active = wnck_window_is_active (win);
+ d->win = win;
+ d->last_pos_entered = NULL;
+
+ attr.event_mask = ButtonPressMask | EnterWindowMask | LeaveWindowMask |
+ ExposureMask;
+ attr.override_redirect = TRUE;
+
+ gdk_error_trap_push ();
+
+ if (mode)
+ {
+ GdkScreen *screen = gdk_display_get_default_screen (gdk_display_get_default ());
+ GdkColormap *colormap;
+
+ d->frame_window = create_gdk_window (frame);
+ d->decor_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+ if (gdk_drawable_get_depth (GDK_DRAWABLE (d->frame_window)) == 24)
+ colormap = gdk_screen_get_rgb_colormap (screen);
+ else if (gdk_drawable_get_depth (GDK_DRAWABLE (d->frame_window)) == 32)
+ colormap = gdk_screen_get_rgba_colormap (screen);
+
+ gtk_widget_set_colormap (d->decor_window, colormap);
+
+ d->decor_image = gtk_image_new ();
+
+ gtk_widget_set_colormap (d->decor_image, colormap);
+
+ d->decor_event_box = gtk_event_box_new ();
+ gtk_event_box_set_visible_window (GTK_EVENT_BOX (d->decor_event_box), FALSE);
+ gtk_widget_set_events (d->decor_event_box, GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK);
+
+ g_signal_connect (G_OBJECT (d->decor_event_box), "button-press-event",
+ G_CALLBACK (frame_handle_button_press),
+ (gpointer) (d));
+
+ g_signal_connect (G_OBJECT (d->decor_event_box), "button-release-event",
+ G_CALLBACK (frame_handle_button_release),
+ (gpointer) (d));
+
+ g_signal_connect (G_OBJECT (d->decor_event_box), "motion-notify-event",
+ G_CALLBACK (frame_handle_motion),
+ (gpointer) (d));
+
+ gtk_container_add (GTK_CONTAINER (d->decor_event_box), d->decor_image);
+ gtk_event_box_set_above_child (GTK_EVENT_BOX (d->decor_event_box), TRUE);
+ gtk_widget_show_all (d->decor_event_box);
+ gtk_window_set_decorated (GTK_WINDOW (d->decor_window), FALSE);
+ gtk_window_set_default_size (GTK_WINDOW (d->decor_window), 1000, 1000);
+ gtk_container_add (GTK_CONTAINER (d->decor_window), d->decor_event_box);
+
+ /* Assumed realization happens here */
+
+ g_signal_connect (G_OBJECT (d->decor_window), "realize",
+ G_CALLBACK (frame_window_realized), (gpointer) d);
+
+ gtk_widget_show_all (d->decor_window);
+ gtk_widget_show (d->decor_window);
+
+ g_object_set_data (G_OBJECT (d->frame_window), "client_wnck_window", win);
+ }
+ else
+ {
+ d->frame_window = NULL;
+
+ for (i = 0; i < 3; i++)
+ {
+ for (j = 0; j < 3; j++)
+ {
+ d->event_windows[i][j] =
+ XCreateWindow (xdisplay,
+ frame,
+ 0, 0, 1, 1, 0,
+ CopyFromParent, CopyFromParent, CopyFromParent,
+ CWOverrideRedirect | CWEventMask, &attr);
+
+ if (cursor[i][j].cursor)
+ XDefineCursor (xdisplay, d->event_windows[i][j],
+ cursor[i][j].cursor);
+ }
+ }
+
+ attr.event_mask |= ButtonReleaseMask;
+
+ for (i = 0; i < BUTTON_NUM; i++)
+ {
+ d->button_windows[i] =
+ XCreateWindow (xdisplay,
+ frame,
+ 0, 0, 1, 1, 0,
+ CopyFromParent, CopyFromParent, CopyFromParent,
+ CWOverrideRedirect | CWEventMask, &attr);
+
+ d->button_states[i] = 0;
+ }
+ }
+
+ gdk_display_sync (gdk_display_get_default ());
+ if (!gdk_error_trap_pop ())
+ {
+ if (get_mwm_prop (xid) & (MWM_DECOR_ALL | MWM_DECOR_TITLE))
+ d->decorated = TRUE;
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ g_hash_table_insert (frame_table,
+ GINT_TO_POINTER (d->event_windows[i][j]),
+ GINT_TO_POINTER (xid));
+
+ for (i = 0; i < BUTTON_NUM; i++)
+ g_hash_table_insert (frame_table,
+ GINT_TO_POINTER (d->button_windows[i]),
+ GINT_TO_POINTER (xid));
+
+ if (d->frame_window)
+ {
+ g_hash_table_insert (frame_table,
+ GINT_TO_POINTER (frame),
+ GINT_TO_POINTER (xid));
+ }
+ update_window_decoration_state (win);
+ update_window_decoration_actions (win);
+ update_window_decoration_icon (win);
+ update_window_decoration_size (win);
+
+ update_event_windows (win);
+ }
+ else
+ {
+ memset (d->event_windows, 0, sizeof (d->event_windows));
+ }
+
+ connect_window (win);
+}
+
+static gboolean
+update_switcher_window (WnckWindow *win,
+ Window selected)
+{
+ decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+ GdkPixmap *pixmap, *buffer_pixmap = NULL;
+ gint height, width = 0;
+ WnckWindow *selected_win;
+ Display *xdisplay;
+
+ xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+
+ wnck_window_get_client_window_geometry (win, NULL, NULL, &width, NULL);
+
+ decor_get_default_layout (&switcher_context, width, 1, &d->border_layout);
+
+ width = d->border_layout.width;
+ height = d->border_layout.height;
+
+ d->decorated = FALSE;
+ d->draw = draw_switcher_decoration;
+
+ if (!d->pixmap && switcher_pixmap)
+ {
+ g_object_ref (G_OBJECT (switcher_pixmap));
+ d->pixmap = switcher_pixmap;
+ }
+
+ if (!d->buffer_pixmap && switcher_buffer_pixmap)
+ {
+ g_object_ref (G_OBJECT (switcher_buffer_pixmap));
+ d->buffer_pixmap = switcher_buffer_pixmap;
+ }
+
+ if (!d->width)
+ d->width = switcher_width;
+
+ if (!d->height)
+ d->height = switcher_height;
+
+ selected_win = wnck_window_get (selected);
+ if (selected_win)
+ {
+ glong name_length;
+ PangoLayoutLine *line;
+ const gchar *name;
+
+ if (d->name)
+ {
+ g_free (d->name);
+ d->name = NULL;
+ }
+
+ name = wnck_window_get_name (selected_win);
+ if (name && (name_length = strlen (name)))
+ {
+ if (!d->layout)
+ {
+ d->layout = pango_layout_new (pango_context);
+ if (d->layout)
+ pango_layout_set_wrap (d->layout, PANGO_WRAP_CHAR);
+ }
+
+ if (d->layout)
+ {
+ int tw;
+
+ tw = width - switcher_context.left_space -
+ switcher_context.right_space - 64;
+ pango_layout_set_auto_dir (d->layout, FALSE);
+ pango_layout_set_width (d->layout, tw * PANGO_SCALE);
+ pango_layout_set_text (d->layout, name, name_length);
+
+ line = pango_layout_get_line (d->layout, 0);
+
+ name_length = line->length;
+ if (pango_layout_get_line_count (d->layout) > 1)
+ {
+ if (name_length < 4)
+ {
+ g_object_unref (G_OBJECT (d->layout));
+ d->layout = NULL;
+ }
+ else
+ {
+ d->name = g_strndup (name, name_length);
+ strcpy (d->name + name_length - 3, "...");
+ }
+ }
+ else
+ d->name = g_strndup (name, name_length);
+
+ if (d->layout)
+ pango_layout_set_text (d->layout, d->name, name_length);
+ }
+ }
+ else if (d->layout)
+ {
+ g_object_unref (G_OBJECT (d->layout));
+ d->layout = NULL;
+ }
+ }
+
+ if (selected != switcher_selected_window)
+ {
+ gtk_label_set_text (GTK_LABEL (switcher_label), "");
+ if (selected_win && d->name)
+ gtk_label_set_text (GTK_LABEL (switcher_label), d->name);
+ switcher_selected_window = selected;
+ }
+
+ if (width == d->width && height == d->height)
+ {
+ if (!d->gc)
+ d->gc = gdk_gc_new (d->pixmap);
+
+ if (!d->picture)
+ d->picture =
+ XRenderCreatePicture (xdisplay,
+ GDK_PIXMAP_XID (d->buffer_pixmap),
+ xformat, 0, NULL);
+
+ queue_decor_draw (d);
+ return FALSE;
+ }
+
+ pixmap = create_pixmap (width, height, 32);
+ if (!pixmap)
+ return FALSE;
+
+ buffer_pixmap = create_pixmap (width, height, 32);
+ if (!buffer_pixmap)
+ {
+ g_object_unref (G_OBJECT (pixmap));
+ return FALSE;
+ }
+
+ if (switcher_pixmap)
+ g_object_unref (G_OBJECT (switcher_pixmap));
+
+ if (switcher_buffer_pixmap)
+ g_object_unref (G_OBJECT (switcher_buffer_pixmap));
+
+ if (d->pixmap)
+ g_object_unref (G_OBJECT (d->pixmap));
+
+ if (d->buffer_pixmap)
+ g_object_unref (G_OBJECT (d->buffer_pixmap));
+
+ if (d->gc)
+ g_object_unref (G_OBJECT (d->gc));
+
+ if (d->picture)
+ XRenderFreePicture (xdisplay, d->picture);
+
+ switcher_pixmap = pixmap;
+ switcher_buffer_pixmap = buffer_pixmap;
+
+ switcher_width = width;
+ switcher_height = height;
+
+ g_object_ref (G_OBJECT (pixmap));
+ g_object_ref (G_OBJECT (buffer_pixmap));
+
+ d->pixmap = pixmap;
+ d->buffer_pixmap = buffer_pixmap;
+ d->gc = gdk_gc_new (pixmap);
+
+ d->picture = XRenderCreatePicture (xdisplay, GDK_PIXMAP_XID (buffer_pixmap),
+ xformat, 0, NULL);
+
+ d->width = width;
+ d->height = height;
+
+ d->prop_xid = wnck_window_get_xid (win);
+
+ queue_decor_draw (d);
+
+ return TRUE;
+}
+
+static void
+remove_frame_window (WnckWindow *win)
+{
+ decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+ Display *xdisplay;
+
+ xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+
+ if (d->pixmap)
+ {
+ g_object_unref (G_OBJECT (d->pixmap));
+ d->pixmap = NULL;
+ }
+
+ if (d->buffer_pixmap)
+ {
+ g_object_unref (G_OBJECT (d->buffer_pixmap));
+ d->buffer_pixmap = NULL;
+ }
+
+ if (d->gc)
+ {
+ g_object_unref (G_OBJECT (d->gc));
+ d->gc = NULL;
+ }
+
+ if (d->picture && !d->frame_window)
+ {
+ XRenderFreePicture (xdisplay, d->picture);
+ d->picture = 0;
+ }
+
+ if (d->name)
+ {
+ g_free (d->name);
+ d->name = NULL;
+ }
+
+ if (d->layout)
+ {
+ g_object_unref (G_OBJECT (d->layout));
+ d->layout = NULL;
+ }
+
+ if (d->icon)
+ {
+ cairo_pattern_destroy (d->icon);
+ d->icon = NULL;
+ }
+
+ if (d->icon_pixmap)
+ {
+ g_object_unref (G_OBJECT (d->icon_pixmap));
+ d->icon_pixmap = NULL;
+ }
+
+ if (d->icon_pixbuf)
+ {
+ g_object_unref (G_OBJECT (d->icon_pixbuf));
+ d->icon_pixbuf = NULL;
+ }
+
+ if (d->force_quit_dialog)
+ {
+ GtkWidget *dialog = d->force_quit_dialog;
+
+ d->force_quit_dialog = NULL;
+ gtk_widget_destroy (dialog);
+ }
+
+ if (d->frame_window)
+ {
+ gdk_window_destroy (d->frame_window);
+ d->frame_window = NULL;
+ }
+
+ if (d->decor_image)
+ {
+ g_object_unref (d->decor_window);
+ d->decor_image = NULL;
+ }
+
+ if (d->decor_event_box)
+ {
+ g_object_unref (d->decor_event_box);
+ d->decor_event_box = NULL;
+ }
+
+ if (d->decor_window)
+ {
+ g_object_unref (d->decor_window);
+ d->decor_window = NULL;
+ }
+
+
+
+ d->width = 0;
+ d->height = 0;
+
+ d->decorated = FALSE;
+
+ d->state = 0;
+ d->actions = 0;
+
+ d->context = NULL;
+ d->shadow = NULL;
+
+ draw_list = g_slist_remove (draw_list, d);
+}
+
+static void
+active_window_changed (WnckScreen *screen)
{
- frame_common_event (win, WM_MOVERESIZE_SIZE_BOTTOMRIGHT, xevent);
+ WnckWindow *win;
+ decor_t *d;
+
+ win = wnck_screen_get_previously_active_window (screen);
+ if (win)
+ {
+ d = g_object_get_data (G_OBJECT (win), "decor");
+ if (d && d->pixmap)
+ {
+ d->active = wnck_window_is_active (win);
+ queue_decor_draw (d);
+ }
+ }
+
+ win = wnck_screen_get_active_window (screen);
+ if (win)
+ {
+ d = g_object_get_data (G_OBJECT (win), "decor");
+ if (d && d->pixmap)
+ {
+ d->active = wnck_window_is_active (win);
+ queue_decor_draw (d);
+ }
+ }
+}
+
+static void
+window_opened (WnckScreen *screen,
+ WnckWindow *win)
+{
+ decor_t *d;
+ Window window;
+ gulong xid;
+
+ d = calloc (1, sizeof (decor_t));
+ if (!d)
+ return;
+
+ wnck_window_get_client_window_geometry (win, NULL, NULL,
+ &d->client_width,
+ &d->client_height);
+
+ d->draw = theme_draw_window_decoration;
+ d->pixmap = NULL;
+ d->gc = NULL;
+ d->buffer_pixmap = NULL;
+ d->picture = None;
+
+ g_object_set_data (G_OBJECT (win), "decor", d);
+
+ xid = wnck_window_get_xid (win);
+
+ if (get_window_prop (xid, select_window_atom, &window))
+ {
+ d->prop_xid = wnck_window_get_xid (win);
+ update_switcher_window (win, window);
+ }
+ else if (get_window_prop (xid, frame_input_window_atom, &window))
+ {
+ add_frame_window (win, window, FALSE);
+ }
+ else if (get_window_prop (xid, frame_output_window_atom, &window))
+ {
+ add_frame_window (win, window, TRUE);
+ }
+}
+
+static void
+window_closed (WnckScreen *screen,
+ WnckWindow *win)
+{
+ Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+ decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
+
+ remove_frame_window (win);
+
+ g_object_set_data (G_OBJECT (win), "decor", NULL);
+
+ gdk_error_trap_push ();
+ XDeleteProperty (xdisplay, wnck_window_get_xid (win), win_decor_atom);
+ gdk_display_sync (gdk_display_get_default ());
+ gdk_error_trap_pop ();
+
+ g_free (d);
}
static void
+connect_screen (WnckScreen *screen)
+{
+ GList *windows;
+
+ g_signal_connect_object (G_OBJECT (screen), "active_window_changed",
+ G_CALLBACK (active_window_changed),
+ 0, 0);
+ g_signal_connect_object (G_OBJECT (screen), "window_opened",
+ G_CALLBACK (window_opened),
+ 0, 0);
+ g_signal_connect_object (G_OBJECT (screen), "window_closed",
+ G_CALLBACK (window_closed),
+ 0, 0);
+
+ windows = wnck_screen_get_windows (screen);
+ while (windows != NULL)
+ {
+ window_opened (screen, windows->data);
+ windows = windows->next;
+ }
+}
+
+
+
+static void
force_quit_dialog_realize (GtkWidget *dialog,
void *data)
{
@@ -5303,6 +6143,7 @@ event_filter_func (GdkXEvent *gdkxevent,
case DestroyNotify:
g_hash_table_remove (frame_table,
GINT_TO_POINTER (xevent->xproperty.window));
+ // XXX
break;
case ClientMessage:
if (xevent->xclient.message_type == toolkit_action_atom)
@@ -5370,15 +6211,59 @@ event_filter_func (GdkXEvent *gdkxevent,
if (d->decorated)
{
gint i, j;
+ GTKWDButtonEvent bevent;
+ GTKWDEventType gType;
+
+ bevent.window = xevent->xany.window;
+
+ switch (xevent->type)
+ {
+ case ButtonPress:
+ gType = GButtonPress;
+ bevent.button = xevent->xbutton.button;
+ bevent.x = xevent->xbutton.x;
+ bevent.y = xevent->xbutton.y;
+ bevent.x_root = xevent->xbutton.x_root;
+ bevent.y_root = xevent->xbutton.y_root;
+ bevent.time = xevent->xbutton.time;
+ break;
+ case ButtonRelease:
+ gType = GButtonRelease;
+ bevent.button = xevent->xbutton.button;
+ bevent.x = xevent->xbutton.x;
+ bevent.y = xevent->xbutton.y;
+ bevent.x_root = xevent->xbutton.x_root;
+ bevent.y_root = xevent->xbutton.y_root;
+ bevent.time = xevent->xbutton.time;
+ break;
+ case EnterNotify:
+ gType = GEnterNotify;
+ bevent.x = xevent->xcrossing.x;
+ bevent.y = xevent->xcrossing.y;
+ bevent.x_root = xevent->xcrossing.x_root;
+ bevent.y_root = xevent->xcrossing.y_root;
+ bevent.time = xevent->xcrossing.time;
+ break;
+ case LeaveNotify:
+ gType = GLeaveNotify;
+ bevent.x = xevent->xcrossing.x;
+ bevent.y = xevent->xcrossing.y;
+ bevent.x_root = xevent->xcrossing.x_root;
+ bevent.y_root = xevent->xcrossing.y_root;
+ bevent.time = xevent->xcrossing.time;
+ break;
+ default:
+ break;
+ }
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
if (d->event_windows[i][j] == xevent->xany.window)
- (*callback[i][j]) (win, xevent);
+ (*callback[i][j]) (win, &bevent, gType);
for (i = 0; i < BUTTON_NUM; i++)
if (d->button_windows[i] == xevent->xany.window)
- (*button_callback[i]) (win, xevent);
+ (*button_callback[i]) (win, &bevent, gType);
}
}
}
@@ -5660,7 +6545,13 @@ draw_border_shape (Display *xdisplay,
decor_get_default_layout (c, 1, 1, &d.border_layout);
screen = gdk_display_get_default_screen (gdk_display_get_default ());
- colormap = gdk_screen_get_rgba_colormap (screen);
+ if (gdk_drawable_get_depth (GDK_DRAWABLE (d.pixmap)) == 32)
+ colormap = gdk_screen_get_rgba_colormap (screen);
+ else
+ colormap = gdk_screen_get_rgb_colormap (screen);
+
+ fprintf (stderr, "depths for colormap are %i %i\n", gdk_drawable_get_depth (GDK_DRAWABLE (d.pixmap)),
+ colormap->visual->depth);
gdk_drawable_set_colormap (d.pixmap, colormap);
@@ -7078,8 +7969,6 @@ main (int argc, char *argv[])
}
#endif
- fprintf (stderr, "starting decor\n");
-
gdkdisplay = gdk_display_get_default ();
xdisplay = gdk_x11_display_get_xdisplay (gdkdisplay);
gdkscreen = gdk_display_get_default_screen (gdkdisplay);
@@ -7145,6 +8034,7 @@ main (int argc, char *argv[])
xformat = XRenderFindStandardFormat (xdisplay, PictStandardARGB32);
frame_table = g_hash_table_new (NULL, NULL);
+ //rame_window_table = g_hash_table_new (NULL, NULL);
if (!create_tooltip_window ())
{