Merge pull request #3184 from orestisf1993/issue-1341
floating_enable & floating_maybe_reassign_ws changes
This commit is contained in:
commit
83ac1c0e72
|
@ -88,6 +88,14 @@ Output *get_output_by_name(const char *name, const bool require_active);
|
||||||
*/
|
*/
|
||||||
Output *get_output_containing(unsigned int x, unsigned int y);
|
Output *get_output_containing(unsigned int x, unsigned int y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the active output which contains the midpoint of the given rect. If
|
||||||
|
* such an output doesn't exist, returns the output which contains most of the
|
||||||
|
* rectangle or NULL if there is no output which intersects with it.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Output *get_output_from_rect(Rect rect);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the active output which spans exactly the area specified by
|
* Returns the active output which spans exactly the area specified by
|
||||||
* rect or NULL if there is no output like this.
|
* rect or NULL if there is no output like this.
|
||||||
|
@ -95,15 +103,14 @@ Output *get_output_containing(unsigned int x, unsigned int y);
|
||||||
*/
|
*/
|
||||||
Output *get_output_with_dimensions(Rect rect);
|
Output *get_output_with_dimensions(Rect rect);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* In contained_by_output, we check if any active output contains part of the container.
|
* In output_containing_rect, we check if any active output contains part of the container.
|
||||||
* We do this by checking if the output rect is intersected by the Rect.
|
* We do this by checking if the output rect is intersected by the Rect.
|
||||||
* This is the 2-dimensional counterpart of get_output_containing.
|
* This is the 2-dimensional counterpart of get_output_containing.
|
||||||
* Since we don't actually need the outputs intersected by the given Rect (There could
|
* Returns the output with the maximum intersecting area.
|
||||||
* be many), we just return true or false for convenience.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
bool contained_by_output(Rect rect);
|
Output *output_containing_rect(Rect rect);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the output which is the next one in the given direction.
|
* Gets the output which is the next one in the given direction.
|
||||||
|
|
|
@ -284,10 +284,7 @@ void floating_enable(Con *con, bool automatic) {
|
||||||
|
|
||||||
/* Sanity check: Are the coordinates on the appropriate output? If not, we
|
/* Sanity check: Are the coordinates on the appropriate output? If not, we
|
||||||
* need to change them */
|
* need to change them */
|
||||||
Output *current_output = get_output_containing(nc->rect.x +
|
Output *current_output = get_output_from_rect(nc->rect);
|
||||||
(nc->rect.width / 2),
|
|
||||||
nc->rect.y + (nc->rect.height / 2));
|
|
||||||
|
|
||||||
Con *correct_output = con_get_output(ws);
|
Con *correct_output = con_get_output(ws);
|
||||||
if (!current_output || current_output->con != correct_output) {
|
if (!current_output || current_output->con != correct_output) {
|
||||||
DLOG("This floating window is on the wrong output, fixing coordinates (currently (%d, %d))\n",
|
DLOG("This floating window is on the wrong output, fixing coordinates (currently (%d, %d))\n",
|
||||||
|
@ -295,11 +292,13 @@ void floating_enable(Con *con, bool automatic) {
|
||||||
|
|
||||||
/* If moving from one output to another, keep the relative position
|
/* If moving from one output to another, keep the relative position
|
||||||
* consistent (e.g. a centered dialog will remain centered). */
|
* consistent (e.g. a centered dialog will remain centered). */
|
||||||
if (current_output)
|
if (current_output) {
|
||||||
floating_fix_coordinates(nc, ¤t_output->con->rect, &correct_output->rect);
|
floating_fix_coordinates(nc, ¤t_output->con->rect, &correct_output->rect);
|
||||||
else {
|
/* Make sure that the result is in the correct output. */
|
||||||
nc->rect.x = correct_output->rect.x;
|
current_output = get_output_from_rect(nc->rect);
|
||||||
nc->rect.y = correct_output->rect.y;
|
}
|
||||||
|
if (!current_output || current_output->con != correct_output) {
|
||||||
|
floating_center(nc, ws->rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,21 +319,6 @@ void floating_enable(Con *con, bool automatic) {
|
||||||
if (set_focus)
|
if (set_focus)
|
||||||
con_activate(con);
|
con_activate(con);
|
||||||
|
|
||||||
/* Check if we need to re-assign it to a different workspace because of its
|
|
||||||
* coordinates and exit if that was done successfully. */
|
|
||||||
if (floating_maybe_reassign_ws(nc)) {
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sanitize coordinates: Check if they are on any output */
|
|
||||||
if (get_output_containing(nc->rect.x, nc->rect.y) != NULL) {
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
ELOG("No output found at destination coordinates, centering floating window on current ws\n");
|
|
||||||
floating_center(nc, ws->rect);
|
|
||||||
|
|
||||||
done:
|
|
||||||
floating_set_hint_atom(nc, true);
|
floating_set_hint_atom(nc, true);
|
||||||
ipc_send_window_event("floating", con);
|
ipc_send_window_event("floating", con);
|
||||||
}
|
}
|
||||||
|
@ -429,9 +413,7 @@ void floating_raise_con(Con *con) {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
bool floating_maybe_reassign_ws(Con *con) {
|
bool floating_maybe_reassign_ws(Con *con) {
|
||||||
Output *output = get_output_containing(
|
Output *output = get_output_from_rect(con->rect);
|
||||||
con->rect.x + (con->rect.width / 2),
|
|
||||||
con->rect.y + (con->rect.height / 2));
|
|
||||||
|
|
||||||
if (!output) {
|
if (!output) {
|
||||||
ELOG("No output found at destination coordinates?\n");
|
ELOG("No output found at destination coordinates?\n");
|
||||||
|
@ -867,7 +849,7 @@ drag_result_t drag_pointer(Con *con, const xcb_button_press_event_t *event, xcb_
|
||||||
bool floating_reposition(Con *con, Rect newrect) {
|
bool floating_reposition(Con *con, Rect newrect) {
|
||||||
/* Sanity check: Are the new coordinates on any output? If not, we
|
/* Sanity check: Are the new coordinates on any output? If not, we
|
||||||
* ignore that request. */
|
* ignore that request. */
|
||||||
if (!contained_by_output(newrect)) {
|
if (!output_containing_rect(newrect)) {
|
||||||
ELOG("No output found at destination coordinates. Not repositioning.\n");
|
ELOG("No output found at destination coordinates. Not repositioning.\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
40
src/randr.c
40
src/randr.c
|
@ -114,6 +114,20 @@ Output *get_output_containing(unsigned int x, unsigned int y) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the active output which contains the midpoint of the given rect. If
|
||||||
|
* such an output doesn't exist, returns the output which contains most of the
|
||||||
|
* rectangle or NULL if there is no output which intersects with it.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Output *get_output_from_rect(Rect rect) {
|
||||||
|
unsigned int mid_x = rect.x + rect.width / 2;
|
||||||
|
unsigned int mid_y = rect.y + rect.height / 2;
|
||||||
|
Output *output = get_output_containing(mid_x, mid_y);
|
||||||
|
|
||||||
|
return output ? output : output_containing_rect(rect);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the active output which spans exactly the area specified by
|
* Returns the active output which spans exactly the area specified by
|
||||||
* rect or NULL if there is no output like this.
|
* rect or NULL if there is no output like this.
|
||||||
|
@ -136,27 +150,37 @@ Output *get_output_with_dimensions(Rect rect) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In contained_by_output, we check if any active output contains part of the container.
|
* In output_containing_rect, we check if any active output contains part of the container.
|
||||||
* We do this by checking if the output rect is intersected by the Rect.
|
* We do this by checking if the output rect is intersected by the Rect.
|
||||||
* This is the 2-dimensional counterpart of get_output_containing.
|
* This is the 2-dimensional counterpart of get_output_containing.
|
||||||
* Since we don't actually need the outputs intersected by the given Rect (There could
|
* Returns the output with the maximum intersecting area.
|
||||||
* be many), we just return true or false for convenience.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
bool contained_by_output(Rect rect) {
|
Output *output_containing_rect(Rect rect) {
|
||||||
Output *output;
|
Output *output;
|
||||||
int lx = rect.x, uy = rect.y;
|
int lx = rect.x, uy = rect.y;
|
||||||
int rx = rect.x + rect.width, by = rect.y + rect.height;
|
int rx = rect.x + rect.width, by = rect.y + rect.height;
|
||||||
|
long max_area = 0;
|
||||||
|
Output *result = NULL;
|
||||||
TAILQ_FOREACH(output, &outputs, outputs) {
|
TAILQ_FOREACH(output, &outputs, outputs) {
|
||||||
if (!output->active)
|
if (!output->active)
|
||||||
continue;
|
continue;
|
||||||
|
int lx_o = (int)output->rect.x, uy_o = (int)output->rect.y;
|
||||||
|
int rx_o = (int)(output->rect.x + output->rect.width), by_o = (int)(output->rect.y + output->rect.height);
|
||||||
DLOG("comparing x=%d y=%d with x=%d and y=%d width %d height %d\n",
|
DLOG("comparing x=%d y=%d with x=%d and y=%d width %d height %d\n",
|
||||||
rect.x, rect.y, output->rect.x, output->rect.y, output->rect.width, output->rect.height);
|
rect.x, rect.y, output->rect.x, output->rect.y, output->rect.width, output->rect.height);
|
||||||
if (rx >= (int)output->rect.x && lx <= (int)(output->rect.x + output->rect.width) &&
|
int left = max(lx, lx_o);
|
||||||
by >= (int)output->rect.y && uy <= (int)(output->rect.y + output->rect.height))
|
int right = min(rx, rx_o);
|
||||||
return true;
|
int bottom = min(by, by_o);
|
||||||
|
int top = max(uy, uy_o);
|
||||||
|
if (left < right && bottom > top) {
|
||||||
|
long area = (right - left) * (bottom - top);
|
||||||
|
if (area > max_area) {
|
||||||
|
result = output;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue