chop out the portion of the region that's outside the screen.

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
This commit is contained in:
Havoc Pennington 2002-05-05 00:45:01 +00:00 committed by Havoc Pennington
parent 7fbbd0200f
commit 6f8a7f1870
4 changed files with 109 additions and 5 deletions

View File

@ -1,3 +1,11 @@
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

View File

@ -451,6 +451,34 @@ meta_core_get_frame_workspace (Display *xdisplay,
return meta_window_get_net_wm_desktop (window);
}
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,
@ -579,6 +607,27 @@ meta_core_set_screen_cursor (Display *xdisplay,
meta_screen_set_cursor (window->screen, cursor);
}
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)
{

View File

@ -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.

View File

@ -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]);