Commit aacfc6ed authored by Vincent Povirk's avatar Vincent Povirk Committed by Alexandre Julliard

explorer: Modify rects passed to SHAppBarMessage to not interfere with existing appbars.

parent 8adae9aa
...@@ -189,7 +189,7 @@ static void test_setpos(void) ...@@ -189,7 +189,7 @@ static void test_setpos(void)
do_events(); do_events();
/* the windows are adjusted to they don't overlap */ /* 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", "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, 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); 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) ...@@ -198,7 +198,7 @@ static void test_setpos(void)
window1_info.desired_rect.top = screen_height - 20; window1_info.desired_rect.top = screen_height - 20;
testwindow_setpos(window1); testwindow_setpos(window1);
do_events(); 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", "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, 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); 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) ...@@ -224,15 +224,15 @@ static void test_setpos(void)
testwindow_setpos(window3); testwindow_setpos(window3);
do_events(); 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", "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, 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); 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", "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, 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); 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", "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, 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); 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) ...@@ -246,15 +246,15 @@ static void test_setpos(void)
testwindow_setpos(window3); testwindow_setpos(window3);
do_events(); 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", "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, 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); 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", "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, 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); 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", "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, 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); 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) ...@@ -272,11 +272,11 @@ static void test_setpos(void)
"rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", "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, 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); 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", "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, 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); 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", "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, 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); 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) ...@@ -290,15 +290,15 @@ static void test_setpos(void)
testwindow_setpos(window2); testwindow_setpos(window2);
do_events(); 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", "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, 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); 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", "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, 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); 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", "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, 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); 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) ...@@ -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); 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", "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, 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); window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom);
......
...@@ -16,6 +16,15 @@ ...@@ -16,6 +16,15 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 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" #include "wine/unicode.h"
...@@ -82,6 +91,39 @@ static void send_poschanged(HWND hwnd) ...@@ -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) static UINT_PTR handle_appbarmessage(DWORD msg, PAPPBARDATA abd)
{ {
struct appbar_data* data; struct appbar_data* data;
...@@ -120,10 +162,11 @@ static UINT_PTR handle_appbarmessage(DWORD msg, PAPPBARDATA abd) ...@@ -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); WINE_WARN("removing hwnd %p not on the list\n", abd->hWnd);
return TRUE; return TRUE;
case ABM_QUERYPOS: 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; return TRUE;
case ABM_SETPOS: 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) if (abd->uEdge > ABE_BOTTOM)
{ {
WINE_WARN("invalid edge %i for %p\n", abd->uEdge, abd->hWnd); 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) ...@@ -131,9 +174,13 @@ static UINT_PTR handle_appbarmessage(DWORD msg, PAPPBARDATA abd)
} }
if ((data = get_appbar(abd->hWnd))) if ((data = get_appbar(abd->hWnd)))
{ {
/* calculate acceptable space */
appbar_cliprect(abd);
if (!EqualRect(&abd->rc, &data->rc)) if (!EqualRect(&abd->rc, &data->rc))
send_poschanged(abd->hWnd); send_poschanged(abd->hWnd);
/* reserve that space for this appbar */
data->edge = abd->uEdge; data->edge = abd->uEdge;
data->rc = abd->rc; data->rc = abd->rc;
data->space_reserved = TRUE; data->space_reserved = TRUE;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment