Commit e98fad3e authored by Havoc Pennington's avatar Havoc Pennington Committed by Havoc Pennington
Browse files

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
parent 6628acb5
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
......
......@@ -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.
......
......@@ -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);
}
......@@ -1296,7 +1299,8 @@ event_callback (XEvent *event,
case ButtonPress:
if ((window &&
grab_op_is_mouse (display->grab_op) &&
display->grab_button != (int) event->xbutton.button &&
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.
......@@ -2823,7 +2835,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
if (pointer_already_grabbed)
display->grab_have_pointer = TRUE;
meta_display_set_grab_op_cursor (display, screen, op, FALSE, grab_xwindow,
timestamp);
......@@ -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;
......@@ -3009,6 +3047,21 @@ meta_display_end_grab_op (MetaDisplay *display,
display->grab_update_alarm);
}
#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;
......
......@@ -225,19 +225,24 @@ 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;
Time grab_motion_notify_time;
/* we use property updates as sentinels for certain window focus events
* to avoid some race conditions on EnterNotify events
*/
......
......@@ -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);
}
......@@ -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 */
......@@ -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;
}
......
......@@ -27,6 +27,7 @@
#include "frame.h"
#include "place.h"
#include "prefs.h"
#include "effects.h"
#include <X11/keysym.h>
#include <string.h>
......@@ -1693,10 +1694,24 @@ process_keyboard_move_grab (MetaDisplay *display,
if (is_modifier (display, event->xkey.keycode))
return TRUE;
meta_window_get_position (window, &x, &y);
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 (smart_snap || ((edge > y) && ABS (edge - y) < incr))
y = edge;
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 (smart_snap || ((edge < y) && ABS (edge - y) < incr))
y = edge;
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 (smart_snap || ((edge > x) && ABS (edge - x) < incr))
x = edge;
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 (smart_snap || ((edge < x) && ABS (edge - x) < incr))
x = edge;
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_window_move (window, TRUE, x, y);
meta_window_warp_pointer (window, display->grab_op);
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_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,20 +1990,38 @@ 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;
}
}
meta_window_get_position (window, &orig_x, &orig_y);
x = orig_x;
y = orig_y;
width = window->rect.width;
height = window->rect.height;
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);