X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Ffloating.c;h=643f204b64110a12aede45c4bf4b6ee9e4851f86;hb=78e99440f6ff144bb6842f3fb33c1f65faadc4df;hp=761d207de39cfed6d1fed9e726082b828f4283ae;hpb=19cbd3cbeca8f043830a80a35fdcb28c971d4da5;p=i3%2Fi3 diff --git a/src/floating.c b/src/floating.c index 761d207d..643f204b 100644 --- a/src/floating.c +++ b/src/floating.c @@ -39,6 +39,35 @@ void floating_check_size(Con *floating_con) { const int floating_sane_min_height = 50; const int floating_sane_min_width = 75; Rect floating_sane_max_dimensions; + Con *focused_con = con_descend_focused(floating_con); + + /* obey size increments */ + if (focused_con->height_increment || focused_con->width_increment) { + Rect border_rect = con_border_style_rect(focused_con); + + /* We have to do the opposite calculations that render_con() do + * to get the exact size we want. */ + border_rect.width = -border_rect.width; + border_rect.width += 2 * focused_con->border_width; + border_rect.height = -border_rect.height; + border_rect.height += 2 * focused_con->border_width; + if (con_border_style(focused_con) == BS_NORMAL) + border_rect.height += render_deco_height(); + + if (focused_con->height_increment && + floating_con->rect.height >= focused_con->base_height + border_rect.height) { + floating_con->rect.height -= focused_con->base_height + border_rect.height; + floating_con->rect.height -= floating_con->rect.height % focused_con->height_increment; + floating_con->rect.height += focused_con->base_height + border_rect.height; + } + + if (focused_con->width_increment && + floating_con->rect.width >= focused_con->base_width + border_rect.width) { + floating_con->rect.width -= focused_con->base_width + border_rect.width; + floating_con->rect.width -= floating_con->rect.width % focused_con->width_increment; + floating_con->rect.width += focused_con->base_width + border_rect.width; + } + } /* Unless user requests otherwise (-1), ensure width/height do not exceed * configured maxima or, if unconfigured, limit to combined width of all @@ -165,7 +194,7 @@ void floating_enable(Con *con, bool automatic) { free(name); /* find the height for the decorations */ - int deco_height = config.font.height + 5; + int deco_height = render_deco_height(); DLOG("Original rect: (%d, %d) with %d x %d\n", con->rect.x, con->rect.y, con->rect.width, con->rect.height); DLOG("Geometry = (%d, %d) with %d x %d\n", con->geometry.x, con->geometry.y, con->geometry.width, con->geometry.height); @@ -251,7 +280,7 @@ void floating_enable(Con *con, bool automatic) { /* 5: Subtract the deco_height in order to make the floating window appear * at precisely the position it specified in its original geometry (which * is what applications might remember). */ - deco_height = (con->border_style == BS_NORMAL ? config.font.height + 5 : 0); + deco_height = (con->border_style == BS_NORMAL ? render_deco_height() : 0); nc->rect.y -= deco_height; DLOG("Corrected y = %d (deco_height = %d)\n", nc->rect.y, deco_height); @@ -286,6 +315,8 @@ void floating_disable(Con *con, bool automatic) { return; } + const bool set_focus = (con == focused); + Con *ws = con_get_workspace(con); /* 1: detach from parent container */ @@ -315,8 +346,9 @@ void floating_disable(Con *con, bool automatic) { con_attach(con, con->parent, false); con_fix_percent(con->parent); - // TODO: don’t influence focus handling when Con was not focused before. - con_focus(con); + + if (set_focus) + con_focus(con); } /* @@ -392,6 +424,8 @@ DRAGGING_CB(drag_window_callback) { /* Check if we cross workspace boundaries while moving */ if (!floating_maybe_reassign_ws(con)) return; + /* Ensure not to warp the pointer while dragging */ + x_set_warp_to(NULL); tree_render(); } @@ -409,6 +443,11 @@ void floating_drag_window(Con *con, const xcb_button_press_event_t *event) { /* Drag the window */ drag_pointer(con, event, XCB_NONE, BORDER_TOP /* irrelevant */, XCURSOR_CURSOR_MOVE, drag_window_callback, event); + + /* If this is a scratchpad window, don't auto center it from now on. */ + if (con->scratchpad_state == SCRATCHPAD_FRESH) + con->scratchpad_state = SCRATCHPAD_CHANGED; + tree_render(); } @@ -447,26 +486,27 @@ DRAGGING_CB(resize_window_callback) { dest_height = old_rect->height - (new_y - event->root_y); else dest_height = old_rect->height + (new_y - event->root_y); - /* Obey minimum window size */ - Rect minimum = con_minimum_size(con); - dest_width = max(dest_width, minimum.width); - dest_height = max(dest_height, minimum.height); - /* User wants to keep proportions, so we may have to adjust our values */ if (params->proportional) { dest_width = max(dest_width, (int) (dest_height * ratio)); dest_height = max(dest_height, (int) (dest_width / ratio)); } + con->rect = (Rect) { dest_x, dest_y, dest_width, dest_height }; + + /* Obey window size */ + floating_check_size(con); + /* If not the lower right corner is grabbed, we must also reposition * the client by exactly the amount we resized it */ if (corner & BORDER_LEFT) - dest_x = old_rect->x + (old_rect->width - dest_width); + dest_x = old_rect->x + (old_rect->width - con->rect.width); if (corner & BORDER_TOP) - dest_y = old_rect->y + (old_rect->height - dest_height); + dest_y = old_rect->y + (old_rect->height - con->rect.height); - con->rect = (Rect) { dest_x, dest_y, dest_width, dest_height }; + con->rect.x = dest_x; + con->rect.y = dest_y; /* TODO: don’t re-render the whole tree just because we change * coordinates of a floating window */ @@ -507,6 +547,10 @@ void floating_resize_window(Con *con, const bool proportional, struct resize_window_callback_params params = { corner, proportional, event }; drag_pointer(con, event, XCB_NONE, BORDER_TOP /* irrelevant */, cursor, resize_window_callback, ¶ms); + + /* If this is a scratchpad window, don't auto center it from now on. */ + if (con->scratchpad_state == SCRATCHPAD_FRESH) + con->scratchpad_state = SCRATCHPAD_CHANGED; } /* @@ -618,11 +662,7 @@ void drag_pointer(Con *con, const xcb_button_press_event_t *event, xcb_window_t void floating_reposition(Con *con, Rect newrect) { /* Sanity check: Are the new coordinates on any output? If not, we * ignore that request. */ - Output *output = get_output_containing( - newrect.x + (newrect.width / 2), - newrect.y + (newrect.height / 2)); - - if (!output) { + if (!contained_by_output(newrect)) { ELOG("No output found at destination coordinates. Not repositioning.\n"); return; } @@ -630,6 +670,11 @@ void floating_reposition(Con *con, Rect newrect) { con->rect = newrect; floating_maybe_reassign_ws(con); + + /* If this is a scratchpad window, don't auto center it from now on. */ + if (con->scratchpad_state == SCRATCHPAD_FRESH) + con->scratchpad_state = SCRATCHPAD_CHANGED; + tree_render(); }