Patch from Soeren Sandmann #108926 to improve opaque resize

2003-08-16  Havoc Pennington  <hp@pobox.com>

	Patch from Soeren Sandmann #108926 to improve opaque resize

	* src/frame.c (meta_window_ensure_frame): new function

	* src/ui.c (meta_ui_create_frame_window): new function to create
	a frame with GDK, so that GDK's invalidation etc. work properly
This commit is contained in:
Havoc Pennington 2003-08-16 16:32:10 +00:00 committed by Havoc Pennington
parent 288e10f7fe
commit 71cd8948d2
6 changed files with 149 additions and 72 deletions

View File

@ -1,3 +1,12 @@
2003-08-16 Havoc Pennington <hp@pobox.com>
Patch from Soeren Sandmann #108926 to improve opaque resize
* src/frame.c (meta_window_ensure_frame): new function
* src/ui.c (meta_ui_create_frame_window): new function to create
a frame with GDK, so that GDK's invalidation etc. work properly
2003-08-16 Havoc Pennington <hp@pobox.com>
* src/display.c (xcursor_for_op): fix cursor for

View File

@ -62,8 +62,6 @@ meta_window_ensure_frame (MetaWindow *window)
frame->need_reapply_frame_shape = TRUE;
frame->is_flashing = FALSE;
attrs.event_mask = EVENT_MASK;
meta_verbose ("Framing window %s: visual %s default, depth %d default depth %d\n",
window->desc,
XVisualIDFromVisual (window->xvisual) ==
@ -79,24 +77,19 @@ meta_window_ensure_frame (MetaWindow *window)
* e.g. DRI games can't be children of a parent that has the same
* visual as the client.
*/
frame->xwindow = XCreateWindow (window->display->xdisplay,
window->screen->xroot,
frame->rect.x,
frame->rect.y,
frame->rect.width,
frame->rect.height,
0,
window->screen->default_depth,
CopyFromParent,
window->screen->default_xvisual,
CWEventMask,
&attrs);
/* So our UI can find the window ID */
XFlush (window->display->xdisplay);
frame->xwindow = meta_ui_create_frame_window (window->screen->ui,
window->display->xdisplay,
frame->rect.x,
frame->rect.y,
frame->rect.width,
frame->rect.height,
frame->window->screen->number);
meta_verbose ("Frame for %s is 0x%lx\n", frame->window->desc, frame->xwindow);
attrs.event_mask = EVENT_MASK;
XChangeWindowAttributes (window->display->xdisplay,
frame->xwindow, CWEventMask, &attrs);
meta_display_register_x_window (window->display, &frame->xwindow, window);
@ -133,8 +126,6 @@ meta_window_ensure_frame (MetaWindow *window)
/* stick frame to the window */
window->frame = frame;
meta_ui_add_frame (window->screen->ui, frame->xwindow);
if (window->title)
meta_ui_set_frame_title (window->screen->ui,
window->frame->xwindow,
@ -165,7 +156,6 @@ meta_window_destroy_frame (MetaWindow *window)
frame = window->frame;
meta_bell_notify_frame_destroy (frame);
meta_ui_remove_frame (window->screen->ui, frame->xwindow);
/* Unparent the client window; it may be destroyed,
* thus the error trap.
@ -189,6 +179,8 @@ meta_window_destroy_frame (MetaWindow *window)
window->frame->rect.y);
meta_error_trap_pop (window->display, FALSE);
meta_ui_destroy_frame_window (window->screen->ui, frame->xwindow);
meta_display_unregister_x_window (window->display,
frame->xwindow);
@ -197,9 +189,6 @@ meta_window_destroy_frame (MetaWindow *window)
/* Move keybindings to window instead of frame */
meta_window_grab_keys (window);
/* should we push an error trap? */
XDestroyWindow (window->display->xdisplay, frame->xwindow);
g_free (frame);
/* Put our state back where it should be */
@ -339,23 +328,12 @@ meta_frame_sync_to_window (MetaFrame *frame,
*/
update_shape (frame);
if (need_move && need_resize)
XMoveResizeWindow (frame->window->display->xdisplay,
frame->xwindow,
frame->rect.x,
frame->rect.y,
frame->rect.width,
frame->rect.height);
else if (need_move)
XMoveWindow (frame->window->display->xdisplay,
frame->xwindow,
frame->rect.x,
frame->rect.y);
else if (need_resize)
XResizeWindow (frame->window->display->xdisplay,
frame->xwindow,
frame->rect.width,
frame->rect.height);
meta_ui_move_resize_frame (frame->window->screen->ui,
frame->xwindow,
frame->rect.x,
frame->rect.y,
frame->rect.width,
frame->rect.height);
if (need_resize)
{
@ -379,8 +357,9 @@ meta_frame_queue_draw (MetaFrame *frame)
frame->xwindow);
}
void meta_frame_set_screen_cursor (MetaFrame *frame,
MetaCursor cursor)
void
meta_frame_set_screen_cursor (MetaFrame *frame,
MetaCursor cursor)
{
Cursor xcursor;
if (cursor == frame->current_cursor)

View File

@ -464,22 +464,20 @@ meta_frames_new (int screen_number)
void
meta_frames_manage_window (MetaFrames *frames,
Window xwindow)
Window xwindow,
GdkWindow *window)
{
MetaUIFrame *frame;
g_assert (window);
frame = g_new (MetaUIFrame, 1);
frame->window = gdk_window_foreign_new (xwindow);
frame->window = window;
if (frame->window == NULL)
{
g_free (frame);
meta_bug ("Frame 0x%lx doesn't exist\n", xwindow);
return;
}
gdk_window_set_user_data (frame->window, frames);
gtk_style_set_background (GTK_WIDGET (frames)->style,
frame->window, GTK_STATE_NORMAL);
/* Don't set event mask here, it's in frame.c */
@ -521,7 +519,7 @@ meta_frames_unmanage_window (MetaFrames *frames,
g_hash_table_remove (frames->frames, &frame->xwindow);
g_object_unref (G_OBJECT (frame->window));
gdk_window_destroy (frame->window);
if (frame->layout)
g_object_unref (G_OBJECT (frame->layout));
@ -910,6 +908,25 @@ meta_frames_apply_shapes (MetaFrames *frames,
#endif /* HAVE_SHAPE */
}
void
meta_frames_move_resize_frame (MetaFrames *frames,
Window xwindow,
int x,
int y,
int width,
int height)
{
MetaUIFrame *frame = meta_frames_lookup_window (frames, xwindow);
int old_width, old_height;
gdk_drawable_get_size (frame->window, &old_width, &old_height);
gdk_window_move_resize (frame->window, x, y, width, height);
if (old_width != width || old_height != height)
gdk_window_invalidate_rect (frame->window, NULL, FALSE);
}
void
meta_frames_queue_draw (MetaFrames *frames,
Window xwindow)
@ -1672,7 +1689,7 @@ meta_frames_expose_event (GtkWidget *widget,
MetaFrames *frames;
frames = META_FRAMES (widget);
frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window));
if (frame == NULL)
return FALSE;

View File

@ -103,7 +103,8 @@ GType meta_frames_get_type (void) G_GNUC_CONST;
MetaFrames *meta_frames_new (int screen_number);
void meta_frames_manage_window (MetaFrames *frames,
Window xwindow);
Window xwindow,
GdkWindow *window);
void meta_frames_unmanage_window (MetaFrames *frames,
Window xwindow);
void meta_frames_set_title (MetaFrames *frames,
@ -130,7 +131,12 @@ void meta_frames_apply_shapes (MetaFrames *frames,
int new_window_width,
int new_window_height,
gboolean window_has_shape);
void meta_frames_move_resize_frame (MetaFrames *frames,
Window xwindow,
int x,
int y,
int width,
int height);
void meta_frames_queue_draw (MetaFrames *frames,
Window xwindow);

View File

@ -152,21 +152,78 @@ meta_ui_get_frame_geometry (MetaUI *ui,
left_width, right_width);
}
void
meta_ui_add_frame (MetaUI *ui,
Window xwindow)
Window
meta_ui_create_frame_window (MetaUI *ui,
Display *xdisplay,
gint x,
gint y,
gint width,
gint height,
gint screen_no)
{
meta_frames_manage_window (ui->frames, xwindow);
GdkDisplay *display = gdk_x11_lookup_xdisplay (xdisplay);
GdkScreen *screen = gdk_display_get_screen (display, screen_no);
GdkWindowAttr attrs;
gint attributes_mask;
GdkWindow *window;
/* Default depth/visual handles clients with weird visuals; they can
* always be children of the root depth/visual obviously, but
* e.g. DRI games can't be children of a parent that has the same
* visual as the client.
*/
attrs.title = NULL;
/* frame.c is going to replace the event mask immediately, but
* we still have to set it here to let GDK know what it is.
*/
attrs.event_mask =
GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK |
GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK;
attrs.x = x;
attrs.y = y;
attrs.wclass = GDK_INPUT_OUTPUT;
attrs.visual = gdk_screen_get_system_visual (screen);
attrs.colormap = gdk_screen_get_default_colormap (screen);
attrs.window_type = GDK_WINDOW_CHILD;
attrs.cursor = NULL;
attrs.wmclass_name = NULL;
attrs.wmclass_class = NULL;
attrs.override_redirect = FALSE;
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
window =
gdk_window_new (gdk_screen_get_root_window(screen),
&attrs, attributes_mask);
gdk_window_resize (window, width, height);
meta_frames_manage_window (ui->frames, GDK_WINDOW_XID (window), window);
return GDK_WINDOW_XID (window);
}
void
meta_ui_remove_frame (MetaUI *ui,
Window xwindow)
meta_ui_destroy_frame_window (MetaUI *ui,
Window xwindow)
{
meta_frames_unmanage_window (ui->frames, xwindow);
}
void
meta_ui_move_resize_frame (MetaUI *ui,
Window frame,
int x,
int y,
int width,
int height)
{
meta_frames_move_resize_frame (ui->frames, frame, x, y, width, height);
}
void
meta_ui_map_frame (MetaUI *ui,
Window xwindow)
@ -713,12 +770,11 @@ meta_ui_window_is_widget (MetaUI *ui,
window = gdk_xid_table_lookup (xwindow);
if (window &&
gdk_window_get_window_type (window) != GDK_WINDOW_FOREIGN)
if (window)
{
void *user_data = NULL;
gdk_window_get_user_data (window, &user_data);
return user_data != NULL;
return user_data != NULL && user_data != ui->frames;
}
else
return FALSE;
@ -759,7 +815,7 @@ meta_stock_icons_init (void)
icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
gtk_icon_factory_add (factory, items[i].stock_id, icon_set);
gtk_icon_set_unref (icon_set);
g_object_unref (G_OBJECT (pixbuf));
}

View File

@ -54,11 +54,21 @@ void meta_ui_get_frame_geometry (MetaUI *ui,
Window frame_xwindow,
int *top_height, int *bottom_height,
int *left_width, int *right_width);
void meta_ui_add_frame (MetaUI *ui,
Window xwindow);
void meta_ui_remove_frame (MetaUI *ui,
Window xwindow);
Window meta_ui_create_frame_window (MetaUI *ui,
Display *xdisplay,
gint x,
gint y,
gint width,
gint height,
gint screen_no);
void meta_ui_destroy_frame_window (MetaUI *ui,
Window xwindow);
void meta_ui_move_resize_frame (MetaUI *ui,
Window frame,
int x,
int y,
int width,
int height);
/* GDK insists on tracking map/unmap */
void meta_ui_map_frame (MetaUI *ui,