From 57272355723dabb869e19dc81b4c0dba6ad94a6d Mon Sep 17 00:00:00 2001 From: Rob Adams Date: Mon, 28 Jul 2003 02:09:20 +0000 Subject: [PATCH] Update window shaking loose so that the window is moved to the pointer and 2003-07-27 Rob Adams * 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. --- ChangeLog | 20 +++++++ src/constraints.c | 53 +++++++++++----- src/stack.c | 8 ++- src/tools/metacity-window-demo.c | 100 +++++++++++++++++++++---------- src/window.c | 61 +++++++++++-------- 5 files changed, 169 insertions(+), 73 deletions(-) diff --git a/ChangeLog b/ChangeLog index 62a789689..6c51faea9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2003-07-27 Rob Adams + + * 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. + 2003-07-27 Havoc Pennington * src/theme-viewer.c (run_theme_benchmark): also measure wall diff --git a/src/constraints.c b/src/constraints.c index dba1d2f2e..8e647ecb8 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 31d6d76c6..7a97e80ac 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 718f1f0a6..a3dc157b2 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 (); @@ -866,6 +927,14 @@ do_appwindow (void) window, /* user data for callback */ -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", @@ -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 d3595e793..b831c1cf5 100644 --- a/src/window.c +++ b/src/window.c @@ -5623,17 +5623,27 @@ update_move (MetaWindow *window, if (window->maximized && ABS (dy) >= shake_threshold) { - /* Shake loose */ - - window->shaken_loose = TRUE; + double prop; - /* 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; + /* 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); + + 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; + window->display->grab_initial_window_pos = work_area; + window->shaken_loose = FALSE; + + meta_window_maximize (window); - meta_window_maximize (window); - - return; + return; } } }