return outputs_dimensions;
}
+/**
+ * Called when a floating window is created or resized.
+ * This function resizes the window if its size is higher or lower than the
+ * configured maximum/minimum size, respectively.
+ *
+ */
+void floating_check_size(Con *floating_con) {
+ /* Define reasonable minimal and maximal sizes for floating windows */
+ const int floating_sane_min_height = 50;
+ const int floating_sane_min_width = 75;
+ Rect floating_sane_max_dimensions;
+
+ /* Unless user requests otherwise (-1), ensure width/height do not exceed
+ * configured maxima or, if unconfigured, limit to combined width of all
+ * outputs */
+ if (config.floating_minimum_height != -1) {
+ if (config.floating_minimum_height == 0)
+ floating_con->rect.height = max(floating_con->rect.height, floating_sane_min_height);
+ else
+ floating_con->rect.height = max(floating_con->rect.height, config.floating_minimum_height);
+ }
+ if (config.floating_minimum_width != -1) {
+ if (config.floating_minimum_width == 0)
+ floating_con->rect.width = max(floating_con->rect.width, floating_sane_min_width);
+ else
+ floating_con->rect.width = max(floating_con->rect.width, config.floating_minimum_width);
+ }
+
+ /* Unless user requests otherwise (-1), raise the width/height to
+ * reasonable minimum dimensions */
+ floating_sane_max_dimensions = total_outputs_dimensions();
+ if (config.floating_maximum_height != -1) {
+ if (config.floating_maximum_height == 0)
+ floating_con->rect.height = min(floating_con->rect.height, floating_sane_max_dimensions.height);
+ else
+ floating_con->rect.height = min(floating_con->rect.height, config.floating_maximum_height);
+ }
+ if (config.floating_maximum_width != -1) {
+ if (config.floating_maximum_width == 0)
+ floating_con->rect.width = min(floating_con->rect.width, floating_sane_max_dimensions.width);
+ else
+ floating_con->rect.width = min(floating_con->rect.width, config.floating_maximum_width);
+ }
+}
+
void floating_enable(Con *con, bool automatic) {
bool set_focus = (con == focused);
* otherwise. */
Con *ws = con_get_workspace(con);
nc->parent = ws;
- nc->split = true;
nc->type = CT_FLOATING_CON;
nc->layout = L_SPLITH;
/* We insert nc already, even though its rect is not yet calculated. This
}
}
- /* Define reasonable minimal and maximal sizes for floating windows */
- const int floating_sane_min_height = 50;
- const int floating_sane_min_width = 75;
-
- Rect floating_sane_max_dimensions;
- floating_sane_max_dimensions = total_outputs_dimensions();
-
- /* Unless user requests otherwise (-1), ensure width/height do not exceed
- * configured maxima or, if unconfigured, limit to combined width of all
- * outputs */
- if (config.floating_maximum_height != -1) {
- if (config.floating_maximum_height == 0)
- nc->rect.height = min(nc->rect.height, floating_sane_max_dimensions.height);
- else
- nc->rect.height = min(nc->rect.height, config.floating_maximum_height);
- }
- if (config.floating_maximum_width != -1) {
- if (config.floating_maximum_width == 0)
- nc->rect.width = min(nc->rect.width, floating_sane_max_dimensions.width);
- else
- nc->rect.width = min(nc->rect.width, config.floating_maximum_width);
- }
-
- /* Unless user requests otherwise (-1), raise the width/height to
- * reasonable minimum dimensions */
- if (config.floating_minimum_height != -1) {
- if (config.floating_minimum_height == 0)
- nc->rect.height = max(nc->rect.height, floating_sane_min_height);
- else
- nc->rect.height = max(nc->rect.height, config.floating_minimum_height);
- }
- if (config.floating_minimum_width != -1) {
- if (config.floating_minimum_width == 0)
- nc->rect.width = max(nc->rect.width, floating_sane_min_width);
- else
- nc->rect.width = max(nc->rect.width, config.floating_minimum_width);
- }
+ floating_check_size(nc);
/* 3: attach the child to the new parent container. We need to do this
* because con_border_style_rect() needs to access con->parent. */
/* Sanity check: Are the coordinates on the appropriate output? If not, we
* need to change them */
- Output *current_output = get_output_containing(nc->rect.x, nc->rect.y);
+ Output *current_output = get_output_containing(nc->rect.x +
+ (nc->rect.width / 2), nc->rect.y + (nc->rect.height / 2));
+
Con *correct_output = con_get_output(ws);
if (!current_output || current_output->con != correct_output) {
DLOG("This floating window is on the wrong output, fixing coordinates (currently (%d, %d))\n",
nc->rect.x, nc->rect.y);
- /* Take the relative coordinates of the current output, then add them
- * to the coordinate space of the correct output */
- uint32_t rel_x = (nc->rect.x - (current_output ? current_output->con->rect.x : 0));
- uint32_t rel_y = (nc->rect.y - (current_output ? current_output->con->rect.y : 0));
- nc->rect.x = correct_output->rect.x + rel_x;
- nc->rect.y = correct_output->rect.y + rel_y;
+
+ /* If moving from one output to another, keep the relative position
+ * consistent (e.g. a centered dialog will remain centered). */
+ if (current_output)
+ floating_fix_coordinates(nc, ¤t_output->con->rect, &correct_output->rect);
+ else {
+ nc->rect.x = correct_output->rect.x;
+ nc->rect.y = correct_output->rect.y;
+ }
}
DLOG("Floating rect: (%d, %d) with %d x %d\n", nc->rect.x, nc->rect.y, nc->rect.width, nc->rect.height);
free(inside_event);
} while ((inside_event = xcb_poll_for_event(conn)) != NULL);
- if (last_motion_notify == NULL)
+ if (last_motion_notify == NULL || loop_done)
continue;
new_x = ((xcb_motion_notify_event_t*)last_motion_notify)->root_x;
new_rect->x, new_rect->y, new_rect->width, new_rect->height);
/* First we get the x/y coordinates relative to the x/y coordinates
* of the output on which the window is on */
- int32_t rel_x = (con->rect.x - old_rect->x);
- int32_t rel_y = (con->rect.y - old_rect->y);
+ int32_t rel_x = con->rect.x - old_rect->x + (int32_t)(con->rect.width / 2);
+ int32_t rel_y = con->rect.y - old_rect->y + (int32_t)(con->rect.height / 2);
/* Then we calculate a fraction, for example 0.63 for a window
* which is at y = 1212 of a 1920 px high output */
DLOG("rel_x = %d, rel_y = %d, fraction_x = %f, fraction_y = %f, output->w = %d, output->h = %d\n",
rel_x, rel_y, (double)rel_x / old_rect->width, (double)rel_y / old_rect->height,
old_rect->width, old_rect->height);
/* Here we have to multiply at first. Or we will lose precision when not compiled with -msse2 */
- con->rect.x = (int32_t)new_rect->x + (double)(rel_x * (int32_t)new_rect->width) / (int32_t)old_rect->width;
- con->rect.y = (int32_t)new_rect->y + (double)(rel_y * (int32_t)new_rect->height) / (int32_t)old_rect->height;
+ con->rect.x = (int32_t)new_rect->x + (double)(rel_x * (int32_t)new_rect->width)
+ / (int32_t)old_rect->width - (int32_t)(con->rect.width / 2);
+ con->rect.y = (int32_t)new_rect->y + (double)(rel_y * (int32_t)new_rect->height)
+ / (int32_t)old_rect->height - (int32_t)(con->rect.height / 2);
DLOG("Resulting coordinates: x = %d, y = %d\n", con->rect.x, con->rect.y);
}