diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | src/core.c | 49 | ||||
-rw-r--r-- | src/core.h | 13 | ||||
-rw-r--r-- | src/frames.c | 44 |
4 files changed, 109 insertions, 5 deletions
@@ -1,5 +1,13 @@ 2002-05-04 Havoc Pennington <hp@pobox.com> + * src/frames.c (meta_frames_paint_to_drawable): chop out the + portion of the region that's outside the screen. + + * src/core.c (meta_core_get_screen_size): new function + (meta_core_get_frame_extents): new function + +2002-05-04 Havoc Pennington <hp@pobox.com> + * src/frames.c (meta_frames_init): disable automatic GTK double buffering, since it resulted in gigantic backing pixmaps the size of the whole screen. @@ -452,6 +452,34 @@ meta_core_get_frame_workspace (Display *xdisplay, } void +meta_core_get_frame_extents (Display *xdisplay, + Window frame_xwindow, + int *x, + int *y, + int *width, + int *height) +{ + MetaDisplay *display; + MetaWindow *window; + + display = meta_display_for_x_display (xdisplay); + window = meta_display_lookup_x_window (display, frame_xwindow); + + if (window == NULL || window->frame == NULL) + meta_bug ("No such frame window 0x%lx!\n", frame_xwindow); + + if (x) + *x = window->frame->rect.x; + if (y) + *y = window->frame->rect.y; + if (width) + *width = window->frame->rect.width; + if (height) + *height = window->frame->rect.height; +} + + +void meta_core_show_window_menu (Display *xdisplay, Window frame_xwindow, int root_x, @@ -580,6 +608,27 @@ meta_core_set_screen_cursor (Display *xdisplay, } void +meta_core_get_screen_size (Display *xdisplay, + Window frame_on_screen, + int *width, + int *height) +{ + MetaDisplay *display; + MetaWindow *window; + + display = meta_display_for_x_display (xdisplay); + window = meta_display_lookup_x_window (display, frame_on_screen); + + if (window == NULL || window->frame == NULL) + meta_bug ("No such frame window 0x%lx!\n", frame_on_screen); + + if (width) + *width = window->screen->width; + if (height) + *height = window->screen->height; +} + +void meta_core_increment_event_serial (Display *xdisplay) { MetaDisplay *display; @@ -99,6 +99,14 @@ int meta_core_get_active_workspace (Screen *xscreen); int meta_core_get_frame_workspace (Display *xdisplay, Window frame_xwindow); +void meta_core_get_frame_extents (Display *xdisplay, + Window frame_xwindow, + int *x, + int *y, + int *width, + int *height); + + void meta_core_show_window_menu (Display *xdisplay, Window frame_xwindow, int root_x, @@ -129,6 +137,11 @@ void meta_core_set_screen_cursor (Display *xdisplay, Window frame_on_screen, MetaCursor cursor); +void meta_core_get_screen_size (Display *xdisplay, + Window frame_on_screen, + int *width, + int *height); + /* Used because we ignore EnterNotify when a window is unmapped that * really shouldn't cause focus changes, by comparing the event serial * of the EnterNotify and the UnmapNotify. diff --git a/src/frames.c b/src/frames.c index ab56bd54..aadb86bb 100644 --- a/src/frames.c +++ b/src/frames.c @@ -1299,10 +1299,11 @@ meta_frames_paint_to_drawable (MetaFrames *frames, int i; int top, bottom, left, right; GdkRegion *edges; - GdkRegion *client; + GdkRegion *tmp_region; GdkRectangle area; GdkRectangle *areas; int n_areas; + int screen_width, screen_height; widget = GTK_WIDGET (frames); @@ -1380,19 +1381,52 @@ meta_frames_paint_to_drawable (MetaFrames *frames, /* Repaint each side of the frame */ edges = gdk_region_copy (region); + + /* Punch out the client area */ area.x = left; area.y = top; area.width = w; area.height = h; - client = gdk_region_rectangle (&area); - gdk_region_subtract (edges, client); - gdk_region_destroy (client); + tmp_region = gdk_region_rectangle (&area); + gdk_region_subtract (edges, tmp_region); + gdk_region_destroy (tmp_region); + + /* Chop off stuff outside the screen; this optimization + * is crucial to handle huge client windows, + * like "xterm -geometry 1000x1000" + */ + meta_core_get_frame_extents (gdk_display, + frame->xwindow, + &area.x, &area.y, + &area.width, &area.height); + + meta_core_get_screen_size (gdk_display, + frame->xwindow, + &screen_width, &screen_height); + if ((area.x + area.width) > screen_width) + area.width = screen_width - area.x; + if (area.width < 0) + area.width = 0; + + if ((area.y + area.height) > screen_height) + area.height = screen_height - area.y; + if (area.height < 0) + area.height = 0; + + area.x = 0; /* make relative to frame rather than screen */ + area.y = 0; + + tmp_region = gdk_region_rectangle (&area); + gdk_region_intersect (edges, tmp_region); + gdk_region_destroy (tmp_region); + + /* Now draw remaining portion of region */ gdk_region_get_rectangles (edges, &areas, &n_areas); i = 0; while (i < n_areas) - { + { if (GDK_IS_WINDOW (drawable)) gdk_window_begin_paint_rect (drawable, &areas[i]); |