diff options
author | Dave Davenport <qball@gmpclient.org> | 2018-03-07 21:24:37 +0100 |
---|---|---|
committer | Dave Davenport <qball@gmpclient.org> | 2018-03-07 21:24:37 +0100 |
commit | 7f83fa3dd3f8bd1af96faca3fcd7137ca55f7bb3 (patch) | |
tree | a893e1b4eea604493b1ba5f530e3c86be3651a30 | |
parent | 6efd73ff92239de8ed1f0b0ac2e34624d8fc9fa4 (diff) | |
parent | d9d3724615d393d82da3f0913eb06447771fb171 (diff) |
Merge branch 'next' of github:DaveDavenport/rofi into next
39 files changed, 1270 insertions, 1222 deletions
@@ -1,4 +1,4 @@ -v1.5.0 (dev): +v1.5.0: - [Theme] Accept integer notation for double properties. (#752) - [View] Theme textboxes are vertically sized and horizontal wrapped. (#754) - Rofi 1.4.2 doesn't capture ←, ↑, →, ↓ binding to keys to work in combination with Mode_switch (#744) diff --git a/Examples/test_script_mode.sh b/Examples/test_script_mode.sh index 61e29141..a58ef83e 100755 --- a/Examples/test_script_mode.sh +++ b/Examples/test_script_mode.sh @@ -1,17 +1,28 @@ #!/usr/bin/env bash -echo -en "\x00prompt\x1ftesting\n" -echo -en "\0urgent\x1f0,2\n" -echo -en "\0active\x1f1\n" -echo -en "\0markup-rows\x1ftrue\n" -echo -en "\0message\x1fSpecial <b>bold</b>message\n" +if [ x"$@" = x"quit" ] +then + exit 0 +fi -echo "aap" -echo "noot" -echo "mies" -echo "testing" -echo "<b>Bold</b>" -if [ -n "$@" ] +if [ "$@" ] then - echo "$@" + for a in {1..10} + do + echo "$a" + done + echo "quit" +else + echo -en "\x00prompt\x1ftesting\n" + echo -en "\0urgent\x1f0,2\n" + echo -en "\0active\x1f1\n" + echo -en "\0markup-rows\x1ftrue\n" + echo -en "\0message\x1fSpecial <b>bold</b>message\n" + + echo "aap" + echo "noot" + echo "mies" + echo "testing" + echo "<b>Bold</b>" + echo "quit" fi @@ -191,7 +191,9 @@ apt install rofi **Please note that the latest version of rofi in Ubuntu 16.04 is extremely outdated (v0.15.11)** -This will cause issues with newer scripts (i.e. with clerk) and we recommend to manually download and install the deb file for zesty instead. You can find the deb on [ubuntu's launchpad page for rofi](https://launchpad.net/ubuntu/+source/rofi). +This will cause issues with newer scripts (i.e. with clerk) and misses important updates and bug-fixes. +Newer versions of Rofi however requires versions of xcb-util-xrm and libxkbcommon that are not available in the 16.04 repositories. +These need to be manually installed before rofi can be installed either via source code or Zesty version from the [ubuntu's launchpad page for rofi](https://launchpad.net/ubuntu/+source/rofi). ### Fedora diff --git a/Makefile.am b/Makefile.am index efa65c4b..ab22637b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -195,6 +195,7 @@ themedir=$(pkgdatadir)/themes/ theme_DATA=\ themes/Adapta-Nokto.rasi\ themes/Arc.rasi\ + themes/Arc-Dark.rasi\ themes/DarkBlue.rasi\ themes/Pop-Dark.rasi\ themes/Indego.rasi\ @@ -206,6 +207,7 @@ theme_DATA=\ themes/c64.rasi\ themes/dmenu.rasi\ themes/glue_pro_blue.rasi\ + themes/gruvbox-common.rasi\ themes/gruvbox-dark-hard.rasi\ themes/gruvbox-dark-soft.rasi\ themes/gruvbox-dark.rasi\ @@ -202,7 +202,7 @@ For the full list of key bindings, see: `rofi -show keys` or `rofi -help`. There are currently three methods of setting configuration options: - * Local configuration. Normally, depending on XDG, in `~/.local/rofi/config`. This uses the Xresources format. + * Local configuration. Normally, depending on XDG, in `~/.config/rofi/config`. This uses the Xresources format. * Xresources: A method of storing key values in the Xserver. See [here](https://en.wikipedia.org/wiki/X_resources) for more information. * Command line options: Arguments are passed to **Rofi**. diff --git a/configure.ac b/configure.ac index 9357964e..f71dafc7 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([rofi], [1.4.99-dev], [https://github.com/DaveDavenport/rofi/],[],[https://reddit.com/r/qtools/]) +AC_INIT([rofi], [1.5.0-dev], [https://github.com/DaveDavenport/rofi/],[],[https://reddit.com/r/qtools/]) AC_CONFIG_SRCDIR([source/rofi.c]) AC_CONFIG_HEADER([config.h]) diff --git a/doc/rofi-theme.5 b/doc/rofi-theme.5 index c4ea5408..0f8a34b2 100644 --- a/doc/rofi-theme.5 +++ b/doc/rofi-theme.5 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "ROFI\-THEME" "5" "December 2017" "" "" +.TH "ROFI\-THEME" "5" "February 2018" "" "" . .SH "NAME" \fBrofi\-theme\fR \- Rofi theme format files @@ -118,7 +118,7 @@ It is advised to define the \fIglobal properties section\fR on top of the file t .IP "" 0 . .P -If there are mulitple sections with the same name, they are merged\. Duplicate properties are overwritten and the last parsed entry kept\. +If there are multiple sections with the same name, they are merged\. Duplicate properties are overwritten and the last parsed entry kept\. . .SH "Global properties section" A theme can have one or more global properties sections\. If there is more than one, they will be merged\. @@ -169,7 +169,7 @@ element normal normal, button { .IP "" 0 . .P -Each section inherits the global properties\. Properties can be explicitely inherited from there parent with the \fBinherit\fR keyword\. In the following example: +Each section inherits the global properties\. Properties can be explicitly inherited from their parent with the \fBinherit\fR keyword\. In the following example: . .IP "" 4 . @@ -221,7 +221,7 @@ The properties in a section consist of: .IP "" 0 . .P -Both fields are manditory for a property\. +Both fields are mandatory for a property\. . .P The \fBidentifier\fR names the specified property\. Identifiers can consist of any combination of numbers, letters and \'\-\'\. It must not contain any whitespace\. The structure of the \fBvalue\fR defines the type of the property\. The current parser does not define or enforce a certain type of a particular \fBidentifier\fR\. When used, values with the wrong type that cannot be converted are ignored\. @@ -419,7 +419,7 @@ The white\-space format proposed in CSS4 is also supported\. The different values are: . .IP "\(bu" 4 -\fB{HEX}\fR is a hexidecimal number (\'0\-9a\-f\' case insensitive)\. +\fB{HEX}\fR is a hexadecimal number (\'0\-9a\-f\' case insensitive)\. . .IP "\(bu" 4 \fB{INTEGER}\fR value can be between 0 and 255 or 0\-100 when representing percentage\. @@ -888,7 +888,7 @@ nametotextbox selected\.active { .IP "" 0 . .P -Sets all selected textboxes marked active to the given foreground and background color\. Note that a state modifies the original element, it therefor contains all the properties of that element\. +Sets all selected textboxes marked active to the given foreground and background color\. Note that a state modifies the original element, it therefore contains all the properties of that element\. . .SS "Scrollbar" The scrollbar uses the \fBhandle\fR state when drawing the small scrollbar handle\. This allows the colors used for drawing the handle to be set independently\. @@ -1073,7 +1073,7 @@ The current layout of \fBrofi\fR is structured as follows: | | |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| | | | | | | | |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| | | -| | | sidebar {BOX:horizontal} | | | +| | | sidebar {BOX:horizontal} | | | | | | |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| | | | | | | | Button | | Button | | Button | | Button | | | | | | | |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| | | | diff --git a/doc/rofi-theme.5.markdown b/doc/rofi-theme.5.markdown index 6bcc28c5..655f640e 100644 --- a/doc/rofi-theme.5.markdown +++ b/doc/rofi-theme.5.markdown @@ -87,7 +87,7 @@ make inheritance of properties clearer. } ``` -If there are mulitple sections with the same name, they are merged. Duplicate properties are overwritten and the last +If there are multiple sections with the same name, they are merged. Duplicate properties are overwritten and the last parsed entry kept. ## Global properties section @@ -129,7 +129,7 @@ element normal normal, button { } ``` -Each section inherits the global properties. Properties can be explicitely inherited from there parent with the +Each section inherits the global properties. Properties can be explicitly inherited from their parent with the `inherit` keyword. In the following example: @@ -165,7 +165,7 @@ The properties in a section consist of: {identifier}: {value}; ``` -Both fields are manditory for a property. +Both fields are mandatory for a property. The `identifier` names the specified property. Identifiers can consist of any combination of numbers, letters and '-'. It must not contain any whitespace. @@ -265,7 +265,7 @@ The white-space format proposed in CSS4 is also supported. The different values are: - * `{HEX}` is a hexidecimal number ('0-9a-f' case insensitive). + * `{HEX}` is a hexadecimal number ('0-9a-f' case insensitive). * `{INTEGER}` value can be between 0 and 255 or 0-100 when representing percentage. * `{ANGLE}` is the angle on the color wheel, can be in `deg`, `rad`, `grad` or `turn`. When no unit is specified, degrees is assumed. * `{PERCENTAGE}` can be between 0-1.0, or 0%-100% @@ -549,7 +549,7 @@ nametotextbox selected.active { ``` Sets all selected textboxes marked active to the given foreground and background color. -Note that a state modifies the original element, it therefor contains all the properties of that element. +Note that a state modifies the original element, it therefore contains all the properties of that element. ### Scrollbar @@ -686,7 +686,7 @@ The current layout of **rofi** is structured as follows: | | |-----------------------------------------------------------------------------| | | | | | | | |---------------------------------------------------------------------------| | | -| | | sidebar {BOX:horizontal} | | | +| | | sidebar {BOX:horizontal} | | | | | | |---------------| |---------------| |--------------| |---------------| | | | | | | | Button | | Button | | Button | | Button | | | | | | | |---------------| |---------------| |--------------| |---------------| | | | diff --git a/meson.build b/meson.build index b98f5c2a..c5cfbe53 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('rofi', 'c', - version: '1.4.99-dev', + version: '1.5.0-dev', meson_version: '>=0.39.1', license: [ 'MIT' ], default_options: [ @@ -218,6 +218,7 @@ install_man( install_data( 'themes/Adapta-Nokto.rasi', 'themes/Arc.rasi', + 'themes/Arc-Dark.rasi', 'themes/DarkBlue.rasi', 'themes/Pop-Dark.rasi', 'themes/Indego.rasi', @@ -229,6 +230,7 @@ install_data( 'themes/c64.rasi', 'themes/dmenu.rasi', 'themes/glue_pro_blue.rasi', + 'themes/gruvbox-common.rasi', 'themes/gruvbox-dark-hard.rasi', 'themes/gruvbox-dark-soft.rasi', 'themes/gruvbox-dark.rasi', diff --git a/source/dialogs/script.c b/source/dialogs/script.c index 9daf1354..4f53ee3e 100644 --- a/source/dialogs/script.c +++ b/source/dialogs/script.c @@ -78,7 +78,7 @@ static void parse_header_entry ( Mode *sw, char *line, ssize_t length ) char *value = line + length_key + 1; if ( strcasecmp ( line, "message" ) == 0 ) { g_free ( pd->message ); - pd->message = g_strdup ( value ); + pd->message = strlen(value)? g_strdup ( value ):NULL; } else if ( strcasecmp ( line, "prompt" ) == 0 ) { g_free ( pd->prompt ); @@ -187,6 +187,19 @@ static unsigned int script_mode_get_num_entries ( const Mode *sw ) return rmpd->cmd_list_length; } +static void script_mode_reset_highlight ( Mode *sw ) +{ + ScriptModePrivateData *rmpd = (ScriptModePrivateData *) sw->private_data; + + rmpd->num_urgent_list = 0; + g_free ( rmpd->urgent_list ); + rmpd->urgent_list = NULL; + rmpd->num_active_list = 0; + g_free ( rmpd->active_list ); + rmpd->active_list = NULL; + +} + static ModeMode script_mode_result ( Mode *sw, int mretv, char **input, unsigned int selected_line ) { ScriptModePrivateData *rmpd = (ScriptModePrivateData *) sw->private_data; @@ -204,9 +217,11 @@ static ModeMode script_mode_result ( Mode *sw, int mretv, char **input, unsigned retv = ( mretv & MENU_LOWER_MASK ); } else if ( ( mretv & MENU_OK ) && rmpd->cmd_list[selected_line] != NULL ) { + script_mode_reset_highlight ( sw ); new_list = execute_executor ( sw, rmpd->cmd_list[selected_line], &new_length ); } else if ( ( mretv & MENU_CUSTOM_INPUT ) && *input != NULL && *input[0] != '\0' ) { + script_mode_reset_highlight ( sw ); new_list = execute_executor ( sw, *input, &new_length ); } diff --git a/source/dialogs/ssh.c b/source/dialogs/ssh.c index 8b20ccb8..4f9bb46f 100644 --- a/source/dialogs/ssh.c +++ b/source/dialogs/ssh.c @@ -433,6 +433,20 @@ static unsigned int ssh_mode_get_num_entries ( const Mode *sw ) const SSHModePrivateData *rmpd = (const SSHModePrivateData *) mode_get_private_data ( sw ); return rmpd->hosts_list_length; } +/** + * @param sw Object handle to the SSH Mode object + * + * Cleanup the SSH Mode. Free all allocated memory and NULL the private data pointer. + */ +static void ssh_mode_destroy ( Mode *sw ) +{ + SSHModePrivateData *rmpd = (SSHModePrivateData *) mode_get_private_data ( sw ); + if ( rmpd != NULL ) { + g_strfreev ( rmpd->hosts_list ); + g_free ( rmpd ); + mode_set_private_data ( sw, NULL ); + } +} /** * @param sw Object handle to the SSH Mode object @@ -465,29 +479,14 @@ static ModeMode ssh_mode_result ( Mode *sw, int mretv, char **input, unsigned in } else if ( ( mretv & MENU_ENTRY_DELETE ) && rmpd->hosts_list[selected_line] ) { delete_ssh ( rmpd->hosts_list[selected_line] ); - g_strfreev ( rmpd->hosts_list ); - rmpd->hosts_list_length = 0; - rmpd->hosts_list = NULL; // Stay retv = RELOAD_DIALOG; + ssh_mode_destroy ( sw ); + ssh_mode_init ( sw ); } return retv; } -/** - * @param sw Object handle to the SSH Mode object - * - * Cleanup the SSH Mode. Free all allocated memory and NULL the private data pointer. - */ -static void ssh_mode_destroy ( Mode *sw ) -{ - SSHModePrivateData *rmpd = (SSHModePrivateData *) mode_get_private_data ( sw ); - if ( rmpd != NULL ) { - g_strfreev ( rmpd->hosts_list ); - g_free ( rmpd ); - mode_set_private_data ( sw, NULL ); - } -} /** * @param sw Object handle to the SSH Mode object diff --git a/source/xcb.c b/source/xcb.c index 72a30152..2d8069c9 100644 --- a/source/xcb.c +++ b/source/xcb.c @@ -62,6 +62,11 @@ #include "timings.h" #include <rofi.h> + +/** Minimal randr prefered for running rofi (1.5) */ +#define RANDR_PREF_MAJOR_VERSION 1 +#define RANDR_PREF_MINOR_VERSION 5 + /** Checks if the if x and y is inside rectangle. */ #define INTERSECT( x, y, x1, y1, w1, h1 ) ( ( ( ( x ) >= ( x1 ) ) && ( ( x ) < ( x1 + w1 ) ) ) && ( ( ( y ) >= ( y1 ) ) && ( ( y ) < ( y1 + h1 ) ) ) ) WindowManagerQuirk current_window_manager = WM_EWHM; @@ -99,25 +104,25 @@ const char *netatom_names[] = { EWMH_ATOMS ( ATOM_CHAR ) }; cairo_surface_t *x11_helper_get_screenshot_surface ( void ) { return cairo_xcb_surface_create ( xcb->connection, - xcb_stuff_get_root_window (), root_visual, - xcb->screen->width_in_pixels, xcb->screen->height_in_pixels ); + xcb_stuff_get_root_window (), root_visual, + xcb->screen->width_in_pixels, xcb->screen->height_in_pixels ); } static xcb_pixmap_t get_root_pixmap ( xcb_connection_t *c, - xcb_screen_t *screen, - xcb_atom_t atom ) + xcb_screen_t *screen, + xcb_atom_t atom ) { xcb_get_property_cookie_t cookie; xcb_get_property_reply_t *reply; xcb_pixmap_t rootpixmap = XCB_NONE; cookie = xcb_get_property ( c, - 0, - screen->root, - atom, - XCB_ATOM_PIXMAP, - 0, - 1 ); + 0, + screen->root, + atom, + XCB_ATOM_PIXMAP, + 0, + 1 ); reply = xcb_get_property_reply ( c, cookie, NULL ); @@ -138,7 +143,7 @@ cairo_surface_t * x11_helper_get_bg_surface ( void ) return NULL; } return cairo_xcb_surface_create ( xcb->connection, pm, root_visual, - xcb->screen->width_in_pixels, xcb->screen->height_in_pixels ); + xcb->screen->width_in_pixels, xcb->screen->height_in_pixels ); } // retrieve a text property from a window @@ -234,6 +239,51 @@ static workarea * x11_get_monitor_from_output ( xcb_randr_output_t out ) return retv; } +#if ( ( (XCB_RANDR_MAJOR_VERSION >= RANDR_PREF_MAJOR_VERSION ) && (XCB_RANDR_MINOR_VERSION >= RANDR_PREF_MINOR_VERSION ) ) \ + || XCB_RANDR_MAJOR_VERSION > RANDR_PREF_MAJOR_VERSION ) +/** + * @param mon The randr monitor to parse. + * + * Create monitor based on xrandr monitor id. + * + * @returns A workarea representing the monitor mon + */ +static workarea *x11_get_monitor_from_randr_monitor ( xcb_randr_monitor_info_t *mon ) +{ + // Query to the name of the monitor. + xcb_generic_error_t *err; + xcb_get_atom_name_cookie_t anc = xcb_get_atom_name(xcb->connection, mon->name); + xcb_get_atom_name_reply_t *atom_reply = xcb_get_atom_name_reply( xcb->connection, anc, &err); + if (err != NULL) { + g_warning ("Could not get RandR monitor name: X11 error code %d\n", err->error_code); + free(err); + return NULL; + } + workarea *retv = g_malloc0 ( sizeof ( workarea ) ); + + // Is primary monitor. + retv->primary = mon->primary; + + // Position and size. + retv->x = mon->x; + retv->y = mon->y; + retv->w = mon->width; + retv->h = mon->height; + + // Physical + retv->mw = mon->width_in_millimeters; + retv->mh = mon->height_in_millimeters; + + // Name + retv->name = g_strdup_printf("%.*s", xcb_get_atom_name_name_length(atom_reply), xcb_get_atom_name_name(atom_reply)); + + // Free name atom. + free ( atom_reply ); + + return retv; +} +#endif + static int x11_is_extension_present ( const char *extension ) { xcb_query_extension_cookie_t randr_cookie = xcb_query_extension ( xcb->connection, strlen ( extension ), extension ); @@ -250,18 +300,18 @@ static int x11_is_extension_present ( const char *extension ) static void x11_build_monitor_layout_xinerama () { xcb_xinerama_query_screens_cookie_t screens_cookie = xcb_xinerama_query_screens_unchecked ( - xcb->connection - ); + xcb->connection + ); xcb_xinerama_query_screens_reply_t *screens_reply = xcb_xinerama_query_screens_reply ( - xcb->connection, - screens_cookie, - NULL - ); + xcb->connection, + screens_cookie, + NULL + ); xcb_xinerama_screen_info_iterator_t screens_iterator = xcb_xinerama_query_screens_screen_info_iterator ( - screens_reply - ); + screens_reply + ); for (; screens_iterator.rem > 0; xcb_xinerama_screen_info_next ( &screens_iterator ) ) { workarea *w = g_malloc0 ( sizeof ( workarea ) ); @@ -301,40 +351,75 @@ static void x11_build_monitor_layout () } g_debug ( "Query RANDR for monitor layout." ); - xcb_randr_get_screen_resources_current_reply_t *res_reply; - xcb_randr_get_screen_resources_current_cookie_t src; - src = xcb_randr_get_screen_resources_current ( xcb->connection, xcb->screen->root ); - res_reply = xcb_randr_get_screen_resources_current_reply ( xcb->connection, src, NULL ); - if ( !res_reply ) { - return; //just report error - } - int mon_num = xcb_randr_get_screen_resources_current_outputs_length ( res_reply ); - xcb_randr_output_t *ops = xcb_randr_get_screen_resources_current_outputs ( res_reply ); - - // Get primary. - xcb_randr_get_output_primary_cookie_t pc = xcb_randr_get_output_primary ( xcb->connection, xcb->screen->root ); - xcb_randr_get_output_primary_reply_t *pc_rep = xcb_randr_get_output_primary_reply ( xcb->connection, pc, NULL ); - - for ( int i = mon_num - 1; i >= 0; i-- ) { - workarea *w = x11_get_monitor_from_output ( ops[i] ); - if ( w ) { - w->next = xcb->monitors; - xcb->monitors = w; - if ( pc_rep && pc_rep->output == ops[i] ) { - w->primary = TRUE; + g_debug ( "Randr XCB api version: %d.%d.", XCB_RANDR_MAJOR_VERSION, XCB_RANDR_MINOR_VERSION ); +#if ( ( ( XCB_RANDR_MAJOR_VERSION == RANDR_PREF_MAJOR_VERSION ) && (XCB_RANDR_MINOR_VERSION >= RANDR_PREF_MINOR_VERSION ) ) \ + || XCB_RANDR_MAJOR_VERSION > RANDR_PREF_MAJOR_VERSION ) + xcb_randr_query_version_cookie_t cversion = xcb_randr_query_version(xcb->connection, + RANDR_PREF_MAJOR_VERSION, RANDR_PREF_MINOR_VERSION); + xcb_randr_query_version_reply_t *rversion = xcb_randr_query_version_reply( xcb->connection, cversion, NULL ); + if ( rversion ) { + g_debug ( "Found randr version: %d.%d", rversion->major_version, rversion->minor_version ); + // Check if we are 1.5 and up. + if ( ( ( rversion->major_version == XCB_RANDR_MAJOR_VERSION ) && (rversion->minor_version >= XCB_RANDR_MINOR_VERSION ) ) || + ( rversion->major_version > XCB_RANDR_MAJOR_VERSION ) ){ + xcb_randr_get_monitors_cookie_t t = xcb_randr_get_monitors( xcb->connection, xcb->screen->root, 1 ); + xcb_randr_get_monitors_reply_t *mreply = xcb_randr_get_monitors_reply ( xcb->connection, t, NULL ); + if( mreply ) { + xcb_randr_monitor_info_iterator_t iter = xcb_randr_get_monitors_monitors_iterator ( mreply ); + while ( iter.rem > 0 ) { + workarea *w = x11_get_monitor_from_randr_monitor ( iter.data ); + if ( w ) { + w->next = xcb->monitors; + xcb->monitors = w; + } + xcb_randr_monitor_info_next (&iter); + } + free ( mreply ); } } + free ( rversion ); + } +#endif + + // If no monitors found. + if ( xcb->monitors == NULL ) { + xcb_randr_get_screen_resources_current_reply_t *res_reply; + xcb_randr_get_screen_resources_current_cookie_t src; + src = xcb_randr_get_screen_resources_current ( xcb->connection, xcb->screen->root ); + res_reply = xcb_randr_get_screen_resources_current_reply ( xcb->connection, src, NULL ); + if ( !res_reply ) { + return; //just report error + } + int mon_num = xcb_randr_get_screen_resources_current_outputs_length ( res_reply ); + xcb_randr_output_t *ops = xcb_randr_get_screen_resources_current_outputs ( res_reply ); + + // Get primary. + xcb_randr_get_output_primary_cookie_t pc = xcb_randr_get_output_primary ( xcb->connection, xcb->screen->root ); + xcb_randr_get_output_primary_reply_t *pc_rep = xcb_randr_get_output_primary_reply ( xcb->connection, pc, NULL ); + + for ( int i = mon_num - 1; i >= 0; i-- ) { + workarea *w = x11_get_monitor_from_output ( ops[i] ); + if ( w ) { + w->next = xcb->monitors; + xcb->monitors = w; + if ( pc_rep && pc_rep->output == ops[i] ) { + w->primary = TRUE; + } + } + } + // If exists, free primary output reply. + if ( pc_rep ) { + free ( pc_rep ); + } + free ( res_reply ); + } + // Number monitor int index = 0; for ( workarea *iter = xcb->monitors; iter; iter = iter->next ) { iter->monitor_id = index++; } - // If exists, free primary output reply. - if ( pc_rep ) { - free ( pc_rep ); - } - free ( res_reply ); } void display_dump_monitor_layout ( void ) @@ -352,13 +437,13 @@ void display_dump_monitor_layout ( void ) printf ( "%s size%s: %d,%d\n", ( is_term ) ? color_bold : "", is_term ? color_reset : "", iter->w, iter->h ); if ( iter->mw > 0 && iter->mh > 0 ) { printf ( "%s size%s: %dmm,%dmm dpi: %.0f,%.0f\n", - ( is_term ) ? color_bold : "", - is_term ? color_reset : "", - iter->mw, - iter->mh, - iter->w * 25.4 / (double) iter->mw, - iter->h * 25.4 / (double) iter->mh - ); + ( is_term ) ? color_bold : "", + is_term ? color_reset : "", + iter->mw, + iter->mh, + iter->w * 2 |