summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--src/core.c49
-rw-r--r--src/core.h13
-rw-r--r--src/frames.c44
4 files changed, 109 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 5c125504..a8a047c8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/src/core.c b/src/core.c
index 89b29450..61c16b82 100644
--- a/src/core.c
+++ b/src/core.c
@@ -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;
diff --git a/src/core.h b/src/core.h
index 7952e88e..bcd9dd90 100644
--- a/src/core.h
+++ b/src/core.h
@@ -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]);