i3-nagbar: add possibility to open bar on focused monitor
Closes #3692 i3-nagbar will open by default on the monitor with input focus and using the flag -p on the primary monitor.
This commit is contained in:
parent
37ebd2a179
commit
b6690045ed
@ -11,7 +11,8 @@ strongly encouraged to upgrade.
|
||||
│ Changes in i3 v4.20 │
|
||||
└────────────────────────────┘
|
||||
|
||||
• placeholder
|
||||
• i3-nagbar: position on focused monitor by default
|
||||
• i3-nagbar: add option to position on primary monitor
|
||||
|
||||
┌────────────────────────────┐
|
||||
│ Bugfixes │
|
||||
|
@ -266,13 +266,9 @@ static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the position and size the i3-nagbar window should use.
|
||||
* This will be the primary output or a fallback if it cannot be determined.
|
||||
* Tries to position the rectangle on the primary output.
|
||||
*/
|
||||
static xcb_rectangle_t get_window_position(void) {
|
||||
/* Default values if we cannot determine the primary output or its CRTC info. */
|
||||
xcb_rectangle_t result = (xcb_rectangle_t){50, 50, 500, font.height + 2 * MSG_PADDING + BAR_BORDER};
|
||||
|
||||
static void set_window_position_primary(xcb_rectangle_t *result) {
|
||||
xcb_randr_get_screen_resources_current_cookie_t rcookie = xcb_randr_get_screen_resources_current(conn, root);
|
||||
xcb_randr_get_output_primary_cookie_t pcookie = xcb_randr_get_output_primary(conn, root);
|
||||
|
||||
@ -314,14 +310,61 @@ static xcb_rectangle_t get_window_position(void) {
|
||||
goto free_resources;
|
||||
}
|
||||
|
||||
result.x = crtc->x;
|
||||
result.y = crtc->y;
|
||||
result->x = crtc->x;
|
||||
result->y = crtc->y;
|
||||
goto free_resources;
|
||||
|
||||
free_resources:
|
||||
free(res);
|
||||
free(primary);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to position the rectangle on the output with input focus.
|
||||
* If unsuccessful, try to position on primary output.
|
||||
*/
|
||||
static void set_window_position_focus(xcb_rectangle_t *result) {
|
||||
bool success = false;
|
||||
xcb_get_input_focus_reply_t *input_focus = NULL;
|
||||
xcb_get_geometry_reply_t *geometry = NULL;
|
||||
xcb_translate_coordinates_reply_t *coordinates = NULL;
|
||||
|
||||
/* To avoid the input window disappearing while determining its position */
|
||||
xcb_grab_server(conn);
|
||||
|
||||
input_focus = xcb_get_input_focus_reply(conn, xcb_get_input_focus(conn), NULL);
|
||||
if (input_focus == NULL || input_focus->focus == XCB_NONE) {
|
||||
LOG("Failed to receive the current input focus or no window has the input focus right now.\n");
|
||||
goto free_resources;
|
||||
}
|
||||
|
||||
geometry = xcb_get_geometry_reply(conn, xcb_get_geometry(conn, input_focus->focus), NULL);
|
||||
if (geometry == NULL) {
|
||||
LOG("Failed to received window geometry.\n");
|
||||
goto free_resources;
|
||||
}
|
||||
|
||||
coordinates = xcb_translate_coordinates_reply(
|
||||
conn, xcb_translate_coordinates(conn, input_focus->focus, root, geometry->x, geometry->y), NULL);
|
||||
if (coordinates == NULL) {
|
||||
LOG("Failed to translate coordinates.\n");
|
||||
goto free_resources;
|
||||
}
|
||||
|
||||
LOG("Found current focus at x = %i / y = %i.\n", coordinates->dst_x, coordinates->dst_y);
|
||||
result->x = coordinates->dst_x;
|
||||
result->y = coordinates->dst_y;
|
||||
success = true;
|
||||
|
||||
free_resources:
|
||||
xcb_ungrab_server(conn);
|
||||
free(input_focus);
|
||||
free(coordinates);
|
||||
free(geometry);
|
||||
if (!success) {
|
||||
LOG("Could not position on focused output, trying to position on primary output.\n");
|
||||
set_window_position_primary(result);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
@ -360,6 +403,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
argv0 = argv[0];
|
||||
|
||||
bool position_on_primary = false;
|
||||
char *pattern = sstrdup("pango:monospace 8");
|
||||
int o, option_index = 0;
|
||||
enum { TYPE_ERROR = 0,
|
||||
@ -373,9 +417,10 @@ int main(int argc, char *argv[]) {
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"message", required_argument, 0, 'm'},
|
||||
{"type", required_argument, 0, 't'},
|
||||
{"primary", no_argument, 0, 'p'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
char *options_string = "b:B:f:m:t:vh";
|
||||
char *options_string = "b:B:f:m:t:vhp";
|
||||
|
||||
prompt = i3string_from_utf8("Please do not run this program.");
|
||||
|
||||
@ -399,8 +444,11 @@ int main(int argc, char *argv[]) {
|
||||
case 'h':
|
||||
free(pattern);
|
||||
printf("i3-nagbar " I3_VERSION "\n");
|
||||
printf("i3-nagbar [-m <message>] [-b <button> <action>] [-B <button> <action>] [-t warning|error] [-f <font>] [-v]\n");
|
||||
printf("i3-nagbar [-m <message>] [-b <button> <action>] [-B <button> <action>] [-t warning|error] [-f <font>] [-v] [-p]\n");
|
||||
return 0;
|
||||
case 'p':
|
||||
position_on_primary = true;
|
||||
break;
|
||||
case 'b':
|
||||
case 'B':
|
||||
buttons = srealloc(buttons, sizeof(button_t) * (buttoncnt + 1));
|
||||
@ -464,7 +512,13 @@ int main(int argc, char *argv[]) {
|
||||
err(EXIT_FAILURE, "pledge");
|
||||
#endif
|
||||
|
||||
xcb_rectangle_t win_pos = get_window_position();
|
||||
/* Default values if we cannot determine the preferred window position. */
|
||||
xcb_rectangle_t win_pos = (xcb_rectangle_t){50, 50, 500, font.height + 2 * MSG_PADDING + BAR_BORDER};
|
||||
if (position_on_primary) {
|
||||
set_window_position_primary(&win_pos);
|
||||
} else {
|
||||
set_window_position_focus(&win_pos);
|
||||
}
|
||||
|
||||
xcb_cursor_context_t *cursor_ctx;
|
||||
if (xcb_cursor_context_new(conn, root_screen, &cursor_ctx) < 0) {
|
||||
|
@ -9,7 +9,7 @@ i3-nagbar - displays an error bar on top of your screen
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
i3-nagbar [-m <message>] [-b <button> <action>] [-B <button> <action>] [-t warning|error] [-f <font>] [-v]
|
||||
i3-nagbar [-m <message>] [-b <button> <action>] [-B <button> <action>] [-t warning|error] [-f <font>] [-v] [-p]
|
||||
|
||||
== OPTIONS
|
||||
|
||||
@ -39,6 +39,10 @@ i3-sensible-terminal.
|
||||
Same as above, but will execute the shell commands directly, without launching a
|
||||
terminal emulator.
|
||||
|
||||
*-p, --primary*::
|
||||
Always opens the i3-nagbar on the primary monitor. By default it opens on the
|
||||
focused monitor.
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
i3-nagbar is used by i3 to tell you about errors in your configuration file
|
||||
|
Loading…
x
Reference in New Issue
Block a user