diff --git a/doc/fvwm3_manpage_source.adoc b/doc/fvwm3_manpage_source.adoc index 1c9489f7c..583d93e24 100644 --- a/doc/fvwm3_manpage_source.adoc +++ b/doc/fvwm3_manpage_source.adoc @@ -341,6 +341,16 @@ the window's upper right hand corner 5 pixels above and to the left of the upper left hand corner of the screen; others may do just plain bizarre things. +There is a fvwm-specific extension to geometry strings which can also +enforce the geometry is relative to the given screen. For example: + +.... +xterm -geometry +0+0@n +.... + +Where 'n' can be one of a RandR monitor name, or an assigned monitor number. +For more details, see the RANDR SUPPORT section. + There are several ways to cause a window to map onto a desktop or page other than the currently active one. The geometry technique mentioned above (specifying x,y coordinates larger than the physical screen size), diff --git a/fvwm/expand.c b/fvwm/expand.c index bceeabab9..3a8970e39 100644 --- a/fvwm/expand.c +++ b/fvwm/expand.c @@ -25,7 +25,6 @@ #include "libs/ColorUtils.h" #include "libs/safemalloc.h" #include "libs/FEvent.h" -#include "libs/strtonum.h" #include "fvwm.h" #include "externs.h" #include "cursor.h" @@ -543,12 +542,10 @@ static signed int expand_vars_extended( /* We could be left with ".?" */ char *m_name = NULL; - struct monitor *mon2 = NULL, *m_loop; + struct monitor *mon2 = NULL; char *rest_s; - const char *errstr; char *p_free; int got_string; - int pos = -1; /* The first word is the monitor name: * @@ -560,22 +557,7 @@ static signed int expand_vars_extended( p_free = rest_s; got_string = 0; while ((m_name = strsep(&rest_s, ".")) != NULL) { - /* Try parsing the name as a number. If that fails, - * then treat it as a valid name. - */ - pos = strtonum(m_name, 0, INT_MAX, &errstr); - if (errstr != NULL) - pos = -1; - - RB_FOREACH(m_loop, monitors, &monitor_q) { - if (m_loop->number == pos) { - mon2 = m_loop; - goto rest; - } - } - mon2 = monitor_resolve_name(m_name); -rest: if (mon2 == NULL) { free(p_free); diff --git a/libs/FScreen.c b/libs/FScreen.c index 3188eea9f..041c6fd74 100644 --- a/libs/FScreen.c +++ b/libs/FScreen.c @@ -29,6 +29,7 @@ #include "FScreen.h" #include "FEvent.h" #include "queue.h" +#include "strtonum.h" #define GLOBAL_SCREEN_NAME "_global" @@ -114,6 +115,18 @@ monitor_scan_edges(struct monitor *m) } } +struct monitor * +monitor_by_number(int n) +{ + struct monitor *m_loop; + + RB_FOREACH(m_loop, monitors, &monitor_q) { + if (m_loop->number == n) + return (m_loop); + } + return (NULL); +} + void monitor_refresh_global(void) { @@ -217,11 +230,22 @@ struct monitor * monitor_resolve_name(const char *scr) { struct monitor *m = NULL; + int pos = -1; + const char *errstr; if (scr == NULL) { return NULL; } + + /* Try and look up the monitor as a number. If that succeeds, + * try and match that number as something valid in the monitor + * information we have. + */ + pos = strtonum(scr, 0, INT_MAX, &errstr); + if (errstr == NULL) + return (monitor_by_number(pos)); + /* "@g" is for the global screen. */ if (strcmp(scr, "g") == 0) { m = monitor_get_global(); diff --git a/libs/FScreen.h b/libs/FScreen.h index aec9dd963..6a6084098 100644 --- a/libs/FScreen.h +++ b/libs/FScreen.h @@ -156,6 +156,7 @@ RB_PROTOTYPE(monitors, monitor, entry, monitor_compare); struct monitor *monitor_resolve_name(const char *); struct monitor *monitor_by_xy(int, int); struct monitor *monitor_by_output(int); +struct monitor *monitor_by_number(int); struct monitor *monitor_by_primary(void); struct monitor *monitor_by_last_primary(void); struct monitor *monitor_get_current(void);