From aacfc6ed95660ce3d730b557f91baa43636f19fd Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Tue, 2 Sep 2008 16:06:42 -0500 Subject: [PATCH] explorer: Modify rects passed to SHAppBarMessage to not interfere with existing appbars. --- dlls/shell32/tests/appbar.c | 28 ++++++++++---------- programs/explorer/appbar.c | 51 +++++++++++++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 16 deletions(-) diff --git a/dlls/shell32/tests/appbar.c b/dlls/shell32/tests/appbar.c index 108ead33dbe..8c2315ffc49 100644 --- a/dlls/shell32/tests/appbar.c +++ b/dlls/shell32/tests/appbar.c @@ -189,7 +189,7 @@ static void test_setpos(void) do_events(); /* the windows are adjusted to they don't overlap */ - todo_wine ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window2_info.allocated_rect), + ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window2_info.allocated_rect), "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); @@ -198,7 +198,7 @@ static void test_setpos(void) window1_info.desired_rect.top = screen_height - 20; testwindow_setpos(window1); do_events(); - todo_wine ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window2_info.allocated_rect), + ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window2_info.allocated_rect), "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); @@ -224,15 +224,15 @@ static void test_setpos(void) testwindow_setpos(window3); do_events(); - todo_wine ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window2_info.allocated_rect), + ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window2_info.allocated_rect), "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); - todo_wine ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window3_info.allocated_rect), + ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window3_info.allocated_rect), "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom); - todo_wine ok(!IntersectRect(&rc, &window3_info.allocated_rect, &window2_info.allocated_rect), + ok(!IntersectRect(&rc, &window3_info.allocated_rect, &window2_info.allocated_rect), "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom, window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); @@ -246,15 +246,15 @@ static void test_setpos(void) testwindow_setpos(window3); do_events(); - todo_wine ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window2_info.allocated_rect), + ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window2_info.allocated_rect), "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); - todo_wine ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window3_info.allocated_rect), + ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window3_info.allocated_rect), "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom); - todo_wine ok(!IntersectRect(&rc, &window3_info.allocated_rect, &window2_info.allocated_rect), + ok(!IntersectRect(&rc, &window3_info.allocated_rect, &window2_info.allocated_rect), "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom, window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); @@ -272,11 +272,11 @@ static void test_setpos(void) "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); - todo_wine ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window3_info.allocated_rect), + ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window3_info.allocated_rect), "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom); - todo_wine ok(!IntersectRect(&rc, &window3_info.allocated_rect, &window2_info.allocated_rect), + ok(!IntersectRect(&rc, &window3_info.allocated_rect, &window2_info.allocated_rect), "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom, window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); @@ -290,15 +290,15 @@ static void test_setpos(void) testwindow_setpos(window2); do_events(); - todo_wine ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window2_info.allocated_rect), + ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window2_info.allocated_rect), "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); - todo_wine ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window3_info.allocated_rect), + ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window3_info.allocated_rect), "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom); - todo_wine ok(!IntersectRect(&rc, &window3_info.allocated_rect, &window2_info.allocated_rect), + ok(!IntersectRect(&rc, &window3_info.allocated_rect, &window2_info.allocated_rect), "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom, window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); @@ -315,7 +315,7 @@ static void test_setpos(void) ok(window2_info.allocated_rect.bottom = expected, "window2's bottom is %i, expected %i\n", window2_info.allocated_rect.bottom, expected); - todo_wine ok(!IntersectRect(&rc, &window3_info.allocated_rect, &window2_info.allocated_rect), + ok(!IntersectRect(&rc, &window3_info.allocated_rect, &window2_info.allocated_rect), "rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom, window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); diff --git a/programs/explorer/appbar.c b/programs/explorer/appbar.c index b67a60eb982..810231819c2 100644 --- a/programs/explorer/appbar.c +++ b/programs/explorer/appbar.c @@ -16,6 +16,15 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + * TODO: freedesktop _NET_WM_STRUT integration + * + * TODO: find when a fullscreen app is in the foreground and send FULLSCREENAPP + * notifications + * + * TODO: detect changes in the screen size and send ABN_POSCHANGED ? + * + * TODO: multiple monitor support */ #include "wine/unicode.h" @@ -82,6 +91,39 @@ static void send_poschanged(HWND hwnd) } } +/* appbar_cliprect: cut out parts of the rectangle that interfere with existing appbars */ +static void appbar_cliprect(PAPPBARDATA abd) +{ + struct appbar_data* data; + LIST_FOR_EACH_ENTRY(data, &appbars, struct appbar_data, entry) + { + if (data->hwnd == abd->hWnd) + { + /* we only care about appbars that were added before this one */ + return; + } + if (data->space_reserved) + { + /* move in the side that corresponds to the other appbar's edge */ + switch (data->edge) + { + case ABE_BOTTOM: + abd->rc.bottom = min(abd->rc.bottom, data->rc.top); + break; + case ABE_LEFT: + abd->rc.left = max(abd->rc.left, data->rc.right); + break; + case ABE_RIGHT: + abd->rc.right = min(abd->rc.right, data->rc.left); + break; + case ABE_TOP: + abd->rc.top = max(abd->rc.top, data->rc.bottom); + break; + } + } + } +} + static UINT_PTR handle_appbarmessage(DWORD msg, PAPPBARDATA abd) { struct appbar_data* data; @@ -120,10 +162,11 @@ static UINT_PTR handle_appbarmessage(DWORD msg, PAPPBARDATA abd) WINE_WARN("removing hwnd %p not on the list\n", abd->hWnd); return TRUE; case ABM_QUERYPOS: - WINE_FIXME("SHAppBarMessage(ABM_QUERYPOS, hwnd=%p, edge=%x, rc=%s): stub\n", abd->hWnd, abd->uEdge, wine_dbgstr_rect(&abd->rc)); + if (abd->uEdge > ABE_BOTTOM) + WINE_WARN("invalid edge %i for %p\n", abd->uEdge, abd->hWnd); + appbar_cliprect(abd); return TRUE; case ABM_SETPOS: - WINE_FIXME("SHAppBarMessage(ABM_SETPOS, hwnd=%p, edge=%x, rc=%s): stub\n", abd->hWnd, abd->uEdge, wine_dbgstr_rect(&abd->rc)); if (abd->uEdge > ABE_BOTTOM) { WINE_WARN("invalid edge %i for %p\n", abd->uEdge, abd->hWnd); @@ -131,9 +174,13 @@ static UINT_PTR handle_appbarmessage(DWORD msg, PAPPBARDATA abd) } if ((data = get_appbar(abd->hWnd))) { + /* calculate acceptable space */ + appbar_cliprect(abd); + if (!EqualRect(&abd->rc, &data->rc)) send_poschanged(abd->hWnd); + /* reserve that space for this appbar */ data->edge = abd->uEdge; data->rc = abd->rc; data->space_reserved = TRUE;