Merge reduced_resources mode patch from the branch. Offers wireframe and

2003-10-12  Havoc Pennington  <hp@redhat.com>

        Merge reduced_resources mode patch from the branch. Offers
	wireframe and no-animations.

	* src/window.c (implement_showing): no animation if we are
	in reduced resources mode

	* src/prefs.c: add REDUCED_RESOURCES pref

	* src/window.c (meta_window_update_keyboard_resize): fix to
	modify grab_anchor_window_pos to grab_wireframe_rect if
	appropriate instead of window->rect

	* src/display.h (struct _MetaDisplay): add grab_start_serial used
	to avoid responding to events that occurred prior to the grab
	initialization.

	Still broken in various ways, specifically EnterNotify that
	occurred prior to XGrabPointer is processed as if it occurred
	after.

	* src/window.c (meta_window_update_keyboard_move): add this
	instead of meta_window_warp_pointer() crack

	* src/effects.c (meta_effects_update_wireframe): draw a kind of
	grid for the wireframe, instead of just a rectangle, like twm

	* src/screen.c (meta_screen_new): line width of 3 for the XOR gc

        "Reduced resources" mode based on wireframe patch from
	Erwann Chenede. Still pretty buggy.

	* src/keybindings.c (process_keyboard_move_grab)
	(process_keyboard_resize_grab): add gruesome wireframe hacks

	* src/display.c (meta_display_end_grab_op): end wireframe
	(meta_display_begin_grab_op): begin wireframe

	* src/effects.c (meta_effects_end_wireframe)
	(meta_effects_update_wireframe, meta_effects_begin_wireframe):
	routines to draw the wireframe stuff

	* src/window.c (window_should_be_showing): hide window when
	doing wireframe, commented out as it breaks grab
	* src/window.c (meta_window_refresh_resize_popup): handle wireframe

	* src/screen.c (meta_screen_new): create a screen->root_xor_gc
	for use in drawing wireframes

	* src/frames.c (meta_frames_push_delay_exposes): repaint
	everything before we delay
This commit is contained in:
Havoc Pennington 2003-10-12 06:25:38 +00:00 committed by Havoc Pennington
parent 6628acb59c
commit e98fad3e62
16 changed files with 748 additions and 165 deletions

View File

@ -1,3 +1,56 @@
2003-10-12 Havoc Pennington <hp@redhat.com>
Merge reduced_resources mode patch from the branch. Offers
wireframe and no-animations.
* src/window.c (implement_showing): no animation if we are
in reduced resources mode
* src/prefs.c: add REDUCED_RESOURCES pref
* src/window.c (meta_window_update_keyboard_resize): fix to
modify grab_anchor_window_pos to grab_wireframe_rect if
appropriate instead of window->rect
* src/display.h (struct _MetaDisplay): add grab_start_serial used
to avoid responding to events that occurred prior to the grab
initialization.
Still broken in various ways, specifically EnterNotify that
occurred prior to XGrabPointer is processed as if it occurred
after.
* src/window.c (meta_window_update_keyboard_move): add this
instead of meta_window_warp_pointer() crack
* src/effects.c (meta_effects_update_wireframe): draw a kind of
grid for the wireframe, instead of just a rectangle, like twm
* src/screen.c (meta_screen_new): line width of 3 for the XOR gc
"Reduced resources" mode based on wireframe patch from
Erwann Chenede. Still pretty buggy.
* src/keybindings.c (process_keyboard_move_grab)
(process_keyboard_resize_grab): add gruesome wireframe hacks
* src/display.c (meta_display_end_grab_op): end wireframe
(meta_display_begin_grab_op): begin wireframe
* src/effects.c (meta_effects_end_wireframe)
(meta_effects_update_wireframe, meta_effects_begin_wireframe):
routines to draw the wireframe stuff
* src/window.c (window_should_be_showing): hide window when
doing wireframe, commented out as it breaks grab
* src/window.c (meta_window_refresh_resize_popup): handle wireframe
* src/screen.c (meta_screen_new): create a screen->root_xor_gc
for use in drawing wireframes
* src/frames.c (meta_frames_push_delay_exposes): repaint
everything before we delay
2003-10-11 Havoc Pennington <hp@pobox.com>
* src/display.c (meta_display_begin_grab_op): initialize

7
README
View File

@ -370,12 +370,11 @@ A: This one is also in rationales.txt. Because "ouija board" UI, where
http://pobox.com/~hp/free-software-ui.html
http://pobox.com/~hp/features.html
Q: Why no wireframe move/resize?
Q: Why does wireframe move/resize suck?
A: It's implemented in a patch that will be merged for GNOME 2.6
and is already in some vendor packages.
A: You can turn it on with the reduced_resources setting.
But: Because it has low usability, and is a pain
But: it has low usability, and is a pain
to implement, and there's no reason opaque move/resize should be a
problem on any setup that can run a modern desktop worth a darn to
begin with.

View File

@ -35,6 +35,7 @@
#include "resizepopup.h"
#include "workspace.h"
#include "bell.h"
#include "effects.h"
#include <X11/Xatom.h>
#include <X11/cursorfont.h>
#ifdef HAVE_SOLARIS_XINERAMA
@ -1219,7 +1220,8 @@ event_callback (XEvent *event,
* goes to the frame.
*/
frame_was_receiver = TRUE;
meta_topic (META_DEBUG_EVENTS, "Frame was receiver of event\n");
meta_topic (META_DEBUG_EVENTS, "Frame was receiver of event for %s\n",
window->desc);
}
#ifdef HAVE_XSYNC
@ -1231,6 +1233,7 @@ event_callback (XEvent *event,
if (display->grab_op != META_GRAB_OP_NONE &&
display->grab_window != NULL &&
event->xany.serial > display->grab_start_serial &&
grab_op_is_mouse (display->grab_op))
meta_window_handle_mouse_grab_op_event (display->grab_window, event);
}
@ -1297,6 +1300,7 @@ event_callback (XEvent *event,
if ((window &&
grab_op_is_mouse (display->grab_op) &&
display->grab_button != (int) event->xbutton.button &&
event->xany.serial > display->grab_start_serial &&
display->grab_window == window) ||
grab_op_is_keyboard (display->grab_op))
{
@ -1446,16 +1450,19 @@ event_callback (XEvent *event,
break;
case ButtonRelease:
if (display->grab_window == window &&
event->xany.serial > display->grab_start_serial &&
grab_op_is_mouse (display->grab_op))
meta_window_handle_mouse_grab_op_event (window, event);
break;
case MotionNotify:
if (display->grab_window == window &&
event->xany.serial > display->grab_start_serial &&
grab_op_is_mouse (display->grab_op))
meta_window_handle_mouse_grab_op_event (window, event);
break;
case EnterNotify:
if (display->grab_window == window &&
event->xany.serial > display->grab_start_serial &&
grab_op_is_mouse (display->grab_op))
meta_window_handle_mouse_grab_op_event (window, event);
/* do this even if window->has_focus to avoid races */
@ -1519,6 +1526,7 @@ event_callback (XEvent *event,
break;
case LeaveNotify:
if (display->grab_window == window &&
event->xany.serial > display->grab_start_serial &&
grab_op_is_mouse (display->grab_op))
meta_window_handle_mouse_grab_op_event (window, event);
else if (window != NULL)
@ -2797,8 +2805,9 @@ meta_display_begin_grab_op (MetaDisplay *display,
Window grab_xwindow;
meta_topic (META_DEBUG_WINDOW_OPS,
"Doing grab op %d on window %s button %d pointer already grabbed: %d\n",
op, window ? window->desc : "none", button, pointer_already_grabbed);
"Doing grab op %d on window %s button %d pointer already grabbed: %d pointer pos %d,%d\n",
op, window ? window->desc : "none", button, pointer_already_grabbed,
root_x, root_y);
if (display->grab_op != META_GRAB_OP_NONE)
{
@ -2808,6 +2817,9 @@ meta_display_begin_grab_op (MetaDisplay *display,
return FALSE;
}
/* We'll ignore any events < this serial. */
display->grab_start_serial = XNextRequest (display->xdisplay);
/* FIXME:
* If we have no MetaWindow we do our best
* and try to do the grab on the RootWindow.
@ -2860,8 +2872,8 @@ meta_display_begin_grab_op (MetaDisplay *display,
display->grab_xwindow = grab_xwindow;
display->grab_button = button;
display->grab_mask = modmask;
display->grab_initial_root_x = root_x;
display->grab_initial_root_y = root_y;
display->grab_anchor_root_x = root_x;
display->grab_anchor_root_y = root_y;
display->grab_latest_motion_x = root_x;
display->grab_latest_motion_y = root_y;
display->grab_last_moveresize_time.tv_sec = 0;
@ -2870,6 +2882,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
#ifdef HAVE_XSYNC
display->grab_update_alarm = None;
#endif
display->grab_was_cancelled = FALSE;
if (display->grab_window)
{
@ -2877,9 +2890,34 @@ meta_display_begin_grab_op (MetaDisplay *display,
meta_window_get_position (display->grab_window,
&display->grab_initial_window_pos.x,
&display->grab_initial_window_pos.y);
display->grab_anchor_window_pos = display->grab_initial_window_pos;
display->grab_wireframe_active =
meta_prefs_get_reduced_resources () &&
(meta_grab_op_is_resizing (display->grab_op) ||
meta_grab_op_is_moving (display->grab_op));
if (display->grab_wireframe_active)
{
/* FIXME we should really display the outer frame rect,
* but that complicates all the move/resize code since
* it works in terms of window rect.
*/
display->grab_wireframe_rect = window->rect;
if (window->frame)
{
display->grab_wireframe_rect.x += window->frame->rect.x;
display->grab_wireframe_rect.y += window->frame->rect.y;
}
meta_window_calc_showing (display->grab_window);
meta_effects_begin_wireframe (display->grab_window->screen,
&display->grab_wireframe_rect);
}
#ifdef HAVE_XSYNC
if (meta_grab_op_is_resizing (display->grab_op) &&
if (!display->grab_wireframe_active &&
meta_grab_op_is_resizing (display->grab_op) &&
display->grab_window->update_counter != None)
{
XSyncAlarmAttributes values;
@ -3010,6 +3048,21 @@ meta_display_end_grab_op (MetaDisplay *display,
}
#endif /* HAVE_XSYNC */
if (display->grab_wireframe_active)
{
display->grab_wireframe_active = FALSE;
meta_effects_end_wireframe (display->grab_window->screen,
&display->grab_wireframe_rect);
if (!display->grab_was_cancelled)
meta_window_move_resize (display->grab_window,
TRUE,
display->grab_wireframe_rect.x,
display->grab_wireframe_rect.y,
display->grab_wireframe_rect.width,
display->grab_wireframe_rect.height);
meta_window_calc_showing (display->grab_window);
}
display->grab_window = NULL;
display->grab_screen = NULL;
display->grab_xwindow = None;

View File

@ -225,14 +225,19 @@ struct _MetaDisplay
MetaScreen *grab_screen;
MetaWindow *grab_window;
Window grab_xwindow;
gulong grab_start_serial;
int grab_button;
int grab_initial_root_x;
int grab_initial_root_y;
int grab_anchor_root_x;
int grab_anchor_root_y;
MetaRectangle grab_anchor_window_pos;
int grab_latest_motion_x;
int grab_latest_motion_y;
gulong grab_mask;
guint grab_have_pointer : 1;
guint grab_have_keyboard : 1;
guint grab_wireframe_active : 1;
guint grab_was_cancelled : 1;
MetaRectangle grab_wireframe_rect;
MetaRectangle grab_initial_window_pos;
MetaResizePopup *grab_resize_popup;
GTimeVal grab_last_moveresize_time;

View File

@ -409,5 +409,108 @@ meta_effects_draw_box_animation (MetaScreen *screen,
XFlush (context->screen->display->xdisplay);
}
void
meta_effects_begin_wireframe (MetaScreen *screen,
const MetaRectangle *rect)
{
/* Grab the X server to avoid screen dirt */
meta_display_grab (screen->display);
meta_ui_push_delay_exposes (screen->ui);
meta_effects_update_wireframe (screen, NULL, rect);
}
static void
draw_xor_rect (MetaScreen *screen,
const MetaRectangle *rect)
{
/* The lines in the center can't overlap the rectangle or each
* other, or the XOR gets reversed. So we have to draw things
* a bit oddly.
*/
XSegment segments[8];
int i;
#define LINE_WIDTH META_WIREFRAME_XOR_LINE_WIDTH
XDrawRectangle (screen->display->xdisplay,
screen->xroot,
screen->root_xor_gc,
rect->x, rect->y,
rect->width, rect->height);
/* Don't put lines inside small rectangles where they won't fit */
if (rect->width < (LINE_WIDTH * 4) ||
rect->height < (LINE_WIDTH * 4))
return;
/* Two vertical lines at 1/3 and 2/3 */
segments[0].x1 = rect->x + rect->width / 3;
segments[0].y1 = rect->y + LINE_WIDTH / 2 + LINE_WIDTH % 2;
segments[0].x2 = segments[0].x1;
segments[0].y2 = rect->y + rect->height - LINE_WIDTH / 2;
segments[1] = segments[0];
segments[1].x1 = rect->x + (rect->width / 3) * 2;
segments[1].x2 = segments[1].x1;
/* Now make two horizontal lines at 1/3 and 2/3, but not
* overlapping the verticals
*/
segments[2].x1 = rect->x + LINE_WIDTH / 2 + LINE_WIDTH % 2;
segments[2].x2 = segments[0].x1 - LINE_WIDTH / 2;
segments[2].y1 = rect->y + rect->height / 3;
segments[2].y2 = segments[2].y1;
segments[3] = segments[2];
segments[3].x1 = segments[2].x2 + LINE_WIDTH;
segments[3].x2 = segments[1].x1 - LINE_WIDTH / 2;
segments[4] = segments[3];
segments[4].x1 = segments[3].x2 + LINE_WIDTH;
segments[4].x2 = rect->x + rect->width - LINE_WIDTH / 2;
/* Second horizontal line is just like the first, but
* shifted down
*/
i = 5;
while (i < 8)
{
segments[i] = segments[i - 3];
segments[i].y1 = rect->y + (rect->height / 3) * 2;
segments[i].y2 = segments[i].y1;
++i;
}
XDrawSegments (screen->display->xdisplay,
screen->xroot,
screen->root_xor_gc,
segments,
G_N_ELEMENTS (segments));
}
void
meta_effects_update_wireframe (MetaScreen *screen,
const MetaRectangle *old_rect,
const MetaRectangle *new_rect)
{
if (old_rect)
draw_xor_rect (screen, old_rect);
if (new_rect)
draw_xor_rect (screen, new_rect);
XFlush (screen->display->xdisplay);
}
void
meta_effects_end_wireframe (MetaScreen *screen,
const MetaRectangle *old_rect)
{
meta_effects_update_wireframe (screen, old_rect, NULL);
meta_display_ungrab (screen->display);
meta_ui_pop_delay_exposes (screen->ui);
}

View File

@ -41,4 +41,12 @@ void meta_effects_draw_box_animation (MetaScreen *screen,
double seconds_duration,
MetaBoxAnimType anim_type);
void meta_effects_begin_wireframe (MetaScreen *screen,
const MetaRectangle *rect);
void meta_effects_update_wireframe (MetaScreen *screen,
const MetaRectangle *old_rect,
const MetaRectangle *new_rect);
void meta_effects_end_wireframe (MetaScreen *screen,
const MetaRectangle *old_rect);
#endif /* META_EFFECTS_H */

View File

@ -2110,6 +2110,13 @@ get_control (MetaFrames *frames,
void
meta_frames_push_delay_exposes (MetaFrames *frames)
{
if (frames->expose_delay_count == 0)
{
/* Make sure we've repainted things */
gdk_window_process_all_updates ();
XFlush (gdk_display);
}
frames->expose_delay_count += 1;
}

View File

@ -27,6 +27,7 @@
#include "frame.h"
#include "place.h"
#include "prefs.h"
#include "effects.h"
#include <X11/keysym.h>
#include <string.h>
@ -1693,9 +1694,23 @@ process_keyboard_move_grab (MetaDisplay *display,
if (is_modifier (display, event->xkey.keycode))
return TRUE;
if (display->grab_wireframe_active)
{
x = display->grab_wireframe_rect.x;
y = display->grab_wireframe_rect.y;
}
else
{
meta_window_get_position (window, &x, &y);
}
/* FIXME in wireframe mode the edge snapping is all fucked up
* since the edge-find routines use window->rect. Window
* constraints are also broken with wireframe.
*/
smart_snap = (event->xkey.state & ShiftMask) != 0;
if (display->grab_wireframe_active)
smart_snap = FALSE;
#define SMALL_INCREMENT 1
#define NORMAL_INCREMENT 10
@ -1709,13 +1724,18 @@ process_keyboard_move_grab (MetaDisplay *display,
if (keysym == XK_Escape)
{
/* End move and restore to original position */
/* End resize and restore to original state.
* The move_resize is only needed when !wireframe
* since in wireframe we always moveresize at the end
* of the grab only.
*/
meta_window_move_resize (display->grab_window,
TRUE,
display->grab_initial_window_pos.x,
display->grab_initial_window_pos.y,
display->grab_initial_window_pos.width,
display->grab_initial_window_pos.height);
display->grab_was_cancelled = TRUE;
}
/* When moving by increments, we still snap to edges if the move
@ -1729,11 +1749,14 @@ process_keyboard_move_grab (MetaDisplay *display,
case XK_KP_Prior:
case XK_Up:
case XK_KP_Up:
edge = meta_window_find_next_horizontal_edge (window, FALSE);
y -= incr;
if (!display->grab_wireframe_active)
{
edge = meta_window_find_next_horizontal_edge (window, FALSE);
if (smart_snap || ((edge > y) && ABS (edge - y) < incr))
y = edge;
}
handled = TRUE;
break;
@ -1741,11 +1764,14 @@ process_keyboard_move_grab (MetaDisplay *display,
case XK_KP_Next:
case XK_Down:
case XK_KP_Down:
edge = meta_window_find_next_horizontal_edge (window, TRUE);
y += incr;
if (!display->grab_wireframe_active)
{
edge = meta_window_find_next_horizontal_edge (window, TRUE);
if (smart_snap || ((edge < y) && ABS (edge - y) < incr))
y = edge;
}
handled = TRUE;
break;
@ -1757,11 +1783,14 @@ process_keyboard_move_grab (MetaDisplay *display,
case XK_KP_End:
case XK_Left:
case XK_KP_Left:
edge = meta_window_find_next_vertical_edge (window, FALSE);
x -= incr;
if (!display->grab_wireframe_active)
{
edge = meta_window_find_next_vertical_edge (window, FALSE);
if (smart_snap || ((edge > x) && ABS (edge - x) < incr))
x = edge;
}
handled = TRUE;
break;
@ -1769,18 +1798,43 @@ process_keyboard_move_grab (MetaDisplay *display,
case XK_KP_Next:
case XK_Right:
case XK_KP_Right:
edge = meta_window_find_next_vertical_edge (window, TRUE);
x += incr;
if (!display->grab_wireframe_active)
{
edge = meta_window_find_next_vertical_edge (window, TRUE);
if (smart_snap || ((edge < x) && ABS (edge - x) < incr))
x = edge;
}
handled = TRUE;
break;
}
if (handled)
{
meta_topic (META_DEBUG_KEYBINDINGS,
"Computed new window location %d,%d due to keypress\n",
x, y);
if (display->grab_wireframe_active)
{
MetaRectangle new_xor;
new_xor = display->grab_wireframe_rect;
new_xor.x = x;
new_xor.y = y;
meta_effects_update_wireframe (window->screen,
&display->grab_wireframe_rect,
&new_xor);
display->grab_wireframe_rect = new_xor;
}
else
{
meta_window_move (window, TRUE, x, y);
meta_window_warp_pointer (window, display->grab_op);
}
meta_window_update_keyboard_move (window);
}
return handled;
@ -1815,13 +1869,18 @@ process_keyboard_resize_grab (MetaDisplay *display,
if (keysym == XK_Escape)
{
/* End resize and restore to original state */
/* End resize and restore to original state.
* The move_resize is only needed when !wireframe
* since in wireframe we always moveresize at the end
* of the grab only.
*/
meta_window_move_resize (display->grab_window,
TRUE,
display->grab_initial_window_pos.x,
display->grab_initial_window_pos.y,
display->grab_initial_window_pos.width,
display->grab_initial_window_pos.height);
display->grab_was_cancelled = TRUE;
return FALSE;
}
@ -1931,19 +1990,37 @@ process_keyboard_resize_grab (MetaDisplay *display,
if (handled)
{
meta_window_update_resize_grab_op (window, TRUE);
meta_window_update_keyboard_resize (window, TRUE);
return TRUE;
}
if (display->grab_wireframe_active)
{
x = display->grab_wireframe_rect.x;
y = display->grab_wireframe_rect.y;
orig_x = x;
orig_y = y;
width = display->grab_wireframe_rect.width;
height = display->grab_wireframe_rect.height;
}
else
{
meta_window_get_position (window, &orig_x, &orig_y);
x = orig_x;
y = orig_y;
width = window->rect.width;
height = window->rect.height;
}
gravity = meta_resize_gravity_from_grab_op (display->grab_op);
/* FIXME in wireframe mode the edge snapping is all fucked up
* since the edge-find routines use window->rect. Window
* constraints are also broken with wireframe.
*/
smart_snap = (event->xkey.state & ShiftMask) != 0;
if (display->grab_wireframe_active)
smart_snap = FALSE;
#define SMALL_INCREMENT 1
#define NORMAL_INCREMENT 10
@ -1994,12 +2071,16 @@ process_keyboard_resize_grab (MetaDisplay *display,
case NorthWestGravity:
case NorthEastGravity:
/* Move bottom edge up */
edge = meta_window_find_next_horizontal_edge (window, TRUE);
height -= height_inc;
if (!display->grab_wireframe_active)
{
edge = meta_window_find_next_horizontal_edge (window, TRUE);
if (smart_snap || ((edge > (y+height)) &&
ABS (edge - (y+height)) < height_inc))
height = edge - y;
}
handled = TRUE;
break;
@ -2008,11 +2089,15 @@ process_keyboard_resize_grab (MetaDisplay *display,
case SouthWestGravity:
case SouthEastGravity:
/* Move top edge up */
edge = meta_window_find_next_horizontal_edge (window, FALSE);
y -= height_inc;
if (!display->grab_wireframe_active)
{
edge = meta_window_find_next_horizontal_edge (window, FALSE);
if (smart_snap || ((edge > y) && ABS (edge - y) < height_inc))
y = edge;
}
height += (orig_y - y);
break;
@ -2035,12 +2120,16 @@ process_keyboard_resize_grab (MetaDisplay *display,
case NorthWestGravity:
case NorthEastGravity:
/* Move bottom edge down */
edge = meta_window_find_next_horizontal_edge (window, TRUE);
height += height_inc;
if (!display->grab_wireframe_active)
{
edge = meta_window_find_next_horizontal_edge (window, TRUE);
if (smart_snap || ((edge < (y+height)) &&
ABS (edge - (y+height)) < height_inc))
height = edge - y;
}
handled = TRUE;
break;
@ -2049,11 +2138,15 @@ process_keyboard_resize_grab (MetaDisplay *display,
case SouthWestGravity:
case SouthEastGravity:
/* Move top edge down */
edge = meta_window_find_next_horizontal_edge (window, FALSE);
y += height_inc;
if (!display->grab_wireframe_active)
{
edge = meta_window_find_next_horizontal_edge (window, FALSE);
if (smart_snap || ((edge < y) && ABS (edge - y) < height_inc))
y = edge;
}
height -= (y - orig_y);
break;
@ -2076,11 +2169,15 @@ process_keyboard_resize_grab (MetaDisplay *display,
case SouthEastGravity:
case NorthEastGravity:
/* Move left edge left */
edge = meta_window_find_next_vertical_edge (window, TRUE);
x -= width_inc;
if (!display->grab_wireframe_active)
{
edge = meta_window_find_next_vertical_edge (window, TRUE);
if (smart_snap || ((edge > x) && ABS (edge - x) < width_inc))
x = edge;
}
width += (orig_x - x);
break;
@ -2089,12 +2186,16 @@ process_keyboard_resize_grab (MetaDisplay *display,
case SouthWestGravity:
case NorthWestGravity:
/* Move right edge left */
edge = meta_window_find_next_vertical_edge (window, FALSE);
width -= width_inc;
if (!display->grab_wireframe_active)
{
edge = meta_window_find_next_vertical_edge (window, FALSE);
if (smart_snap || ((edge > (x+width)) &&
ABS (edge - (x+width)) < width_inc))
width = edge - x;
}
handled = TRUE;
break;
@ -2117,11 +2218,15 @@ process_keyboard_resize_grab (MetaDisplay *display,
case SouthEastGravity:
case NorthEastGravity:
/* Move left edge right */
edge = meta_window_find_next_vertical_edge (window, FALSE);
x += width_inc;
if (!display->grab_wireframe_active)
{
edge = meta_window_find_next_vertical_edge (window, FALSE);
if (smart_snap || ((edge < x) && ABS (edge - x) < width_inc))
x = edge;
}
width -= (x - orig_x);
break;
@ -2130,12 +2235,16 @@ process_keyboard_resize_grab (MetaDisplay *display,
case SouthWestGravity:
case NorthWestGravity:
/* Move right edge right */
edge = meta_window_find_next_vertical_edge (window, TRUE);
width += width_inc;
if (!display->grab_wireframe_active)
{
edge = meta_window_find_next_vertical_edge (window, TRUE);
if (smart_snap || ((edge > (x+width)) &&
ABS (edge - (x+width)) < width_inc))
width = edge - x;
}
handled = TRUE;
break;
@ -2161,9 +2270,33 @@ process_keyboard_resize_grab (MetaDisplay *display,
width = 1;
if (handled)
{
meta_topic (META_DEBUG_KEYBINDINGS,
"Computed new window location %d,%d %dx%d due to keypress\n",
x, y, width, height);
if (display->grab_wireframe_active)
{
MetaRectangle new_xor;
new_xor.x = x;
new_xor.y = y;
new_xor.width = width;
new_xor.height = height;
meta_effects_update_wireframe (window->screen,
&window->display->grab_wireframe_rect,
&new_xor);
window->display->grab_wireframe_rect = new_xor;
/* do this after drawing the wires, so we don't draw over it */
meta_window_refresh_resize_popup (window);
}
else
{
meta_window_move_resize (window, TRUE, x, y, width, height);
meta_window_update_resize_grab_op (window, FALSE);
}
meta_window_update_keyboard_resize (window, FALSE);
}
return handled;

View File

@ -257,6 +257,25 @@
</locale>
</schema>
<schema>
<key>/schemas/apps/metacity/general/reduced_resources</key>
<applyto>/apps/metacity/general/reduced_resources</applyto>
<owner>metacity</owner>
<type>bool</type>
<default>false</default>
<locale name="C">
<short>If true, trade off usability for less resource usage</short>
<long>
If true, metacity will give the user less feedback and
less sense of "direct manipulation", by using wireframes,
avoiding animations, or other means. This is a significant
reduction in usability for many users, but may allow
legacy applications and terminal servers to function
when they would otherwise be impractical.
</long>
</locale>
</schema>
<!-- Window Keybindings -->
<schema>

View File

@ -51,6 +51,7 @@
#define KEY_APPLICATION_BASED "/apps/metacity/general/application_based"
#define KEY_DISABLE_WORKAROUNDS "/apps/metacity/general/disable_workarounds"
#define KEY_BUTTON_LAYOUT "/apps/metacity/general/button_layout"
#define KEY_REDUCED_RESOURCES "/apps/metacity/general/reduced_resources"
#define KEY_COMMAND_PREFIX "/apps/metacity/keybinding_commands/command_"
#define KEY_SCREEN_BINDINGS_PREFIX "/apps/metacity/global_keybindings"
@ -83,6 +84,8 @@ static gboolean auto_raise = FALSE;
static gboolean auto_raise_delay = 500;
static gboolean provide_visual_bell = TRUE;
static gboolean bell_is_audible = TRUE;
static gboolean reduced_resources = FALSE;
static MetaVisualBellType visual_bell_type = META_VISUAL_BELL_INVALID;
static MetaButtonLayout button_layout = {
{
@ -129,6 +132,7 @@ static gboolean update_command (const char *name,
const char *value);
static gboolean update_workspace_name (const char *name,
const char *value);
static gboolean update_reduced_resources (gboolean value);
static void change_notify (GConfClient *client,
guint cnxn_id,
@ -372,7 +376,6 @@ meta_prefs_init (void)
cleanup_error (&err);
update_button_layout (str_val);
g_free (str_val);
#endif /* HAVE_GCONF */
bool_val = gconf_client_get_bool (default_client, KEY_VISUAL_BELL,
&err);
@ -388,6 +391,12 @@ meta_prefs_init (void)
update_visual_bell_type (str_val);
g_free (str_val);
bool_val = gconf_client_get_bool (default_client, KEY_REDUCED_RESOURCES,
&err);
cleanup_error (&err);
update_reduced_resources (bool_val);
#endif /* HAVE_GCONF */
/* Load keybindings prefs */
init_bindings ();
@ -733,6 +742,22 @@ change_notify (GConfClient *client,
if (update_visual_bell_type (str))
queue_changed (META_PREF_VISUAL_BELL_TYPE);
}
else if (strcmp (key, KEY_REDUCED_RESOURCES) == 0)
{
gboolean b;
if (value && value->type != GCONF_VALUE_BOOL)
{
meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
KEY_REDUCED_RESOURCES);
goto out;
}
b = value ? gconf_value_get_bool (value) : reduced_resources;
if (update_reduced_resources (b))
queue_changed (META_PREF_REDUCED_RESOURCES);
}
else
{
meta_topic (META_DEBUG_PREFS, "Key %s doesn't mean anything to Metacity\n",
@ -1239,6 +1264,16 @@ update_auto_raise_delay (int value)
return old != auto_raise_delay;
}
static gboolean
update_reduced_resources (gboolean value)
{
gboolean old = reduced_resources;
reduced_resources = value;
return old != reduced_resources;
}
#endif /* HAVE_GCONF */
#ifdef WITH_VERBOSE_MODE
@ -1305,6 +1340,10 @@ meta_preference_to_string (MetaPreference pref)
case META_PREF_VISUAL_BELL_TYPE:
return "VISUAL_BELL_TYPE";
break;
case META_PREF_REDUCED_RESOURCES:
return "REDUCED_RESOURCES";
break;
}
return "(unknown)";
@ -1974,6 +2013,12 @@ meta_prefs_get_auto_raise_delay ()
return auto_raise_delay;
}
gboolean
meta_prefs_get_reduced_resources ()
{
return reduced_resources;
}
MetaKeyBindingAction
meta_prefs_get_keybinding_action (const char *name)
{

View File

@ -45,7 +45,8 @@ typedef enum
META_PREF_WORKSPACE_NAMES,
META_PREF_VISUAL_BELL,
META_PREF_AUDIBLE_BELL,
META_PREF_VISUAL_BELL_TYPE
META_PREF_VISUAL_BELL_TYPE,
META_PREF_REDUCED_RESOURCES
} MetaPreference;
typedef void (* MetaPrefsChangedFunc) (MetaPreference pref,
@ -69,6 +70,7 @@ gboolean meta_prefs_get_application_based (void);
gboolean meta_prefs_get_disable_workarounds (void);
gboolean meta_prefs_get_auto_raise (void);
int meta_prefs_get_auto_raise_delay (void);
gboolean meta_prefs_get_reduced_resources (void);
const char* meta_prefs_get_command (int i);

View File

@ -1,11 +1,11 @@
#! /bin/bash
if test -z "$XNEST_DISPLAY"; then
XNEST_DISPLAY=:1
XNEST_DISPLAY=:8
fi
if test -z "$CLIENT_DISPLAY"; then
CLIENT_DISPLAY=:1
CLIENT_DISPLAY=:8
fi
if test -z "$METACITY_DISPLAY"; then

View File

@ -539,6 +539,19 @@ meta_screen_new (MetaDisplay *display,
screen->showing_desktop = FALSE;
{
XGCValues gc_values;
gc_values.subwindow_mode = IncludeInferiors;
gc_values.function = GXinvert;
gc_values.line_width = META_WIREFRAME_XOR_LINE_WIDTH;
screen->root_xor_gc = XCreateGC (screen->display->xdisplay,
screen->xroot,
GCSubwindowMode | GCFunction | GCLineWidth,
&gc_values);
}
screen->xinerama_infos = NULL;
screen->n_xinerama_infos = 0;
screen->last_xinerama_index = 0;
@ -680,6 +693,9 @@ meta_screen_free (MetaScreen *screen)
if (screen->work_area_idle != 0)
g_source_remove (screen->work_area_idle);
XFreeGC (screen->display->xdisplay,
screen->root_xor_gc);
g_free (screen->screen_name);
g_free (screen);

View File

@ -56,6 +56,8 @@ typedef enum
META_SCREEN_RIGHT
} MetaScreenDirection;
#define META_WIREFRAME_XOR_LINE_WIDTH 5
struct _MetaScreen
{
MetaDisplay *display;
@ -108,6 +110,9 @@ struct _MetaScreen
guint showing_desktop : 1;
int closing;
/* gc for XOR on root window */
GC root_xor_gc;
};
MetaScreen* meta_screen_new (MetaDisplay *display,

View File

@ -1206,6 +1206,14 @@ window_should_be_showing (MetaWindow *window)
showing = FALSE;
}
#if 0
/* 5. See if we're drawing wireframe
*/
if (window->display->grab_window == window &&
window->display->grab_wireframe_active)
showing = FALSE;
#endif
return showing;
}
@ -1230,7 +1238,8 @@ implement_showing (MetaWindow *window,
* if we are mapped now, we are supposed to
* be minimized, and we are on the current workspace.
*/
if (on_workspace && window->minimized && window->mapped)
if (on_workspace && window->minimized && window->mapped &&
!meta_prefs_get_reduced_resources ())
{
MetaRectangle icon_rect, window_rect;
gboolean result;
@ -1856,7 +1865,7 @@ meta_window_unmaximize (MetaWindow *window)
if (meta_grab_op_is_moving (window->display->grab_op) &&
window->display->grab_window == window)
{
window->display->grab_initial_window_pos = window->saved_rect;
window->display->grab_anchor_window_pos = window->saved_rect;
}
meta_window_move_resize (window,
@ -5620,7 +5629,7 @@ check_moveresize_frequency (MetaWindow *window)
window->display->grab_last_moveresize_time = current_time;
meta_topic (META_DEBUG_RESIZING,
" Doing move/resize now (%g of %g seconds elapsed)\n",
" Checked moveresize freq, allowing move/resize now (%g of %g seconds elapsed)\n",
elapsed / 1000.0, 1.0 / max_resizes_per_second);
return TRUE;
@ -5639,11 +5648,19 @@ update_move (MetaWindow *window,
window->display->grab_latest_motion_x = x;
window->display->grab_latest_motion_y = y;
dx = x - window->display->grab_initial_root_x;
dy = y - window->display->grab_initial_root_y;
dx = x - window->display->grab_anchor_root_x;
dy = y - window->display->grab_anchor_root_y;
new_x = window->display->grab_initial_window_pos.x + dx;
new_y = window->display->grab_initial_window_pos.y + dy;
new_x = window->display->grab_anchor_window_pos.x + dx;
new_y = window->display->grab_anchor_window_pos.y + dy;
meta_verbose ("x,y = %d,%d anchor ptr %d,%d anchor pos %d,%d dx,dy %d,%d\n",
x, y,
window->display->grab_anchor_root_x,
window->display->grab_anchor_root_y,
window->display->grab_anchor_window_pos.x,
window->display->grab_anchor_window_pos.y,
dx, dy);
/* shake loose (unmaximize) maximized window if dragged beyond the threshold
* in the Y direction. You can't pull a window loose via X motion.
@ -5733,6 +5750,24 @@ update_move (MetaWindow *window,
if (window->maximized)
return;
if (window->display->grab_wireframe_active)
{
/* FIXME Horribly broken, does not honor position
* constraints
*/
MetaRectangle new_xor;
new_xor = window->display->grab_wireframe_rect;
new_xor.x = new_x;
new_xor.y = new_y;
meta_effects_update_wireframe (window->screen,
&window->display->grab_wireframe_rect,
&new_xor);
window->display->grab_wireframe_rect = new_xor;
}
else
{
/* FIXME, edge snapping broken in wireframe mode */
if (mask & ShiftMask)
{
/* snap to edges */
@ -5741,6 +5776,7 @@ update_move (MetaWindow *window,
}
meta_window_move (window, TRUE, new_x, new_y);
}
}
static void
@ -5751,15 +5787,20 @@ update_resize (MetaWindow *window,
int new_w, new_h;
int gravity;
MetaRectangle old;
int new_x, new_y;
window->display->grab_latest_motion_x = x;
window->display->grab_latest_motion_y = y;
dx = x - window->display->grab_initial_root_x;
dy = y - window->display->grab_initial_root_y;
dx = x - window->display->grab_anchor_root_x;
dy = y - window->display->grab_anchor_root_y;
new_w = window->display->grab_initial_window_pos.width;
new_h = window->display->grab_initial_window_pos.height;
new_w = window->display->grab_anchor_window_pos.width;
new_h = window->display->grab_anchor_window_pos.height;
/* FIXME this is only used in wireframe mode */
new_x = window->display->grab_anchor_window_pos.x;
new_y = window->display->grab_anchor_window_pos.y;
switch (window->display->grab_op)
{
@ -5779,6 +5820,7 @@ update_resize (MetaWindow *window,
case META_GRAB_OP_KEYBOARD_RESIZING_SW:
case META_GRAB_OP_KEYBOARD_RESIZING_W:
new_w -= dx;
new_x += dx;
break;
default:
@ -5803,6 +5845,7 @@ update_resize (MetaWindow *window,
case META_GRAB_OP_KEYBOARD_RESIZING_NE:
case META_GRAB_OP_KEYBOARD_RESIZING_NW:
new_h -= dy;
new_y += dy;
break;
default:
break;
@ -5817,7 +5860,37 @@ update_resize (MetaWindow *window,
gravity = meta_resize_gravity_from_grab_op (window->display->grab_op);
g_assert (gravity >= 0);
if (window->display->grab_wireframe_active)
{
/* FIXME This is crap. For example, the wireframe isn't
* constrained in the way that a real resize would be. An
* obvious elegant solution is to unmap the window during
* wireframe, but still resize it; however, that probably
* confuses broken clients that have problems with opaque
* resize, they probably don't track their visibility.
*/
MetaRectangle new_xor;
if ((new_x + new_w <= new_x) || (new_y + new_h <= new_y))
return;
new_xor.x = new_x;
new_xor.y = new_y;
new_xor.width = new_w;
new_xor.height = new_h;
meta_effects_update_wireframe (window->screen,
&window->display->grab_wireframe_rect,
&new_xor);
window->display->grab_wireframe_rect = new_xor;
/* do this after drawing the wires, so we don't draw over it */
meta_window_refresh_resize_popup (window);
}
else
{
meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity);
}
/* If we don't actually resize the window, we clear the timestamp,
* so we'll quickly try again. Otherwise you get "stuck" because
@ -6219,6 +6292,13 @@ meta_window_refresh_resize_popup (MetaWindow *window)
if (window->display->grab_window != window)
return;
/* FIXME for now we bail out when doing wireframe, because our
* server grab keeps us from being able to redraw the stuff
* underneath the resize popup.
*/
if (window->display->grab_wireframe_active)
return;
switch (window->display->grab_op)
{
case META_GRAB_OP_RESIZING_SE:
@ -6257,7 +6337,7 @@ meta_window_refresh_resize_popup (MetaWindow *window)
if (window->display->grab_resize_popup != NULL)
{
int gravity;
int x, y;
int x, y, width, height;
MetaFrameGeometry fgeom;
if (window->frame)
@ -6273,13 +6353,24 @@ meta_window_refresh_resize_popup (MetaWindow *window)
gravity = meta_resize_gravity_from_grab_op (window->display->grab_op);
g_assert (gravity >= 0);
if (window->display->grab_wireframe_active)
{
x = window->display->grab_wireframe_rect.x;
y = window->display->grab_wireframe_rect.y;
width = window->display->grab_wireframe_rect.width;
height = window->display->grab_wireframe_rect.height;
}
else
{
meta_window_get_position (window, &x, &y);
width = window->rect.width;
height = window->rect.height;
}
meta_ui_resize_popup_set (window->display->grab_resize_popup,
gravity,
x, y,
window->rect.width,
window->rect.height,
width, height,
window->size_hints.base_width,
window->size_hints.base_height,
window->size_hints.min_width,
@ -6406,53 +6497,70 @@ meta_window_is_ancestor_of_transient (MetaWindow *window,
return d.found;
}
/* Warp pointer to location appropriate for grab,
* return root coordinates where pointer ended up.
*/
static gboolean
warp_pointer (MetaWindow *window,
warp_grab_pointer (MetaWindow *window,
MetaGrabOp grab_op,
int *x,
int *y)
{
MetaRectangle rect;
/* We may not have done begin_grab_op yet, i.e. may not be in a grab
*/
if (window == window->display->grab_window &&
window->display->grab_wireframe_active)
rect = window->display->grab_wireframe_rect;
else
{
rect = window->rect;
meta_window_get_position (window, &rect.x, &rect.y);
}
switch (grab_op)
{
case META_GRAB_OP_KEYBOARD_MOVING:
case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
*x = window->rect.width / 2;
*y = window->rect.height / 2;
*x = rect.width / 2;
*y = rect.height / 2;
break;
case META_GRAB_OP_KEYBOARD_RESIZING_S:
*x = window->rect.width / 2;
*y = window->rect.height;
*x = rect.width / 2;
*y = rect.height;
break;
case META_GRAB_OP_KEYBOARD_RESIZING_N:
*x = window->rect.width / 2;
*x = rect.width / 2;
*y = 0;
break;
case META_GRAB_OP_KEYBOARD_RESIZING_W:
*x = 0;
*y = window->rect.height / 2;
*y = rect.height / 2;
break;
case META_GRAB_OP_KEYBOARD_RESIZING_E:
*x = window->rect.width;
*y = window->rect.height / 2;
*x = rect.width;
*y = rect.height / 2;
break;
case META_GRAB_OP_KEYBOARD_RESIZING_SE:
*x = window->rect.width;
*y = window->rect.height;
*x = rect.width;
*y = rect.height;
break;
case META_GRAB_OP_KEYBOARD_RESIZING_NE:
*x = window->rect.width;
*x = rect.width;
*y = 0;
break;
case META_GRAB_OP_KEYBOARD_RESIZING_SW:
*x = 0;
*y = window->rect.height;
*y = rect.height;
break;
case META_GRAB_OP_KEYBOARD_RESIZING_NW:
@ -6464,45 +6572,45 @@ warp_pointer (MetaWindow *window,
return FALSE;
}
*x += rect.x;
*y += rect.y;
meta_error_trap_push_with_return (window->display);
meta_topic (META_DEBUG_WINDOW_OPS,
"Warping pointer to %d,%d with window at %d,%d\n",
*x, *y, rect.x, rect.y);
XWarpPointer (window->display->xdisplay,
None,
window->xwindow,
window->screen->xroot,
0, 0, 0, 0,
*x,
*y);
*x, *y);
if (meta_error_trap_pop_with_return (window->display, FALSE) != Success)
{
meta_verbose ("Failed to warp pointer for window %s\n", window->desc);
meta_verbose ("Failed to warp pointer for window %s\n",
window->desc);
return FALSE;
}
return TRUE;
}
gboolean
meta_window_warp_pointer (MetaWindow *window,
MetaGrabOp grab_op)
{
int x, y;
return warp_pointer (window, grab_op, &x, &y);
}
void
meta_window_begin_grab_op (MetaWindow *window,
MetaGrabOp op,
Time timestamp)
{
int x, y, x_offset, y_offset;
int x, y;
gulong grab_start_serial;
meta_window_get_position (window, &x, &y);
grab_start_serial = XNextRequest (window->display->xdisplay);
meta_window_raise (window);
warp_pointer (window, op, &x_offset, &y_offset);
warp_grab_pointer (window,
op, &x, &y);
meta_display_begin_grab_op (window->display,
window->screen,
@ -6510,30 +6618,49 @@ meta_window_begin_grab_op (MetaWindow *window,
op,
FALSE, 0, 0,
timestamp,
x + x_offset,
y + y_offset);
x, y);
/* We override the one set in display_begin_grab_op since we
* did additional stuff as part of the grabbing process
*/
window->display->grab_start_serial = grab_start_serial;
}
void
meta_window_update_resize_grab_op (MetaWindow *window,
meta_window_update_keyboard_resize (MetaWindow *window,
gboolean update_cursor)
{
int x, y, x_offset, y_offset;
int x, y;
meta_window_get_position (window, &x, &y);
warp_grab_pointer (window,
window->display->grab_op,
&x, &y);
warp_pointer (window, window->display->grab_op, &x_offset, &y_offset);
/* As we warped the pointer, we have to reset the apparent
* initial window state, since if the mouse moves we want
* to use those events to do the right thing.
*/
if (window->display->grab_window == window)
{
window->display->grab_initial_root_x = x + x_offset;
window->display->grab_initial_root_y = y + y_offset;
/* As we warped the pointer, we have to reset the anchor state,
* since if the mouse moves we want to use those events to do the
* right thing. Also, this means that the motion notify
* from the pointer warp comes back as a no-op.
*/
int dx, dy;
window->display->grab_initial_window_pos = window->rect;
dx = x - window->display->grab_anchor_root_x;
dy = y - window->display->grab_anchor_root_y;
window->display->grab_anchor_root_x += dx;
window->display->grab_anchor_root_y += dy;
if (window->display->grab_wireframe_active)
{
window->display->grab_anchor_window_pos =
window->display->grab_wireframe_rect;
}
else
{
window->display->grab_anchor_window_pos = window->rect;
meta_window_get_position (window,
&window->display->grab_anchor_window_pos.x,
&window->display->grab_anchor_window_pos.y);
}
}
if (update_cursor)
@ -6547,6 +6674,16 @@ meta_window_update_resize_grab_op (MetaWindow *window,
}
}
void
meta_window_update_keyboard_move (MetaWindow *window)
{
int x, y;
warp_grab_pointer (window,
window->display->grab_op,
&x, &y);
}
void
meta_window_update_layer (MetaWindow *window)
{

View File

@ -469,15 +469,13 @@ void meta_window_foreach_ancestor (MetaWindow *window,
MetaWindowForeachFunc func,
void *data);
gboolean meta_window_warp_pointer (MetaWindow *window,
MetaGrabOp grab_op);
void meta_window_begin_grab_op (MetaWindow *window,
MetaGrabOp op,
Time timestamp);
void meta_window_update_resize_grab_op (MetaWindow *window,
void meta_window_update_keyboard_resize (MetaWindow *window,
gboolean update_cursor);
void meta_window_update_keyboard_move (MetaWindow *window);
void meta_window_update_layer (MetaWindow *window);