X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Ffloating.c;h=d01cb43dfec887257d5e842e477583ba1e572513;hb=d68982761367698da43c9c90129e77c86c9ccc4f;hp=1c35c8d0e854bb3364bd47e761dd26224b36e040;hpb=2314f107784196d8fc7ee500645dbdf548f91386;p=i3%2Fi3 diff --git a/src/floating.c b/src/floating.c index 1c35c8d0..d01cb43d 100644 --- a/src/floating.c +++ b/src/floating.c @@ -198,7 +198,7 @@ void floating_enable(Con *con, bool automatic) { 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); - Rect zero = { 0, 0, 0, 0 }; + Rect zero = {0, 0, 0, 0}; nc->rect = con->geometry; /* If the geometry was not set (split containers), we need to determine a * sensible one by combining the geometry of all children */ @@ -231,7 +231,7 @@ void floating_enable(Con *con, bool automatic) { nc->rect.width -= border_style_rect.width; /* Add some more pixels for the title bar */ - if(con_border_style(con) == BS_NORMAL) + if (con_border_style(con) == BS_NORMAL) nc->rect.height += deco_height; /* Honor the X11 border */ @@ -246,19 +246,18 @@ void floating_enable(Con *con, bool automatic) { if (con->window && con->window->leader != XCB_NONE && (leader = con_by_window_id(con->window->leader)) != NULL) { DLOG("Centering above leader\n"); - nc->rect.x = leader->rect.x + (leader->rect.width / 2) - (nc->rect.width / 2); - nc->rect.y = leader->rect.y + (leader->rect.height / 2) - (nc->rect.height / 2); + floating_center(nc, leader->rect); } else { /* center the window on workspace as fallback */ - nc->rect.x = ws->rect.x + (ws->rect.width / 2) - (nc->rect.width / 2); - nc->rect.y = ws->rect.y + (ws->rect.height / 2) - (nc->rect.height / 2); + floating_center(nc, ws->rect); } } /* 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.width / 2), nc->rect.y + (nc->rect.height / 2)); + (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) { @@ -297,16 +296,21 @@ void floating_enable(Con *con, bool automatic) { /* 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)) + if (floating_maybe_reassign_ws(nc)) { + ipc_send_window_event("floating", con); return; + } /* Sanitize coordinates: Check if they are on any output */ - if (get_output_containing(nc->rect.x, nc->rect.y) != NULL) + if (get_output_containing(nc->rect.x, nc->rect.y) != NULL) { + ipc_send_window_event("floating", con); return; + } ELOG("No output found at destination coordinates, centering floating window on current ws\n"); - nc->rect.x = ws->rect.x + (ws->rect.width / 2) - (nc->rect.width / 2); - nc->rect.y = ws->rect.y + (ws->rect.height / 2) - (nc->rect.height / 2); + floating_center(nc, ws->rect); + + ipc_send_window_event("floating", con); } void floating_disable(Con *con, bool automatic) { @@ -336,7 +340,8 @@ void floating_disable(Con *con, bool automatic) { * workspace itself */ if (focused->type == CT_WORKSPACE) con->parent = focused; - else con->parent = focused->parent; + else + con->parent = focused->parent; /* con_fix_percent will adjust the percent value */ con->percent = 0.0; @@ -349,6 +354,8 @@ void floating_disable(Con *con, bool automatic) { if (set_focus) con_focus(con); + + ipc_send_window_event("floating", con); } /* @@ -410,6 +417,15 @@ bool floating_maybe_reassign_ws(Con *con) { return true; } +/* + * Centers a floating con above the specified rect. + * + */ +void floating_center(Con *con, Rect rect) { + con->rect.x = rect.x + (rect.width / 2) - (con->rect.width / 2); + con->rect.y = rect.y + (rect.height / 2) - (con->rect.height / 2); +} + DRAGGING_CB(drag_window_callback) { const struct xcb_button_press_event_t *event = extra; @@ -481,25 +497,27 @@ DRAGGING_CB(resize_window_callback) { uint32_t dest_width; uint32_t dest_height; - double ratio = (double) old_rect->width / old_rect->height; + double ratio = (double)old_rect->width / old_rect->height; /* First guess: We resize by exactly the amount the mouse moved, * taking into account in which corner the client was grabbed */ if (corner & BORDER_LEFT) dest_width = old_rect->width - (new_x - event->root_x); - else dest_width = old_rect->width + (new_x - event->root_x); + else + dest_width = old_rect->width + (new_x - event->root_x); if (corner & BORDER_TOP) dest_height = old_rect->height - (new_y - event->root_y); - else dest_height = old_rect->height + (new_y - event->root_y); + else + dest_height = old_rect->height + (new_y - event->root_y); /* 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)); + 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 }; + con->rect = (Rect){dest_x, dest_y, dest_width, dest_height}; /* Obey window size */ floating_check_size(con); @@ -537,21 +555,19 @@ void floating_resize_window(Con *con, const bool proportional, if (event->event_x <= (int16_t)(con->rect.width / 2)) corner |= BORDER_LEFT; - else corner |= BORDER_RIGHT; + else + corner |= BORDER_RIGHT; int cursor = 0; if (event->event_y <= (int16_t)(con->rect.height / 2)) { corner |= BORDER_TOP; - cursor = (corner & BORDER_LEFT) ? - XCURSOR_CURSOR_TOP_LEFT_CORNER : XCURSOR_CURSOR_TOP_RIGHT_CORNER; - } - else { + cursor = (corner & BORDER_LEFT) ? XCURSOR_CURSOR_TOP_LEFT_CORNER : XCURSOR_CURSOR_TOP_RIGHT_CORNER; + } else { corner |= BORDER_BOTTOM; - cursor = (corner & BORDER_LEFT) ? - XCURSOR_CURSOR_BOTTOM_LEFT_CORNER : XCURSOR_CURSOR_BOTTOM_RIGHT_CORNER; + cursor = (corner & BORDER_LEFT) ? XCURSOR_CURSOR_BOTTOM_LEFT_CORNER : XCURSOR_CURSOR_BOTTOM_RIGHT_CORNER; } - struct resize_window_callback_params params = { corner, proportional, event }; + struct resize_window_callback_params params = {corner, proportional, event}; /* get the initial rect in case of revert/cancel */ Rect initial_rect = con->rect; @@ -589,13 +605,13 @@ struct drag_x11_cb { }; static void xcb_drag_check_cb(EV_P_ ev_check *w, int revents) { - struct drag_x11_cb *dragloop = (struct drag_x11_cb*)w; + struct drag_x11_cb *dragloop = (struct drag_x11_cb *)w; xcb_motion_notify_event_t *last_motion_notify = NULL; xcb_generic_event_t *event; while ((event = xcb_poll_for_event(conn)) != NULL) { if (event->response_type == 0) { - xcb_generic_error_t *error = (xcb_generic_error_t*)event; + xcb_generic_error_t *error = (xcb_generic_error_t *)event; DLOG("X11 Error received (probably harmless)! sequence 0x%x, error_code = %d\n", error->sequence, error->error_code); free(event); @@ -617,7 +633,7 @@ static void xcb_drag_check_cb(EV_P_ ev_check *w, int revents) { break; case XCB_UNMAP_NOTIFY: { - xcb_unmap_notify_event_t *unmap_event = (xcb_unmap_notify_event_t*)event; + xcb_unmap_notify_event_t *unmap_event = (xcb_unmap_notify_event_t *)event; Con *con = con_by_window_id(unmap_event->window); if (con != NULL) { @@ -636,7 +652,7 @@ static void xcb_drag_check_cb(EV_P_ ev_check *w, int revents) { case XCB_MOTION_NOTIFY: /* motion_notify events are saved for later */ FREE(last_motion_notify); - last_motion_notify = (xcb_motion_notify_event_t*)event; + last_motion_notify = (xcb_motion_notify_event_t *)event; break; default: @@ -645,7 +661,7 @@ static void xcb_drag_check_cb(EV_P_ ev_check *w, int revents) { break; } - if (last_motion_notify != (xcb_motion_notify_event_t*)event) + if (last_motion_notify != (xcb_motion_notify_event_t *)event) free(event); if (dragloop->result != DRAGGING) @@ -656,15 +672,14 @@ static void xcb_drag_check_cb(EV_P_ ev_check *w, int revents) { return; dragloop->callback( - dragloop->con, - &(dragloop->old_rect), - last_motion_notify->root_x, - last_motion_notify->root_y, - dragloop->extra); + dragloop->con, + &(dragloop->old_rect), + last_motion_notify->root_x, + last_motion_notify->root_y, + dragloop->extra); free(last_motion_notify); } - /* * This function grabs your pointer and keyboard and lets you drag stuff around * (borders). Every time you move your mouse, an XCB_MOTION_NOTIFY event will @@ -674,26 +689,28 @@ static void xcb_drag_check_cb(EV_P_ ev_check *w, int revents) { * */ drag_result_t drag_pointer(Con *con, const xcb_button_press_event_t *event, xcb_window_t - confine_to, border_t border, int cursor, callback_t callback, const void *extra) -{ - xcb_cursor_t xcursor = (cursor && xcursor_supported) ? - xcursor_get_cursor(cursor) : XCB_NONE; + confine_to, + border_t border, int cursor, callback_t callback, const void *extra) { + xcb_cursor_t xcursor = (cursor && xcursor_supported) ? xcursor_get_cursor(cursor) : XCB_NONE; /* Grab the pointer */ xcb_grab_pointer_cookie_t cookie; xcb_grab_pointer_reply_t *reply; + xcb_generic_error_t *error; + cookie = xcb_grab_pointer(conn, - false, /* get all pointer events specified by the following mask */ - root, /* grab the root window */ - XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION, /* which events to let through */ - XCB_GRAB_MODE_ASYNC, /* pointer events should continue as normal */ - XCB_GRAB_MODE_ASYNC, /* keyboard mode */ - confine_to, /* confine_to = in which window should the cursor stay */ - xcursor, /* possibly display a special cursor */ - XCB_CURRENT_TIME); - - if ((reply = xcb_grab_pointer_reply(conn, cookie, NULL)) == NULL) { - ELOG("Could not grab pointer\n"); + false, /* get all pointer events specified by the following mask */ + root, /* grab the root window */ + XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION, /* which events to let through */ + XCB_GRAB_MODE_ASYNC, /* pointer events should continue as normal */ + XCB_GRAB_MODE_ASYNC, /* keyboard mode */ + confine_to, /* confine_to = in which window should the cursor stay */ + xcursor, /* possibly display a special cursor */ + XCB_CURRENT_TIME); + + if ((reply = xcb_grab_pointer_reply(conn, cookie, &error)) == NULL) { + ELOG("Could not grab pointer (error_code = %d)\n", error->error_code); + free(error); return DRAG_ABORT; } @@ -704,15 +721,17 @@ drag_result_t drag_pointer(Con *con, const xcb_button_press_event_t *event, xcb_ xcb_grab_keyboard_reply_t *keyb_reply; keyb_cookie = xcb_grab_keyboard(conn, - false, /* get all keyboard events */ - root, /* grab the root window */ - XCB_CURRENT_TIME, - XCB_GRAB_MODE_ASYNC, /* continue processing pointer events as normal */ - XCB_GRAB_MODE_ASYNC /* keyboard mode */ - ); - - if ((keyb_reply = xcb_grab_keyboard_reply(conn, keyb_cookie, NULL)) == NULL) { - ELOG("Could not grab keyboard\n"); + false, /* get all keyboard events */ + root, /* grab the root window */ + XCB_CURRENT_TIME, + XCB_GRAB_MODE_ASYNC, /* continue processing pointer events as normal */ + XCB_GRAB_MODE_ASYNC /* keyboard mode */ + ); + + if ((keyb_reply = xcb_grab_keyboard_reply(conn, keyb_cookie, &error)) == NULL) { + ELOG("Could not grab keyboard (error_code = %d)\n", error->error_code); + free(error); + xcb_ungrab_pointer(conn, XCB_CURRENT_TIME); return DRAG_ABORT; } @@ -784,18 +803,16 @@ void floating_fix_coordinates(Con *con, Rect *old_rect, Rect *new_rect) { 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)(con->rect.width / 2); + 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); + 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 - (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); + 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); }