This commit is contained in:
rhp 2001-06-12 04:38:24 +00:00
parent 073a5d4ea9
commit 29c0947f3c
12 changed files with 481 additions and 39 deletions

View File

@ -47,6 +47,9 @@ struct _MetaFrameActionGrab
static void clear_tip (MetaFrame *frame); static void clear_tip (MetaFrame *frame);
static guint draw_handler = 0;
static GSList *draw_pending = NULL;
static void static void
meta_frame_init_info (MetaFrame *frame, meta_frame_init_info (MetaFrame *frame,
MetaFrameInfo *info) MetaFrameInfo *info)
@ -93,26 +96,6 @@ meta_frame_init_info (MetaFrame *frame,
info->current_control_state = META_STATE_PRELIGHT; info->current_control_state = META_STATE_PRELIGHT;
} }
static void
pango_hack_start (MetaDisplay *display)
{
if (display->server_grab_count > 0)
{
meta_verbose ("Pango workaround, ungrabbing server\n");
XUngrabServer (display->xdisplay);
}
}
static void
pango_hack_end (MetaDisplay *display)
{
if (display->server_grab_count > 0)
{
meta_verbose ("Pango workaround, regrabbing server\n");
XGrabServer (display->xdisplay);
}
}
void void
meta_frame_calc_geometry (MetaFrame *frame, meta_frame_calc_geometry (MetaFrame *frame,
int child_width, int child_height, int child_width, int child_height,
@ -140,7 +123,10 @@ meta_frame_calc_geometry (MetaFrame *frame,
info.height = child_height; info.height = child_height;
if (!frame->theme_acquired) if (!frame->theme_acquired)
frame->theme_data = window->screen->engine->acquire_frame (&info); {
frame->theme_data = window->screen->engine->acquire_frame (&info);
frame->theme_acquired = TRUE;
}
geom.left_width = 0; geom.left_width = 0;
geom.right_width = 0; geom.right_width = 0;
@ -152,10 +138,8 @@ meta_frame_calc_geometry (MetaFrame *frame,
geom.shape_mask = None; geom.shape_mask = None;
pango_hack_start (frame->window->display);
window->screen->engine->fill_frame_geometry (&info, &geom, window->screen->engine->fill_frame_geometry (&info, &geom,
frame->theme_data); frame->theme_data);
pango_hack_end (frame->window->display);
*geomp = geom; *geomp = geom;
} }
@ -191,7 +175,7 @@ set_background_color (MetaFrame *frame)
{ {
XSetWindowAttributes attrs; XSetWindowAttributes attrs;
attrs.background_pixel = None; attrs.background_pixel = frame->bg_pixel;
XChangeWindowAttributes (frame->window->display->xdisplay, XChangeWindowAttributes (frame->window->display->xdisplay,
frame->xwindow, frame->xwindow,
CWBackPixel, CWBackPixel,
@ -226,6 +210,9 @@ meta_window_ensure_frame (MetaWindow *window)
frame->bg_pixel = 0; frame->bg_pixel = 0;
frame->mapped = FALSE; frame->mapped = FALSE;
frame->edges_exposed = FALSE;
frame->title_exposed = FALSE;
attrs.event_mask = EVENT_MASK; attrs.event_mask = EVENT_MASK;
@ -283,6 +270,11 @@ meta_window_destroy_frame (MetaWindow *window)
frame = window->frame; frame = window->frame;
if (frame->title_exposed || frame->edges_exposed)
{
draw_pending = g_slist_remove (draw_pending, frame);
}
if (frame->tooltip_timeout) if (frame->tooltip_timeout)
clear_tip (frame); clear_tip (frame);
@ -403,12 +395,10 @@ meta_frame_draw_now (MetaFrame *frame,
info.drawable = p; info.drawable = p;
info.xoffset = - x; info.xoffset = - x;
info.yoffset = - y; info.yoffset = - y;
pango_hack_start (frame->window->display);
frame->window->screen->engine->expose_frame (&info, frame->window->screen->engine->expose_frame (&info,
0, 0, width, height, 0, 0, width, height,
frame->theme_data); frame->theme_data);
pango_hack_end (frame->window->display);
XCopyArea (frame->window->display->xdisplay, XCopyArea (frame->window->display->xdisplay,
p, frame->xwindow, p, frame->xwindow,
@ -419,13 +409,51 @@ meta_frame_draw_now (MetaFrame *frame,
XFreePixmap (frame->window->display->xdisplay, XFreePixmap (frame->window->display->xdisplay,
p); p);
frame->title_exposed = FALSE;
frame->edges_exposed = FALSE;
}
static gboolean
draw_idle (gpointer data)
{
GSList *tmp;
tmp = draw_pending;
while (tmp != NULL)
{
int yoffset;
MetaFrame *frame;
frame = tmp->data;
yoffset = 0;
if (!frame->title_exposed)
yoffset += frame->child_y;
meta_frame_draw_now (frame, 0, yoffset,
frame->rect.width,
frame->rect.height - yoffset);
tmp = tmp->next;
}
g_slist_free (draw_pending);
draw_pending = NULL;
draw_handler = 0;
return FALSE;
} }
void void
meta_frame_queue_draw (MetaFrame *frame) meta_frame_queue_draw (MetaFrame *frame)
{ {
/* FIXME, actually queue */ if (draw_handler == 0)
meta_frame_draw_now (frame, 0, 0, -1, -1); draw_handler = g_idle_add (draw_idle, NULL);
if (!(frame->title_exposed || frame->edges_exposed))
draw_pending = g_slist_prepend (draw_pending, frame);
frame->title_exposed = TRUE;
frame->edges_exposed = TRUE;
} }
static void static void
@ -938,11 +966,13 @@ meta_frame_event (MetaFrame *frame,
case KeymapNotify: case KeymapNotify:
break; break;
case Expose: case Expose:
meta_frame_draw_now (frame, {
event->xexpose.x, gboolean title_was_exposed = frame->title_exposed;
event->xexpose.y, meta_frame_queue_draw (frame);
event->xexpose.width, if (!title_was_exposed &&
event->xexpose.height); event->xexpose.y > frame->child_y)
frame->title_exposed = FALSE;
}
break; break;
case GraphicsExpose: case GraphicsExpose:
break; break;

View File

@ -63,6 +63,10 @@ struct _MetaFrame
guint theme_acquired : 1; guint theme_acquired : 1;
guint mapped : 1; guint mapped : 1;
/* world's lamest expose compression */
guint edges_exposed : 1;
guint title_exposed : 1;
}; };
void meta_window_ensure_frame (MetaWindow *window); void meta_window_ensure_frame (MetaWindow *window);

125
src/frames.c Normal file
View File

@ -0,0 +1,125 @@
/* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include "frames.h"
static void meta_frames_class_init (MetaFramesClass *klass);
static void meta_frames_init (MetaFrames *frames);
static void meta_frames_destroy (GtkObject *object);
static void meta_frames_finalize (GObject *object);
static void meta_frames_style_set (GtkWidget *widget,
GtkStyle *prev_style);
static GtkWidgetClass *parent_class = NULL;
static guint signals[LAST_SIGNAL];
GtkType
meta_frames_get_type (void)
{
static GtkType frames_type = 0;
if (!frames_type)
{
static const GtkTypeInfo frames_info =
{
"MetaFrames",
sizeof (MetaFrames),
sizeof (MetaFramesClass),
(GtkClassInitFunc) meta_frames_class_init,
(GtkObjectInitFunc) meta_frames_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL,
};
frames_type = gtk_type_unique (GTK_TYPE_WIDGET, &frames_info);
}
return frames_type;
}
static void
meta_frames_class_init (MetaFramesClass *class)
{
GObjectClass *gobject_class;
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
gobject_class = G_OBJECT_CLASS (class);
object_class = (GtkObjectClass*) class;
widget_class = (GtkWidgetClass*) class;
parent_class = g_type_class_peek_parent (class);
gobject_class->finalize = meta_frames_finalize;
object_class->destroy = meta_frames_destroy;
widget_class->style_set = meta_frames_style_set;
gtk_widget_class_install_style_property (widget_class,
g_param_spec_int ("slider_width",
_("Slider Width"),
_("Width of scrollbar or scale thumb"),
0,
G_MAXINT,
14,
G_PARAM_READABLE));
}
static void
meta_frames_init (MetaFrames *frames)
{
GTK_WINDOW (frames)->type = GTK_WINDOW_POPUP;
}
static void
meta_frames_destroy (GtkObject *object)
{
}
static void
meta_frames_finalize (GObject *object)
{
}
void
meta_frames_manage_window (MetaFrames *frames,
GdkWindow *window)
{
g_return_if_fail (GDK_IS_WINDOW (window));
gdk_window_set_user_data (window, frames);
gdk_window_set_events (window,
GDK_EXPOSURE_MASK |
GDK_POINTER_MOTION_MASK |
GDK_POINTER_MOTION_HINT_MASK |
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_STRUCTURE_MASK);
}

60
src/frames.h Normal file
View File

@ -0,0 +1,60 @@
/* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef META_FRAMES_H
#define META_FRAMES_H
#include <gtk/gtk.h>
/* This is one widget that manages all the window frames
* as subwindows.
*/
#define META_TYPE_FRAMES (meta_frames_get_type ())
#define META_FRAMES(obj) (META_CHECK_CAST ((obj), META_TYPE_FRAMES, MetaFrames))
#define META_FRAMES_CLASS(klass) (META_CHECK_CLASS_CAST ((klass), META_TYPE_FRAMES, MetaFramesClass))
#define META_IS_FRAMES(obj) (META_CHECK_TYPE ((obj), META_TYPE_FRAMES))
#define META_IS_FRAMES_CLASS(klass) (META_CHECK_CLASS_TYPE ((klass), META_TYPE_FRAMES))
#define META_FRAMES_GET_CLASS(obj) (META_CHECK_GET_CLASS ((obj), META_TYPE_FRAMES, MetaFramesClass))
typedef struct _MetaFrames MetaFrames;
typedef struct _MetaFramesClass MetaFramesClass;
struct _MetaFrames
{
GtkWindow parent_instance;
};
struct _MetaFramesClass
{
GtkWindowClass parent_class;
};
GType meta_frames_get_type (void) G_GNUC_CONST;
MetaFrames *meta_frames_new (void);
void meta_frames_manage_window (MetaFrames *frames,
GdkWindow *window);
#endif

View File

@ -39,6 +39,7 @@ main (int argc, char **argv)
{ {
struct sigaction act; struct sigaction act;
sigset_t empty_mask; sigset_t empty_mask;
char *display_name;
sigemptyset (&empty_mask); sigemptyset (&empty_mask);
act.sa_handler = SIG_IGN; act.sa_handler = SIG_IGN;
@ -57,6 +58,16 @@ main (int argc, char **argv)
g_type_init (0); /* grumble */ g_type_init (0); /* grumble */
meta_errors_init (); meta_errors_init ();
if (g_getenv ("METACITY_DISPLAY"))
{
meta_verbose ("Using METACITY_DISPLAY %s\n",
g_getenv ("METACITY_DISPLAY"));
display_name =
g_strconcat ("DISPLAY=", g_getenv ("METACITY_DISPLAY"), NULL);
putenv (display_name);
/* DO NOT FREE display_name, putenv() sucks */
}
if (!meta_display_open (NULL)) if (!meta_display_open (NULL))
meta_exit (META_EXIT_ERROR); meta_exit (META_EXIT_ERROR);

View File

@ -29,5 +29,5 @@ if test -z "$ONLY_WM"; then
fi fi
if test -z "$ONLY_SETUP"; then if test -z "$ONLY_SETUP"; then
METACITY_UISLAVE_DIR=./uislave DISPLAY=:1 exec unst libtool --mode=execute $DEBUG ./metacity METACITY_UISLAVE_DIR=./uislave METACITY_DISPLAY=:1 exec unst libtool --mode=execute $DEBUG ./metacity
fi fi

View File

@ -194,6 +194,9 @@ meta_screen_new (MetaDisplay *display,
screen); screen);
screen->stack = meta_stack_new (screen); screen->stack = meta_stack_new (screen);
/* hack pango to get its coverage window */
meta_screen_get_pango_context (screen, NULL, PANGO_DIRECTION_LTR);
meta_verbose ("Added screen %d ('%s') root 0x%lx\n", meta_verbose ("Added screen %d ('%s') root 0x%lx\n",
screen->number, screen->screen_name, screen->xroot); screen->number, screen->screen_name, screen->xroot);
@ -354,7 +357,26 @@ meta_screen_get_pango_context (MetaScreen *screen,
* are honored. * are honored.
*/ */
pango_context_set_base_dir (ctx, direction); pango_context_set_base_dir (ctx, direction);
pango_context_set_font_description (ctx, desc);
if (desc == NULL)
{
desc = pango_font_description_from_string ("Sans 12");
pango_context_set_font_description (ctx, desc);
pango_font_description_free (desc);
}
else
{
pango_context_set_font_description (ctx, desc);
}
{
/* Make Pango grab server now not later */
PangoLayout *hack;
hack = pango_layout_new (ctx);
pango_layout_set_text (hack, "foo", -1);
pango_layout_get_extents (hack, NULL, NULL);
g_object_unref (G_OBJECT (hack));
}
screen->pango_context = ctx; screen->pango_context = ctx;
} }

View File

@ -601,7 +601,8 @@ default_expose_frame (MetaFrameInfo *info,
draw_current_control_bg (info, &fgeom); draw_current_control_bg (info, &fgeom);
if (fgeom.title_rect.width > 0 && fgeom.title_rect.height > 0) if (y < fgeom.top_height &&
fgeom.title_rect.width > 0 && fgeom.title_rect.height > 0)
{ {
int layout_y; int layout_y;
MetaRectangle clip; MetaRectangle clip;

125
src/uislave/frames.c Normal file
View File

@ -0,0 +1,125 @@
/* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include "frames.h"
static void meta_frames_class_init (MetaFramesClass *klass);
static void meta_frames_init (MetaFrames *frames);
static void meta_frames_destroy (GtkObject *object);
static void meta_frames_finalize (GObject *object);
static void meta_frames_style_set (GtkWidget *widget,
GtkStyle *prev_style);
static GtkWidgetClass *parent_class = NULL;
static guint signals[LAST_SIGNAL];
GtkType
meta_frames_get_type (void)
{
static GtkType frames_type = 0;
if (!frames_type)
{
static const GtkTypeInfo frames_info =
{
"MetaFrames",
sizeof (MetaFrames),
sizeof (MetaFramesClass),
(GtkClassInitFunc) meta_frames_class_init,
(GtkObjectInitFunc) meta_frames_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL,
};
frames_type = gtk_type_unique (GTK_TYPE_WIDGET, &frames_info);
}
return frames_type;
}
static void
meta_frames_class_init (MetaFramesClass *class)
{
GObjectClass *gobject_class;
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
gobject_class = G_OBJECT_CLASS (class);
object_class = (GtkObjectClass*) class;
widget_class = (GtkWidgetClass*) class;
parent_class = g_type_class_peek_parent (class);
gobject_class->finalize = meta_frames_finalize;
object_class->destroy = meta_frames_destroy;
widget_class->style_set = meta_frames_style_set;
gtk_widget_class_install_style_property (widget_class,
g_param_spec_int ("slider_width",
_("Slider Width"),
_("Width of scrollbar or scale thumb"),
0,
G_MAXINT,
14,
G_PARAM_READABLE));
}
static void
meta_frames_init (MetaFrames *frames)
{
GTK_WINDOW (frames)->type = GTK_WINDOW_POPUP;
}
static void
meta_frames_destroy (GtkObject *object)
{
}
static void
meta_frames_finalize (GObject *object)
{
}
void
meta_frames_manage_window (MetaFrames *frames,
GdkWindow *window)
{
g_return_if_fail (GDK_IS_WINDOW (window));
gdk_window_set_user_data (window, frames);
gdk_window_set_events (window,
GDK_EXPOSURE_MASK |
GDK_POINTER_MOTION_MASK |
GDK_POINTER_MOTION_HINT_MASK |
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_STRUCTURE_MASK);
}

60
src/uislave/frames.h Normal file
View File

@ -0,0 +1,60 @@
/* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef META_FRAMES_H
#define META_FRAMES_H
#include <gtk/gtk.h>
/* This is one widget that manages all the window frames
* as subwindows.
*/
#define META_TYPE_FRAMES (meta_frames_get_type ())
#define META_FRAMES(obj) (META_CHECK_CAST ((obj), META_TYPE_FRAMES, MetaFrames))
#define META_FRAMES_CLASS(klass) (META_CHECK_CLASS_CAST ((klass), META_TYPE_FRAMES, MetaFramesClass))
#define META_IS_FRAMES(obj) (META_CHECK_TYPE ((obj), META_TYPE_FRAMES))
#define META_IS_FRAMES_CLASS(klass) (META_CHECK_CLASS_TYPE ((klass), META_TYPE_FRAMES))
#define META_FRAMES_GET_CLASS(obj) (META_CHECK_GET_CLASS ((obj), META_TYPE_FRAMES, MetaFramesClass))
typedef struct _MetaFrames MetaFrames;
typedef struct _MetaFramesClass MetaFramesClass;
struct _MetaFrames
{
GtkWindow parent_instance;
};
struct _MetaFramesClass
{
GtkWindowClass parent_class;
};
GType meta_frames_get_type (void) G_GNUC_CONST;
MetaFrames *meta_frames_new (void);
void meta_frames_manage_window (MetaFrames *frames,
GdkWindow *window);
#endif

View File

@ -324,7 +324,11 @@ meta_window_free (MetaWindow *window)
window->border_width); window->border_width);
meta_error_trap_pop (window->display); meta_error_trap_pop (window->display);
g_free (window->sm_client_id);
g_free (window->role);
g_free (window->res_class);
g_free (window->res_name);
g_free (window->title); g_free (window->title);
g_free (window->desc); g_free (window->desc);
g_free (window); g_free (window);

View File

@ -127,7 +127,7 @@ struct _MetaWindow
*/ */
guint user_has_resized : 1; guint user_has_resized : 1;
guint user_has_moved : 1; guint user_has_moved : 1;
/* Number of UnmapNotify that are caused by us, if /* Number of UnmapNotify that are caused by us, if
* we get UnmapNotify with none pending then the client * we get UnmapNotify with none pending then the client
* is withdrawing the window. * is withdrawing the window.