summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHavoc Pennington <hp@pobox.com>2003-08-16 16:32:10 +0000
committerHavoc Pennington <hp@src.gnome.org>2003-08-16 16:32:10 +0000
commit71cd8948d2b66310b5ea9e5466c589bb52c7c4e7 (patch)
tree9fe3242ae85dba50d4e3597e101468441550a31e
parent288e10f7fe88b7b55d2ca650475cf87555286330 (diff)
downloadmetacity-71cd8948d2b66310b5ea9e5466c589bb52c7c4e7.tar.gz
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
-rw-r--r--ChangeLog9
-rw-r--r--src/frame.c67
-rw-r--r--src/frames.c39
-rw-r--r--src/frames.h10
-rw-r--r--src/ui.c76
-rw-r--r--src/ui.h20
6 files changed, 149 insertions, 72 deletions
diff --git a/ChangeLog b/ChangeLog
index 181e5d9b..8d34cd4d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
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
META_GRAB_OP_MOVING, #111943 from John Paul Wallington
diff --git a/src/frame.c b/src/frame.c
index 4d22cacc..ba6b21c7 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -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)
diff --git a/src/frames.c b/src/frames.c
index 2805d9e0..a99c13aa 100644
--- a/src/frames.c
+++ b/src/frames.c
@@ -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));
@@ -911,6 +909,25 @@ meta_frames_apply_shapes (MetaFrames *frames,
}
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;
diff --git a/src/frames.h b/src/frames.h
index 182b6516..13b4f9a8 100644
--- a/src/frames.h
+++ b/src/frames.h
@@ -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);
diff --git a/src/ui.c b/src/ui.c
index eff54f27..1f53c3b1 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -152,19 +152,76 @@ meta_ui_get_frame_geometry (MetaUI *ui,
left_width, right_width);
}
+Window
+meta_ui_create_frame_window (MetaUI *ui,
+ Display *xdisplay,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ gint screen_no)
+{
+ 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_add_frame (MetaUI *ui,
- Window xwindow)
+meta_ui_destroy_frame_window (MetaUI *ui,
+ Window xwindow)
{
- meta_frames_manage_window (ui->frames, xwindow);
+ meta_frames_unmanage_window (ui->frames, xwindow);
}
void
-meta_ui_remove_frame (MetaUI *ui,
- Window xwindow)
+meta_ui_move_resize_frame (MetaUI *ui,
+ Window frame,
+ int x,
+ int y,
+ int width,
+ int height)
{
- meta_frames_unmanage_window (ui->frames, xwindow);
+ meta_frames_move_resize_frame (ui->frames, frame, x, y, width, height);
}
void
@@ -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));
}
diff --git a/src/ui.h b/src/ui.h
index 6ed69041..bdbb8146 100644
--- a/src/ui.h
+++ b/src/ui.h
@@ -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,