From 077d2433a7186550ee349284b1849ec2048af69c Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sat, 21 Jan 2012 15:07:53 +0000 Subject: [PATCH] Bugfix: Fix coordinates when the rect of an output changes (Thanks Paul) Fixes #623 --- include/floating.h | 7 +++++++ src/con.c | 15 +-------------- src/floating.c | 22 ++++++++++++++++++++++ src/randr.c | 12 +++++++++--- 4 files changed, 39 insertions(+), 17 deletions(-) diff --git a/include/floating.h b/include/floating.h index b6c7c6e3..43137c9c 100644 --- a/include/floating.h +++ b/include/floating.h @@ -146,4 +146,11 @@ void drag_pointer(Con *con, const xcb_button_press_event_t *event, */ void floating_reposition(Con *con, Rect newrect); +/** + * Fixes the coordinates of the floating window whenever the window gets + * reassigned to a different output (or when the output’s rect changes). + * + */ +void floating_fix_coordinates(Con *con, Rect *old_rect, Rect *new_rect); + #endif diff --git a/src/con.c b/src/con.c index c901c18d..f1b97442 100644 --- a/src/con.c +++ b/src/con.c @@ -613,20 +613,7 @@ void con_move_to_workspace(Con *con, Con *workspace, bool fix_coordinates, bool /* Take the relative coordinates of the current output, then add them * to the coordinate space of the correct output */ if (fix_coordinates && con->type == CT_FLOATING_CON) { - DLOG("Floating window, fixing coordinates\n"); - /* First we get the x/y coordinates relative to the x/y coordinates - * of the output on which the window is on */ - uint32_t rel_x = (con->rect.x - source_output->rect.x); - uint32_t rel_y = (con->rect.y - source_output->rect.y); - /* Then we calculate a fraction, for example 0.63 for a window - * which is at y = 1212 of a 1920 px high output */ - double fraction_x = ((double)rel_x / source_output->rect.width); - double fraction_y = ((double)rel_y / source_output->rect.height); - DLOG("rel_x = %d, rel_y = %d, fraction_x = %f, fraction_y = %f, output->w = %d, output->h = %d\n", - rel_x, rel_y, fraction_x, fraction_y, source_output->rect.width, source_output->rect.height); - con->rect.x = dest_output->rect.x + (fraction_x * dest_output->rect.width); - con->rect.y = dest_output->rect.y + (fraction_y * dest_output->rect.height); - DLOG("Resulting coordinates: x = %d, y = %d\n", con->rect.x, con->rect.y); + floating_fix_coordinates(con, &(source_output->rect), &(dest_output->rect)); } else DLOG("Not fixing coordinates, fix_coordinates flag = %d\n", fix_coordinates); /* If moving to a visible workspace, call show so it can be considered diff --git a/src/floating.c b/src/floating.c index 780d9138..f7dd2ebc 100644 --- a/src/floating.c +++ b/src/floating.c @@ -551,6 +551,28 @@ void floating_reposition(Con *con, Rect newrect) { tree_render(); } +/* + * Fixes the coordinates of the floating window whenever the window gets + * reassigned to a different output (or when the output’s rect changes). + * + */ +void floating_fix_coordinates(Con *con, Rect *old_rect, Rect *new_rect) { + DLOG("Fixing coordinates of floating window %p\n", con); + /* First we get the x/y coordinates relative to the x/y coordinates + * of the output on which the window is on */ + uint32_t rel_x = (con->rect.x - old_rect->x); + uint32_t rel_y = (con->rect.y - old_rect->y); + /* Then we calculate a fraction, for example 0.63 for a window + * which is at y = 1212 of a 1920 px high output */ + double fraction_x = ((double)rel_x / old_rect->width); + double fraction_y = ((double)rel_y / old_rect->height); + DLOG("rel_x = %d, rel_y = %d, fraction_x = %f, fraction_y = %f, output->w = %d, output->h = %d\n", + rel_x, rel_y, fraction_x, fraction_y, old_rect->width, old_rect->height); + con->rect.x = new_rect->x + (fraction_x * new_rect->width); + con->rect.y = new_rect->y + (fraction_y * new_rect->height); + DLOG("Resulting coordinates: x = %d, y = %d\n", con->rect.x, con->rect.y); +} + #if 0 /* * Moves the client 10px to the specified direction. diff --git a/src/randr.c b/src/randr.c index d1683e9f..bb6b4e90 100644 --- a/src/randr.c +++ b/src/randr.c @@ -2,7 +2,7 @@ * vim:ts=4:sw=4:expandtab * * i3 - an improved dynamic tiling window manager - * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE) + * © 2009-2012 Michael Stapelberg and contributors (see also: LICENSE) * * For more information on RandR, please see the X.org RandR specification at * http://cgit.freedesktop.org/xorg/proto/randrproto/tree/randrproto.txt @@ -511,8 +511,6 @@ void init_ws_for_output(Output *output, Con *content) { * */ static void output_change_mode(xcb_connection_t *conn, Output *output) { - //i3Font *font = load_font(conn, config.font); - DLOG("Output mode changed, updating rect\n"); assert(output->con != NULL); output->con->rect = output->rect; @@ -522,6 +520,14 @@ static void output_change_mode(xcb_connection_t *conn, Output *output) { /* Point content to the container of the workspaces */ content = output_get_content(output->con); + /* Fix the position of all floating windows on this output. + * The 'rect' of each workspace will be updated in src/render.c. */ + TAILQ_FOREACH(workspace, &(content->nodes_head), nodes) { + TAILQ_FOREACH(child, &(workspace->floating_head), floating_windows) { + floating_fix_coordinates(child, &(workspace->rect), &(output->con->rect)); + } + } + /* If default_orientation is NO_ORIENTATION, we change the orientation of * the workspaces and their childs depending on output resolution. This is * only done for workspaces with maximum one child. */