summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRob Adams <robadams@ucla.edu>2003-07-28 02:09:20 +0000
committerRob Adams <readams@src.gnome.org>2003-07-28 02:09:20 +0000
commit57272355723dabb869e19dc81b4c0dba6ad94a6d (patch)
tree62da2a99b3d88686daebfe611038335ce33ff24c /src
parent74fa2a7ab2aa1f1cb750805993ca38e9f7e3eaff (diff)
downloadmetacity-57272355723dabb869e19dc81b4c0dba6ad94a6d.tar.gz
Update window shaking loose so that the window is moved to the pointer and
2003-07-27 Rob Adams <robadams@ucla.edu> * src/window.c (update_move): Update window shaking loose so that the window is moved to the pointer and certain drag state is properly restored once windows "reattach". Fix for #115000 based on the patch by Jurg Billeter. * src/screen.c (meta_screen_resize): Invalidate work areas after an xrandr screen size update. Fix for #117230. * src/stack.c (window_is_fullscreen_size): Check the bottom corner of the window in addition to the top corner. Fix for #118194. * src/constraints.c (meta_window_constrain): Support aspect ratio hints in the new constraints code. Fix for #113798. * src/tools/metacity-window-demo.c (toggle_aspect_ratio): toggle the aspect ratio hints to force a 16:9 aspect ratio. (do_appwindow): add a button to toggle aspect ratio.
Diffstat (limited to 'src')
-rw-r--r--src/constraints.c53
-rw-r--r--src/stack.c8
-rw-r--r--src/tools/metacity-window-demo.c100
-rw-r--r--src/window.c57
4 files changed, 147 insertions, 71 deletions
diff --git a/src/constraints.c b/src/constraints.c
index dba1d2f2..8e647ecb 100644
--- a/src/constraints.c
+++ b/src/constraints.c
@@ -1411,7 +1411,6 @@ meta_window_constrain (MetaWindow *window,
current = *new;
}
-#if 0
/* Now we have to sort out the aspect ratio */
if (!window->fullscreen)
{
@@ -1429,19 +1428,33 @@ meta_window_constrain (MetaWindow *window,
width = current.width;
height = current.height;
- /* Use the standard cut-and-pasted-between-every-WM code: */
if (min_aspect * height > width)
{
int delta;
- delta = FLOOR (height - width / min_aspect, window->size_hints.height_inc);
- if (height - delta >= window->size_hints.min_height)
- height -= delta;
- else
+ if (y_direction == META_RESIZE_CENTER)
{
delta = FLOOR (height * min_aspect - width, window->size_hints.width_inc);
if (width + delta <= window->size_hints.max_width)
width += delta;
+ else
+ {
+ delta = FLOOR (height - width / min_aspect, window->size_hints.height_inc);
+ if (height - delta >= window->size_hints.min_height)
+ height -= delta;
+ }
+ }
+ else
+ {
+ delta = FLOOR (height - width / min_aspect, window->size_hints.height_inc);
+ if (height - delta >= window->size_hints.min_height)
+ height -= delta;
+ else
+ {
+ delta = FLOOR (height * min_aspect - width, window->size_hints.width_inc);
+ if (width + delta <= window->size_hints.max_width)
+ width += delta;
+ }
}
}
@@ -1449,14 +1462,29 @@ meta_window_constrain (MetaWindow *window,
{
int delta;
- delta = FLOOR (width - height * max_aspect, window->size_hints.width_inc);
- if (width - delta >= window->size_hints.min_width)
- width -= delta;
- else
+ if (x_direction == META_RESIZE_CENTER)
{
delta = FLOOR (width / max_aspect - height, window->size_hints.height_inc);
if (height + delta <= window->size_hints.max_height)
height += delta;
+ else
+ {
+ delta = FLOOR (width - height * max_aspect, window->size_hints.width_inc);
+ if (width - delta >= window->size_hints.min_width)
+ width -= delta;
+ }
+ }
+ else
+ {
+ delta = FLOOR (width - height * max_aspect, window->size_hints.width_inc);
+ if (width - delta >= window->size_hints.min_width)
+ width -= delta;
+ else
+ {
+ delta = FLOOR (width / max_aspect - height, window->size_hints.height_inc);
+ if (height + delta <= window->size_hints.max_height)
+ height += delta;
+ }
}
}
@@ -1508,13 +1536,8 @@ meta_window_constrain (MetaWindow *window,
}
current = *new;
-
- g_print ("3 x_delta = %d y_delta = %d pos = %d,%d size = %dx%d\n",
- x_delta, y_delta,
- current.x, current.y, current.width, current.height);
}
-#endif
meta_topic (META_DEBUG_GEOMETRY,
"Constrained %s new %d,%d %dx%d old %d,%d %dx%d\n",
window->desc,
diff --git a/src/stack.c b/src/stack.c
index 31d6d76c..7a97e80a 100644
--- a/src/stack.c
+++ b/src/stack.c
@@ -193,7 +193,9 @@ window_is_fullscreen_size (MetaWindow *window)
meta_window_get_work_area_current_xinerama (window, &workarea);
if (window->rect.x <= workarea.x &&
- window->rect.y <= workarea.y)
+ window->rect.y <= workarea.y &&
+ window->rect.x + window->rect.width >= workarea.x + workarea.width &&
+ window->rect.y + window->rect.height >= workarea.y + workarea.height)
return TRUE;
}
@@ -207,7 +209,9 @@ window_is_fullscreen_size (MetaWindow *window)
meta_window_get_work_area_current_xinerama (window, &workarea);
if (window->rect.x <= workarea.x &&
- window->rect.y <= workarea.y)
+ window->rect.y <= workarea.y &&
+ window->rect.x + window->rect.width >= workarea.x + workarea.width &&
+ window->rect.y + window->rect.height >= workarea.y + workarea.height)
return TRUE;
}
diff --git a/src/tools/metacity-window-demo.c b/src/tools/metacity-window-demo.c
index 718f1f0a..a3dc157b 100644
--- a/src/tools/metacity-window-demo.c
+++ b/src/tools/metacity-window-demo.c
@@ -26,6 +26,8 @@
static GtkWidget* do_appwindow (void);
+gboolean aspect_on;
+
static void
set_gdk_window_struts (GdkWindow *window,
int left,
@@ -702,6 +704,34 @@ sleep_cb (GtkWidget *button,
sleep (1000);
}
+toggle_aspect_ratio (GtkWidget *button,
+ gpointer data)
+{
+ GtkWidget *window;
+ GdkGeometry geom;
+
+ if (aspect_on)
+ {
+ geom.min_aspect = 0;
+ geom.max_aspect = 65535;
+ }
+ else
+ {
+ geom.min_aspect = 1.777778;
+ geom.max_aspect = 1.777778;
+ }
+
+ aspect_on = !aspect_on;
+
+ window = gtk_widget_get_ancestor (button, GTK_TYPE_WINDOW);
+ if (window)
+ gtk_window_set_geometry_hints (GTK_WINDOW (window),
+ GTK_WIDGET (data),
+ &geom,
+ GDK_HINT_ASPECT);
+
+}
+
static void
toggle_decorated_cb (GtkWidget *button,
gpointer data)
@@ -799,7 +829,9 @@ do_appwindow (void)
*/
++window_count;
-
+
+ aspect_on = FALSE;
+
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Application Window");
@@ -838,6 +870,35 @@ do_appwindow (void)
GTK_EXPAND | GTK_FILL, 0,
0, 0);
+ /* Create document
+ */
+
+ sw = gtk_scrolled_window_new (NULL, NULL);
+
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
+ GTK_SHADOW_IN);
+
+ gtk_table_attach (GTK_TABLE (table),
+ sw,
+ /* X direction */ /* Y direction */
+ 0, 1, 2, 3,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+ 0, 0);
+
+ gtk_window_set_default_size (GTK_WINDOW (window),
+ 200, 200);
+
+ contents = gtk_text_view_new ();
+ gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (contents),
+ PANGO_WRAP_WORD);
+
+ gtk_container_add (GTK_CONTAINER (sw),
+ contents);
+
/* Create the toolbar
*/
toolbar = gtk_toolbar_new ();
@@ -867,6 +928,14 @@ do_appwindow (void)
-1); /* -1 means "append" */
gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
+ GTK_STOCK_OPEN,
+ "This is a demo button that locks the aspect ratio using a hint",
+ NULL,
+ G_CALLBACK (toggle_aspect_ratio),
+ contents, /* user data for callback */
+ -1); /* -1 means "append" */
+
+ gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
GTK_STOCK_QUIT,
"This is a demo button with a 'quit' icon",
NULL,
@@ -885,35 +954,6 @@ do_appwindow (void)
GTK_EXPAND | GTK_FILL, 0,
0, 0);
- /* Create document
- */
-
- sw = gtk_scrolled_window_new (NULL, NULL);
-
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
-
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
- GTK_SHADOW_IN);
-
- gtk_table_attach (GTK_TABLE (table),
- sw,
- /* X direction */ /* Y direction */
- 0, 1, 2, 3,
- GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
- 0, 0);
-
- gtk_window_set_default_size (GTK_WINDOW (window),
- 200, 200);
-
- contents = gtk_text_view_new ();
- gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (contents),
- PANGO_WRAP_WORD);
-
- gtk_container_add (GTK_CONTAINER (sw),
- contents);
-
/* Create statusbar */
statusbar = gtk_statusbar_new ();
diff --git a/src/window.c b/src/window.c
index d3595e79..b831c1cf 100644
--- a/src/window.c
+++ b/src/window.c
@@ -5623,17 +5623,27 @@ update_move (MetaWindow *window,
if (window->maximized && ABS (dy) >= shake_threshold)
{
+ double prop;
+
/* Shake loose */
-
window->shaken_loose = TRUE;
+
+ /* move the unmaximized window to the cursor */
+ prop =
+ ((double)(x - window->display->grab_initial_window_pos.x)) /
+ ((double)window->display->grab_initial_window_pos.width);
- /* 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;
+ window->display->grab_initial_window_pos.x =
+ x - window->saved_rect.width * prop;
+ window->display->grab_initial_window_pos.y = y;
+
+ if (window->frame)
+ {
+ window->display->grab_initial_window_pos.y += window->frame->child_y / 2;
+ }
+
+ window->saved_rect.x = window->display->grab_initial_window_pos.x-dx;
+ window->saved_rect.y = window->display->grab_initial_window_pos.y-dy;
meta_window_unmaximize (window);
@@ -5645,30 +5655,28 @@ update_move (MetaWindow *window,
else if (window->shaken_loose || window->maximized)
{
const MetaXineramaScreenInfo *wxinerama;
+ MetaRectangle work_area;
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))
+ meta_window_get_work_area_for_xinerama (window, monitor, &work_area);
+
+ /* check if cursor is near the top of a xinerama work area */
+ if (x >= work_area.x &&
+ x < (work_area.x + work_area.width) &&
+ y >= work_area.y &&
+ y < (work_area.y + 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;
+ window->saved_rect.x = work_area.x;
+ window->saved_rect.y = work_area.y;
if (window->frame)
{
@@ -5679,11 +5687,12 @@ update_move (MetaWindow *window,
meta_window_unmaximize (window);
}
- window->shaken_loose = FALSE;
-
- meta_window_maximize (window);
+ window->display->grab_initial_window_pos = work_area;
+ window->shaken_loose = FALSE;
+
+ meta_window_maximize (window);
- return;
+ return;
}
}
}