summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHavoc Pennington <hp@pobox.com>2003-06-12 05:55:06 +0000
committerHavoc Pennington <hp@src.gnome.org>2003-06-12 05:55:06 +0000
commit0a20419628ab061c6442b2963e9ae6bceb2667a1 (patch)
treeb89965e94ac4a755d43f320b238d0f3e82f12155
parent2d4503ee593dbed1ca3b32729cee427b66103b4d (diff)
downloadmetacity-0a20419628ab061c6442b2963e9ae6bceb2667a1.tar.gz
make raise-on-click explicitly only happen in click to focus mode.
2003-06-12 Havoc Pennington <hp@pobox.com> * src/display.c (event_callback): make raise-on-click explicitly only happen in click to focus mode. * src/window.c (update_move): apply patch from Jurg Billeter to allow you to "shake loose" maximized windows and move them between Xinerama heads. #93586 * src/display.c: delete event_queue_callback * src/display.h (struct _MetaDisplay): get rid of grab_current_window_pos and grab_current_root_[xy] as I could find absolutely no code using them for anything. They were just sort of randomly assigned to for no apparent reason. * src/display.c (event_callback): double-click timeout is per screen, so get the screen and pass screen->ui to meta_ui_get_double_click_timeout() * src/ui.c (meta_ui_get_double_click_timeout): take a MetaUI argument so we get the right settings for each screen (meta_ui_get_drag_threshold): new function
-rw-r--r--ChangeLog24
-rw-r--r--src/display.c62
-rw-r--r--src/display.h3
-rw-r--r--src/ui.c28
-rw-r--r--src/ui.h3
-rw-r--r--src/window.c119
-rw-r--r--src/window.h9
7 files changed, 197 insertions, 51 deletions
diff --git a/ChangeLog b/ChangeLog
index 80b5c067..9fcbdb9a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2003-06-12 Havoc Pennington <hp@pobox.com>
+
+ * src/display.c (event_callback): make raise-on-click explicitly
+ only happen in click to focus mode.
+
+ * src/window.c (update_move): apply patch from Jurg Billeter to
+ allow you to "shake loose" maximized windows and move them between
+ Xinerama heads. #93586
+
+ * src/display.c: delete event_queue_callback
+
+ * src/display.h (struct _MetaDisplay): get rid of
+ grab_current_window_pos and grab_current_root_[xy] as I could find
+ absolutely no code using them for anything. They were just sort of
+ randomly assigned to for no apparent reason.
+
+ * src/display.c (event_callback): double-click timeout is per
+ screen, so get the screen and pass screen->ui to
+ meta_ui_get_double_click_timeout()
+
+ * src/ui.c (meta_ui_get_double_click_timeout): take a MetaUI
+ argument so we get the right settings for each screen
+ (meta_ui_get_drag_threshold): new function
+
2003-06-09 Rob Adams <robadams@ucla.edu>
Revamp placement policy for windows that are maximized when they
diff --git a/src/display.c b/src/display.c
index a9e3f30e..764d5ee9 100644
--- a/src/display.c
+++ b/src/display.c
@@ -77,8 +77,6 @@ static GSList *all_displays = NULL;
static void meta_spew_event (MetaDisplay *display,
XEvent *event);
-static void event_queue_callback (XEvent *event,
- gpointer data);
static gboolean event_callback (XEvent *event,
gpointer data);
static Window event_get_modified_window (MetaDisplay *display,
@@ -898,14 +896,6 @@ meta_display_is_double_click (MetaDisplay *display)
static gboolean dump_events = TRUE;
-
-static void
-event_queue_callback (XEvent *event,
- gpointer data)
-{
- event_callback (event, data);
-}
-
static gboolean
grab_op_is_mouse (MetaGrabOp op)
{
@@ -1119,6 +1109,28 @@ window_raise_with_delay_callback (void *data)
return FALSE;
}
+static int
+double_click_timeout_for_event (MetaDisplay *display,
+ XEvent *event)
+{
+ MetaScreen *screen;
+
+ g_assert (event->type == ButtonPress ||
+ event->type == ButtonRelease);
+
+ screen = meta_display_screen_for_root (display,
+ event->xbutton.root);
+ if (screen == NULL)
+ {
+ /* Odd, we aren't managing this screen */
+ meta_warning ("Received button event on root 0x%lx we aren't managing\n",
+ event->xbutton.root);
+ return 250; /* make up number */
+ }
+
+ return meta_ui_get_double_click_timeout (screen->ui);
+}
+
static gboolean
event_callback (XEvent *event,
gpointer data)
@@ -1154,7 +1166,9 @@ event_callback (XEvent *event,
/* mark double click events, kind of a hack, oh well. */
if (((int)event->xbutton.button) == display->last_button_num &&
event->xbutton.window == display->last_button_xwindow &&
- event->xbutton.time < (display->last_button_time + meta_ui_get_double_click_timeout ()))
+ event->xbutton.time < (display->last_button_time +
+ double_click_timeout_for_event (display,
+ event)))
{
display->is_double_click = TRUE;
meta_topic (META_DEBUG_EVENTS,
@@ -1321,12 +1335,20 @@ event_callback (XEvent *event,
* frames.c or special-cased if the click was on a
* minimize/close button.
*/
- meta_window_raise (window);
-
- meta_topic (META_DEBUG_FOCUS,
- "Focusing %s due to unmodified button %d press (display.c)\n",
- window->desc, event->xbutton.button);
- meta_window_focus (window, event->xbutton.time);
+ if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK)
+ {
+ meta_window_raise (window);
+
+ meta_topic (META_DEBUG_FOCUS,
+ "Focusing %s due to unmodified button %d press (display.c)\n",
+ window->desc, event->xbutton.button);
+ meta_window_focus (window, event->xbutton.time);
+ }
+ else
+ {
+ meta_topic (META_DEBUG_FOCUS,
+ "Not raising/focusing window on click due to mouse/sloppy focus mode\n");
+ }
}
/* you can move on alt-click but not on
@@ -2823,8 +2845,6 @@ meta_display_begin_grab_op (MetaDisplay *display,
display->grab_mask = modmask;
display->grab_initial_root_x = root_x;
display->grab_initial_root_y = root_y;
- display->grab_current_root_x = root_x;
- display->grab_current_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;
@@ -2840,7 +2860,6 @@ 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_current_window_pos = display->grab_initial_window_pos;
#ifdef HAVE_XSYNC
if (meta_grab_op_is_resizing (display->grab_op) &&
@@ -2930,6 +2949,9 @@ meta_display_end_grab_op (MetaDisplay *display,
if (display->grab_op == META_GRAB_OP_NONE)
return;
+ if (display->grab_window != NULL)
+ display->grab_window->shaken_loose = FALSE;
+
if (display->grab_op == META_GRAB_OP_KEYBOARD_TABBING_NORMAL ||
display->grab_op == META_GRAB_OP_KEYBOARD_TABBING_DOCK ||
display->grab_op == META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL ||
diff --git a/src/display.h b/src/display.h
index 65f43b13..cea93003 100644
--- a/src/display.h
+++ b/src/display.h
@@ -237,15 +237,12 @@ struct _MetaDisplay
int grab_button;
int grab_initial_root_x;
int grab_initial_root_y;
- int grab_current_root_x;
- int grab_current_root_y;
int grab_latest_motion_x;
int grab_latest_motion_y;
gulong grab_mask;
guint grab_have_pointer : 1;
guint grab_have_keyboard : 1;
MetaRectangle grab_initial_window_pos;
- MetaRectangle grab_current_window_pos;
MetaResizePopup *grab_resize_popup;
GTimeVal grab_last_moveresize_time;
Time grab_motion_notify_time;
diff --git a/src/ui.c b/src/ui.c
index 1a668dde..eff54f27 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -767,21 +767,29 @@ meta_stock_icons_init (void)
}
int
-meta_ui_get_double_click_timeout (void)
+meta_ui_get_double_click_timeout (MetaUI *ui)
{
GtkSettings *settings;
- GObjectClass *klass;
- int timeout = 0;
+ int timeout;
- settings = gtk_settings_get_default ();
-
- klass = G_OBJECT_CLASS (GTK_SETTINGS_GET_CLASS (settings));
- if (g_object_class_find_property (klass, "gtk-double-click-time") == NULL)
- {
- return 250;
- }
+ settings = gtk_widget_get_settings (GTK_WIDGET (ui->frames));
+ timeout = 250;
g_object_get (G_OBJECT (settings), "gtk-double-click-time", &timeout, NULL);
return timeout;
}
+
+int
+meta_ui_get_drag_threshold (MetaUI *ui)
+{
+ GtkSettings *settings;
+ int threshold;
+
+ settings = gtk_widget_get_settings (GTK_WIDGET (ui->frames));
+
+ threshold = 8;
+ g_object_get (G_OBJECT (settings), "gtk-dnd-drag-threshold", &threshold, NULL);
+
+ return threshold;
+}
diff --git a/src/ui.h b/src/ui.h
index 171c342d..6ed69041 100644
--- a/src/ui.h
+++ b/src/ui.h
@@ -165,7 +165,8 @@ gboolean meta_ui_parse_modifier (const char *accel,
gboolean meta_ui_window_is_widget (MetaUI *ui,
Window xwindow);
-int meta_ui_get_double_click_timeout (void);
+int meta_ui_get_double_click_timeout (MetaUI *ui);
+int meta_ui_get_drag_threshold (MetaUI *ui);
#include "tabpopup.h"
diff --git a/src/window.c b/src/window.c
index 31af946b..565c31dd 100644
--- a/src/window.c
+++ b/src/window.c
@@ -440,6 +440,7 @@ meta_window_new (MetaDisplay *display,
window->withdrawn = FALSE;
window->initial_workspace_set = FALSE;
window->calc_placement = FALSE;
+ window->shaken_loose = FALSE;
window->unmaps_pending = 0;
@@ -5693,15 +5694,95 @@ update_move (MetaWindow *window,
{
int dx, dy;
int new_x, new_y;
-
+ int shake_threshold;
+
window->display->grab_latest_motion_x = x;
window->display->grab_latest_motion_y = y;
- dx = x - window->display->grab_current_root_x;
- dy = y - window->display->grab_current_root_y;
+ dx = x - window->display->grab_initial_root_x;
+ dy = y - window->display->grab_initial_root_y;
+
+ new_x = window->display->grab_initial_window_pos.x + dx;
+ new_y = window->display->grab_initial_window_pos.y + 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.
+ */
+
+#define DRAG_THRESHOLD_TO_SHAKE_THRESHOLD_FACTOR 6
+ shake_threshold = meta_ui_get_drag_threshold (window->screen->ui) *
+ DRAG_THRESHOLD_TO_SHAKE_THRESHOLD_FACTOR;
+
+ if (window->maximized && ABS (dy) >= shake_threshold)
+ {
+ /* Shake loose */
+
+ window->shaken_loose = TRUE;
+
+ /* Unmaximize at wherever the window would have moved to if it
+ * hadn't been maximized. FIXME if you grab the right side of
+ * the titlebar then on unmaximize the pointer isn't on the
+ * titlebar which is kind of odd.
+ */
+ window->saved_rect.x = new_x;
+ window->saved_rect.y = new_y;
+
+ meta_window_unmaximize (window);
+
+ return;
+ }
+ /* remaximize window on an other xinerama monitor if window has
+ * been shaken loose or it is still maximized (then move straight)
+ */
+ else if (window->shaken_loose || window->maximized)
+ {
+ const MetaXineramaScreenInfo *wxinerama;
+ int monitor;
+
+ wxinerama = meta_screen_get_xinerama_for_window (window->screen, window);
+
+ for (monitor = 0; monitor < window->screen->n_xinerama_infos; monitor++)
+ {
+ /* FIXME this should check near the top of the work area probably,
+ * maybe only counting full-monitor-width panels in work area
+ * for this purpose.
+ */
+ /* check if cursor is near the top of a xinerama monitor */
+ if (x >= window->screen->xinerama_infos[monitor].x_origin &&
+ x < (window->screen->xinerama_infos[monitor].x_origin +
+ window->screen->xinerama_infos[monitor].width) &&
+ y >= window->screen->xinerama_infos[monitor].y_origin &&
+ y < (window->screen->xinerama_infos[monitor].y_origin + shake_threshold))
+ {
+ /* move the saved rect if window will become maximized on an
+ * other monitor so user isn't surprised on a later unmaximize
+ */
+ if (wxinerama->number != monitor)
+ {
+ window->saved_rect.x = window->screen->xinerama_infos[monitor].x_origin;
+ window->saved_rect.y = window->screen->xinerama_infos[monitor].y_origin;
+
+ if (window->frame)
+ {
+ window->saved_rect.x += window->frame->child_x;
+ window->saved_rect.y += window->frame->child_y;
+ }
+
+ meta_window_unmaximize (window);
+ }
- new_x = window->display->grab_current_window_pos.x + dx;
- new_y = window->display->grab_current_window_pos.y + dy;
+ window->shaken_loose = FALSE;
+
+ meta_window_maximize (window);
+
+ return;
+ }
+ }
+ }
+
+ /* don't allow a maximized window to move */
+ if (window->maximized)
+ return;
if (mask & ShiftMask)
{
@@ -5725,11 +5806,11 @@ update_resize (MetaWindow *window,
window->display->grab_latest_motion_x = x;
window->display->grab_latest_motion_y = y;
- dx = x - window->display->grab_current_root_x;
- dy = y - window->display->grab_current_root_y;
+ dx = x - window->display->grab_initial_root_x;
+ dy = y - window->display->grab_initial_root_y;
- new_w = window->display->grab_current_window_pos.width;
- new_h = window->display->grab_current_window_pos.height;
+ new_w = window->display->grab_initial_window_pos.width;
+ new_h = window->display->grab_initial_window_pos.height;
switch (window->display->grab_op)
{
@@ -6491,15 +6572,21 @@ meta_window_update_resize_grab_op (MetaWindow *window,
int x, y, x_offset, y_offset;
meta_window_get_position (window, &x, &y);
-
+
warp_pointer (window, window->display->grab_op, &x_offset, &y_offset);
- window->display->grab_current_root_x = x + x_offset;
- window->display->grab_current_root_y = y + y_offset;
-
- if (window->display->grab_window)
- window->display->grab_current_window_pos = window->rect;
-
+ /* 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;
+
+ window->display->grab_initial_window_pos = window->rect;
+ }
+
if (update_cursor)
{
meta_display_set_grab_op_cursor (window->display,
diff --git a/src/window.h b/src/window.h
index f9353d1e..5477367a 100644
--- a/src/window.h
+++ b/src/window.h
@@ -229,6 +229,9 @@ struct _MetaWindow
/* icon props have changed */
guint need_reread_icon : 1;
+ /* if TRUE, window was maximized at start of current grab op */
+ guint shaken_loose : 1;
+
#ifdef HAVE_XSYNC
/* XSync update counter */
XSyncCounter update_counter;
@@ -288,7 +291,11 @@ struct _MetaWindow
MetaGroup *group;
};
-#define META_WINDOW_ALLOWS_MOVE(w) ((w)->has_move_func && !(w)->maximized && !(w)->fullscreen)
+/* These differ from window->has_foo_func in that they consider
+ * the dynamic window state such as "maximized", not just the
+ * window's type
+ */
+#define META_WINDOW_ALLOWS_MOVE(w) ((w)->has_move_func && !(w)->fullscreen)
#define META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS(w) ((w)->has_resize_func && !(w)->maximized && !(w)->fullscreen && !(w)->shaded)
#define META_WINDOW_ALLOWS_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && \
(((w)->size_hints.min_width < (w)->size_hints.max_width) || \