diff --git a/doc/FvwmPager.adoc b/doc/FvwmPager.adoc index e69028250..917a356fd 100644 --- a/doc/FvwmPager.adoc +++ b/doc/FvwmPager.adoc @@ -2,148 +2,117 @@ == NAME -FvwmPager - the Fvwm Pager module +FvwmPager - The fvwm pager module == SYNOPSIS -*FvwmPager* [ _-transient_ ] [ _name_ ] [ _first desk_ [ _last desk_ ] ] -FvwmPager is spawned by fvwm, so no command line invocation will work. - -All desks with desk numbers between _first desk_ and _last_ desk are -displayed. If _last desk_ is omitted only the _first desk_ is shown. If -both desk numbers are omitted, the current desk is used instead. If you -use an asterisk '*' in place of _first desk_ the pager will always show -the current desktop, even when you switch desks. - -FvwmPager will compute its initial window size based on your monitor(s) -configuration. By default it makes a page 1/32 the size of your monitor(s) -resolution (see _DeskTopScale_) and matches either the global aspect ratio -or a single monitor if _Monitor_ is set. FvwmPager will preserve this -aspect ratio when you resize it. See the _Geometry_ option for more info. - -Example lines to put in your .fvwm2rc: - -.... -Module FvwmPager 0 3 -.... - -or - -.... -Module FvwmPager * -.... - -or from within an fvwm pop-up menu: +*FvwmPager* [ _-transient_ ] [ _alias_ ] [ _first desk_ [ _last desk_ ] ] -.... -AddToMenu Module-Popup Modules Title -+ Audio Module FvwmAudio -+ Auto Module FvwmAuto 200 -+ Buttons Module FvwmButtons -+ Console Module FvwmConsole -+ Ident Module FvwmIdent -+ Banner Module FvwmBanner -+ Pager Module FvwmPager 0 3 -.... +FvwmPager is spawned by fvwm, so no command line invocation will work. -or +FvwmPager displays a miniature view of the fvwm virtual desktop(s) showing +all desk numbers between _first desk_ and _last desk_. If _last desk_ is +omitted only the _first desk_ is shown. If both desk numbers are omitted, +the current desk is used instead. If you use an asterisk '*' in place of +_first desk_ the pager will always show the current desktop, even when you +switch desks. If you iconify FvwmPager, its icon on the virtual desktop +will be a functional version of the pager only showing the current desktop. + +FvwmPager is launched via the `Module FvwmPager` command from fvwm's config +file, and can be launched from functions, menus, key bindings, and so on. If +the pager is started with the _-transient_ option, the next time a button is +released the pager is closed. Note that this option only works if the window +style of the pager window is 'Sticky' (see the fvwm man page). You should use +the 'StaysOnTop' style too. + +The following example shows how to launch two pagers from your config file +when fvwm starts. The first is a pager which will show all desks from 0 to +3, and the second is a pager which only shows the current desk. .... -+ Pager Module FvwmPager * +AddToFunc StartFunction Module FvwmPager 0 3 +AddToFunc StartFunction Module FvwmPager * .... -If the pager is started with the _-transient_ option, the next time a -button is released the pager is closed. Note that this option does only -work if the window style of the pager window is 'sticky' (see the fvwm -man page). You should use the 'StaysOnTop' style too. +FvwmPager is configured via an fvwm module configuration alias. If an _alias_ +is given, FvwmPager will use the _alias_ for the configuration and name of the +window. If no _alias_ is given, the default 'FvwmPager' alias is used. See the +*CONFIGURATION* section below for a full list of configuration options. -Example: +== DESCRIPTION -.... -Style FvwmPager Sticky, StaysOnTop -*FvwmPager: Rows 1 -*FvwmPager: Columns 1 -Mouse 3 R C Module FvwmPager -transient -.... +FvwmPager displays a miniature view of the fvwm virtual desktop(s) showing +the position of all windows and pages within each visible desktop. If +_DeskHilight_ is set, the location of each monitor within the +desktop is also shown. The pager can be used as a quick reference of the +location of windows and monitors, to change the current page/desk, and to +focus or move windows. The behavior of FvwmPager depends on the current +'DesktopConfiguration'. + +When clicked with button 1, FvwmPager will move the current desk/page to the +location clicked. If using 'DesktopConfiguration global' all monitors will +move to the location clicked, 'DesktopConfiguration per-monitor' moves the +only the monitor which occupies the area clicked, and last +'DesktopConfiguration shared' only allows changing pages of a monitor which +occupies the clicked desk. If _MonitorLabels_ are showing, clicks on the +monitor label will move that monitor to the clicked desk. Clicks in which it +cannot be clearly determined which monitor to move will be ignored, such as +clicks on desk labels or dead space in 'per-monitor' mode, clicking on a desk +not occupied by any monitor in 'shared' mode. It is suggested to use +_MonitorLabels_ with 'shared' mode. + +When clicked with button 3, FvwmPager will move the current view port centered +on the area clicked. Unlike a left click, which always places the monitor(s) +inside a single page's boundaries, left click will 'Scroll' between multiple +pages. While right click is held down, moving the mouse will cause the view +port to 'Scroll' to the mouse location. Note that 'Scroll' works best in +'global' mode. + +When button 2 clicks a window in the pager, that window will gain focus. +Setting the _*FvwmPager: SloppyFocus_ option will give focus to the window +under the mouse without clicking. Holding down button 2 on a window in the +pager can be used the move the window. The window can be placed at any +location inside the pager, and when you move the window outside of the pager, +the window will move to the current location, and can continued to be moved. + +When iconified, FvwmPager's icon on the desktop is a fully functional pager +that only shows the current desk. This icon pager responds to all the same +clicks as described above. This is useful by allowing full pager that shows +multiple virtual desktops to be iconified to a smaller pager that only shows +the current desk. Note that the FvwmPager icon must be visible via +'Style FvwmPager Icon', and not overridden, for this to work. -With this in your .fvwm2rc, if you press control and button 3 in the -root window the pager pops up under the mouse and while the viewport -moves with the mouse. +FvwmPager will compute its initial window size based on your monitor(s) +configuration. By default it makes a pager 1/32 the size of your monitor(s) +resolution (see _DeskTopScale_) and matches either the global +aspect ratio or a single monitor if _Monitor_ is set. Both the size of +the pager (see _Geometry_) and desktop layout (see _Cols_ and _Rows_) +can be configured. -== DESCRIPTION +== CONFIGURATION -The FvwmPager module shows a miniature view of the Fvwm desktops which -are specified in the command line. This is a useful reminder of where -your active windows are. Windows in the pager are shown in the same -color as their fvwm decorations. - -The pager can be used to change your viewport into the current desktop, -to change desktops, or to move windows around. - -Pressing mouse button 1 in the pager will cause you viewport to change -to the selected page of the selected desk. If you click with button 1 in -the desk-label area, you will switch desks but not pages within the -desk. - -Dragging mouse button 2 on a miniature view of a window will cause that -window to be move to the location where you release the mouse button, -but your viewport will not change. If you drag the window out of the -pager and onto your desktop, a full size image of the window will appear -for you to place. There is no way to pick up a full size image of the -window and move it into the pager, however. Since some mice do not have -button 2, I have made provisions to drag windows in the pager by using -pressing modifier-1 (usually Alt) and dragging with button 3. - -Clicking mouse button 3 on a location will cause the viewport to move to -the selected location and switch desks if necessary, but will not align -the viewport to a page boundary. Dragging button 3 will cause the -viewport to move as you drag but not switch desktops, even if the -pointer moves to another desktop. - -With the _*FvwmPager: SloppyFocus_ option the focus is transferred to -the window pointed at with the mouse when the pointer is inside the -pager. - -When iconified, the pager will work as a fully functional current desk -only pager. Windows and viewports can be moved within the icon of the -pager. Users will want to make sure that they have no lines similar to +FvwmPager is configured via a module configuration alias in fvwm's +configuration file. The default alias is 'FvwmPager' and can be configured +using lines of the form: .... -Icon "Fvwm Pager" whatever +*FvwmPager: Option parameters .... -in their .fvwm2rc files. - -== INITIALIZATION - -During initialization, _FvwmPager_ gets config info from *fvwm*'s module -configuration database (see _fvwm_(1), section *MODULE COMMANDS*). - -To use FvwmPager with several different configurations, you can invoke -FvwmPager with an optional parameter, which it will use as its _name_ -instead (e.g "Module FvwmPager OtherPager"). OtherPager will then read -only the lines in the configuration file starting with "*OtherPager", -and not the lines belonging to FvwmPager. This way multiple pager -instances may be used. - -Note: the old way to use the FvwmPager with several different -configurations is to link the executable to another name, i.e. +When FvwmPager is launched with an optional _alias_, that _alias_ will +be used for the configuration instead. For example to start a pager that +shows the current desk on a single monitor, use the following: .... -ln -s FvwmPager OtherPager +DestroyModuleConfig FvwmPagerDP2:* +*FvwmPagerDP2: Monitor DP-2 +*FvwmPagerDP2: Font None +*FvwmPagerDP2: MiniIcons +AddToFunc StartFunction Module FvwmPager FvwmPagerDP2 * .... -This may work, but this method is not supported. - -== KEYBOARD FOCUS CONTROL - -You can direct the keyboard focus to any window on the current desktop -by clicking with button 2 on its image in the pager. The window does not -need to be visible, but it does need to be on the current page. - -== INVOCATION - -The invocation method was shown in the synopsis section +The full list of configuration options and their parameters +are listed below. == CONFIGURATION OPTIONS @@ -159,12 +128,15 @@ The invocation method was shown in the synopsis section *Note*: FvwmPager's dimensions will be slightly adjusted to ensure every page shown has the exact same number of pixels. So the actual size may be slightly different than the specified size. + *FvwmPager: Rows rows:: Tells fvwm how many rows of desks to use when laying out the pager window. + *FvwmPager: Columns columns:: Tells fvwm how many columns of desks to use when laying out the pager window. + *FvwmPager: IconGeometry geometry:: Specifies a size (optional) and location (optional) for the pager's icon window. Since there is no easy way for FvwmPager to determine the @@ -172,79 +144,116 @@ size may be slightly different than the specified size. icon label height when using negative y-coordinates in the icon location specification (used to specify a location relative to the bottom instead of the top of the screen). + *FvwmPager: StartIconic:: Causes the pager to start iconified. + *FvwmPager: NoStartIconic:: Causes the pager to start normally. Useful for canceling the effect of the _StartIconic_ option. + *FvwmPager: LabelsBelow:: Causes the pager to draw desk labels below the corresponding desk. + *FvwmPager: LabelsAbove:: Causes the pager to draw desk labels above the corresponding desk. Useful for canceling the effect of the _LabelsBelow_ option. + *FvwmPager: ShapeLabels:: Causes the pager to hide the labels of all but the current desk. This turns off label hilighting. + *FvwmPager: NoShapeLabels:: Causes the pager to show the labels of all visible desks. Useful for canceling the effect of the _ShapeLabels_ option. + +*FvwmPager: DeskLabels:: + Tells FvwmPager to display a label for each desk. This is the default + state, but this is useful for undoing _Font none_ or _NoDeskLabels_. + +*FvwmPager: NoDeskLabels:: + Tells FvwmPager to not display desk labels. + +*FvwmPager: MonitorLabels:: + Tells FvwmPager to display a row of monitor labels. The monitor label + on the desktop the monitor is currently viewing will be highlighted using + the hilight color. Clicking on a monitor label will move that monitor to + the selected desktop. This option is best used with + 'DesktopConfiguration shared' to be able to control which monitor is moved + to a selected desktop. + +*FvwmPager: NoMonitorLabels:: + Tells FvwmPager to not display monitor labels, the default state. + *FvwmPager: Font font-name:: Specified a font to use to label the desktops. If _font_name_ is - "none" then no desktop labels will be displayed. + "none" then no desktop or monitor labels will be displayed. Note, + if _MonitorLabels_ or _DeskLabels_ is used after _Font none_, + the labels will be shown with a default font. + *FvwmPager: SmallFont font-name:: Specified a font to use to label the window names in the pager. If not specified, the window labels will be omitted. Window labels seem to be fairly useless for desktop scales of 32 or greater. If _font_name_ is "none" then no window names will be displayed. + *FvwmPager: Fore color:: Specifies the color to use to write the desktop labels, and to draw the page-grid lines. + *FvwmPager: Back color:: Specifies the background color for the window. + *FvwmPager: Hilight color:: The active page and desk label will be highlighted by using this background pattern instead of the normal background. + *FvwmPager: HilightPixmap pixmap:: The active page will be highlighted by using this background pattern instead of the normal background. + *FvwmPager: DeskHilight:: - Hilight the active page with the current hilight color/pixmap. Useful - for canceling the effect of the _NoDeskHilight_ option. + Hilight the area shown by all active monitors with the current hilight + color/pixmap. Useful for canceling the effect of the _NoDeskHilight_ option. + *FvwmPager: NoDeskHilight:: Don't hilight the active page. + *FvwmPager: WindowColors fore back hiFore hiBack:: Change the normal/highlight colors of the windows. _fore_ and _hiFore_ specify the colors as used for the font inside the windows. _back_ and _hiBack_ are used to fill the windows with. + *FvwmPager: WindowLabelFormat format:: This specifies a printf() like format for the labels in the mini window. Possible flags are: %t, %i, %c, and %r for the window's title, icon title, class, or resource name, respectively. The default is "%i". + *FvwmPager: DeskColor desk color:: Assigns the color _color_ to desk _desk_ (or the current desk if desk is "*") in the pager window. This replaces the background color for the particular _desk_. This only works when the pager is full sized. When Iconified, the pager uses the color specified by *FvwmPager: Back. -+ - *FvwmPager: Pixmap pixmap:: Use _pixmap_ as background for the pager. + *FvwmPager: DeskPixmap desk pixmap:: Assigns the pixmap _color_ to desk _desk_ (or the current desk if desk is "*") in the pager window. This replaces the background pixmap for the particular _desk_. -+ *FvwmPager: DeskTopScale number:: If the geometry is not specified, then a desktop reduction factor is used to calculate the pager's size. Things in the pager window are shown at 1/_number_ of the actual size. + *FvwmPager: MiniIcons:: Allow the pager to display a window's mini icon in the pager, if it has one, instead of showing the window's name. + *FvwmPager: MoveThreshold pixels:: Defines the distance the pointer has to be moved before a window being dragged with button 2 is actually moved. The default value is three @@ -253,6 +262,7 @@ size may be slightly different than the specified size. is less than zero the default value is used. The value set with the _MoveThreshold_ command in fvwm is inherited by FvwmPager but can be overridden with this option. + *FvwmPager: SloppyFocus:: If the SloppyFocus option is used, you do not need to click into the mini window in the pager to give the real window the focus. Simply @@ -270,8 +280,10 @@ done about this - except not using SloppyFocus in the pager. By default the pages of the virtual desktop are separated by dashed lines in the pager window. This option causes FvwmPager to use solid lines instead. + *FvwmPager: NoSeparators:: Turns off the lines separating the pages of the virtual desktop. + *FvwmPager: Balloons [type]:: Show a balloon describing the window when the pointer is moved into a window in the pager. The default format (the window's icon name) can @@ -279,18 +291,24 @@ done about this - except not using SloppyFocus in the pager. are just shown for an un-iconified pager; if _type_ is _Icon_ balloons are just shown for an iconified pager. If _type_ is anything else (or null) balloons are always shown. + *FvwmPager: BalloonFore color:: Specifies the color for text in the balloon window. If omitted it defaults to the foreground color for the window being described. + *FvwmPager: BalloonBack color:: Specifies the background color for the balloon window. If omitted it defaults to the background color for the window being described. + *FvwmPager: BalloonFont font-name:: Specifies a font to use for the balloon text. Defaults to _fixed_. + *FvwmPager: BalloonBorderWidth number:: Sets the width of the balloon window's border. Defaults to 1. + *FvwmPager: BalloonBorderColor color:: Sets the color of the balloon window's border. Defaults to black. + *FvwmPager: BalloonYOffset number:: The balloon window is positioned to be horizontally centered against the pager window it is describing. The vertical position may be set as @@ -301,46 +319,57 @@ done about this - except not using SloppyFocus in the pager. permit direct transit from pager window to balloon window, causing an event loop. Defaults to +3. The offset will change sign automatically, as needed, to keep the balloon on the screen. + *FvwmPager: BalloonStringFormat format:: The same as _*FvwmPager: WindowLabelFormat_, it just specifies the string to display in the balloons. The default is "%i". + *FvwmPager: Colorset desk colorset:: Tells the module to use colorset _colorset_ for _desk_. If you use an asterisk '*' in place of _desk_, the colorset is used on all desks. + *FvwmPager: BalloonColorset desk colorset:: Tells the module to use colorset _colorset_ for balloons on _desk_. If you use an asterisk '*' in place of _desk_, the colorset is used on all desks. + *FvwmPager: HilightColorset desk colorset:: Tells the module to use colorset _colorset_ for hilighting on _desk_. If you use an asterisk '*' in place of _desk_, the colorset is used on all desks. + *FvwmPager: WindowColorsets colorset activecolorset:: Uses colorsets in the same way as *FvwmPager: WindowColors. The shadow and hilight colors of the colorset are only used for the window borders if the *FvwmPager: Window3DBorders is specified too. + *FvwmPager: WindowMinSize n:: Specifies the minimum size as _n_ pixels of the mini windows. This does not include the width of the border, so the actual minimum size is 2 * _WindowBorderWidth_ + _WindowMinSize_. The default is 3. + *FvwmPager: WindowBorderWidth n:: Specifies the width of the border drawn around the mini windows. This also affects the minimum size of the mini windows, which will be 2 * _WindowBorderWidth_ + _WindowMinSize_. The default is 1. + *FvwmPager: HideSmallWindows:: Tells FvwmPager to not show windows that are the minimum size. Useful for tiny pagers where small windows will appear out of place. + *FvwmPager: Window3DBorders:: Specifies that the mini windows should have a 3d borders based on the mini window background. This option only works if *FvwmPager: WindowColorsets is specified. + *FvwmPager: UseSkipList:: Tells FvwmPager to not show the windows that are using the WindowListSkip style. + *FvwmPager: Monitor RandRName:: Tells FvwmPager to display windows only on _RandRName_ monitor. This is especially meaningful when the _DesktopConfiguration_ command is - set to _per-monitor_. + set to _shared_. == AUTHOR diff --git a/doc/fvwm3_manpage_source.adoc b/doc/fvwm3_manpage_source.adoc index 583d93e24..db87d3984 100644 --- a/doc/fvwm3_manpage_source.adoc +++ b/doc/fvwm3_manpage_source.adoc @@ -3927,7 +3927,7 @@ Move shuffle Up Left *Move* can be used to moved a window to a specified position: + -> *Move* [screen _S_] \[w | m]_x_[p | w] \[w | m]_y_[p | w] [Warp] [ewmhiwa] +> *Move* [screen _S_] \[w | m | v]_x_[p | w] \[w | m | v]_y_[p | w] [Warp] [ewmhiwa] + This will move the window to the _x_ and _y_ position (see below). @@ -3950,8 +3950,11 @@ while a trailing '_w_' means percent of the window width/height. To move the window relative to its current position, add the '_w_' (for "window") prefix before the _x_ and/or _y_ value. To move the window to a position relative to the current location of the pointer, add the '_m_' (for "mouse") prefix. To -leave either coordinate unchanged, "_keep_" can be specified in place of -_x_ or _y_. +move the window relative to the virtual screen coordinates, add the '_v_' +(for "virtual screen") prefix. This is mostly for internal use with FvwmPager, +but can be used to give exact coordinates on the virtual screen and is best +used with the '_p_' suffix. To leave either coordinate unchanged, "_keep_" +can be specified in place of _x_ or _y_. + For advanced uses, the arguments _x_ and _y_ can be used multiple times, but without the prefix '_m_' or '_w_'. (See complex examples diff --git a/fvwm/events.c b/fvwm/events.c index 396f890b1..20bf07d3d 100644 --- a/fvwm/events.c +++ b/fvwm/events.c @@ -1831,6 +1831,9 @@ void monitor_update_ewmh(void) set_ewmhc_strut_values(m, ewbs); } EWMH_Init(m); + + /* Clear the flag now that it's been registered. */ + m->flags &= ~MONITOR_NEW; } TAILQ_FOREACH_SAFE(mo, &monitorsold_q, oentry, mo1) { @@ -4872,4 +4875,4 @@ void CMD_XSync(F_CMD_ARGS) XSync(dpy, 0); return; -} \ No newline at end of file +} diff --git a/fvwm/ewmh.c b/fvwm/ewmh.c index 8736bfbba..10ddd5d84 100644 --- a/fvwm/ewmh.c +++ b/fvwm/ewmh.c @@ -1963,8 +1963,6 @@ void EWMH_Init(struct monitor *m) EWMH_SetDesktopGeometry(m); EWMH_SetClientList(m); EWMH_SetClientListStacking(m); - - m->flags &= ~MONITOR_NEW; } /* diff --git a/fvwm/fvwm3.c b/fvwm/fvwm3.c index 097c2988b..6254c7f88 100644 --- a/fvwm/fvwm3.c +++ b/fvwm/fvwm3.c @@ -2417,9 +2417,16 @@ int main(int argc, char **argv) LoadWindowStates(state_filename); is_tracking_shared = false; - RB_FOREACH(m, monitors, &monitor_q) + RB_FOREACH(m, monitors, &monitor_q) { EWMH_Init(m); + /* Having initialised the monitor at startup here, we can + * remove this flag, as the monitor is no longer considered + * new. + */ + m->flags &= ~MONITOR_NEW; + } + SetRCDefaults(); flush_window_updates(); simplify_style_list(); diff --git a/fvwm/module_interface.c b/fvwm/module_interface.c index a067bd521..a59afaca7 100644 --- a/fvwm/module_interface.c +++ b/fvwm/module_interface.c @@ -468,21 +468,47 @@ void BroadcastName( void BroadcastMonitorList(fmodule *this) { char *name; + const char *m_info; struct monitor *m; fmodule_list_itr moditr; fmodule *module; module_list_itr_init(&moditr); + m_info = "Monitor %s %d %d %d %d %d %d %d %d %d %d"; + while ((module = module_list_itr_next(&moditr)) != NULL) { RB_FOREACH(m, monitors, &monitor_q) { - if (m->flags & MONITOR_DISABLED) - continue; - xasprintf(&name, "Monitor %s", m->si->name); + xasprintf(&name, m_info, m->si->name, m->flags, + m->dx, m->dy, m->virtual_scr.Vx, + m->virtual_scr.Vy, m->virtual_scr.VxMax, + m->virtual_scr.VyMax, m->virtual_scr.CurrentDesk, + monitor_get_all_widths(), monitor_get_all_heights()); SendName(module, M_CONFIG_INFO, 0, 0, 0, name); free(name); } + xasprintf(&name, "DesktopConfiguration %d %d", + monitor_mode, is_tracking_shared); + SendName(module, M_CONFIG_INFO, 0, 0, 0, name); + free(name); + + /* Reissue the DesktopSize command here, rather than sending + * down the DesktopSize -- we want FvwmPager in particular to + * react to a M_NEW_PAGE event, which DesktopSize will do; and + * this avoids duplication in FvwmPager as a result. + */ + char action[256]; + + /* Every monitor will have the same dx/dy values, so just take + * the fist entry in our list. + */ + struct monitor *m = RB_MIN(monitors, &monitor_q); + + snprintf(action, sizeof(action), "DesktopSize %dx%d", + m->dx, m->dy); + execute_function_override_window(NULL, NULL, action, NULL, 0, + NULL); } } @@ -1001,4 +1027,4 @@ void CMD_Send_WindowList(F_CMD_ARGS) } SendPacket(mod, M_END_WINDOWLIST, 0); -} \ No newline at end of file +} diff --git a/fvwm/move_resize.c b/fvwm/move_resize.c index e4621fe48..b48d74254 100644 --- a/fvwm/move_resize.c +++ b/fvwm/move_resize.c @@ -556,6 +556,7 @@ static int GetOnePositionArgument( { int final_pos; int pos_change = 0; + int return_val = 1; float wfactor; if (s1 == 0 || *s1 == 0) @@ -571,6 +572,12 @@ static int GetOnePositionArgument( final_pos = window_pos; s1++; break; + case 'v': + case 'V': + final_pos = 0; + return_val = 2; + s1++; + break; case 'm': case 'M': { @@ -677,7 +684,7 @@ static int GetOnePositionArgument( } *pFinalPos = final_pos; - return 1; + return return_val; } /* GetMoveArguments is used for Move & AnimatedMove @@ -688,6 +695,8 @@ static int GetOnePositionArgument( * 10p -0p Absolute pixel position, from bottom * w+5 w-10p Relative position, right 5%, up ten pixels * m+5 m-10p Pointer relative position, right 5%, up ten pixels + * v+5p v+10p Virtual screen absolute position, place at position + * (5p,10p) in the virtual screen, with (0p,0p) top left. * Returns 2 when x & y have parsed without error, 0 otherwise */ int GetMoveArguments(FvwmWindow *fw, @@ -704,6 +713,8 @@ int GetMoveArguments(FvwmWindow *fw, int scr_h = monitor_get_all_heights(); Bool use_working_area = True; Bool global_flag_parsed = False; + Bool use_virt_x = False; + Bool use_virt_y = False; int retval = 0; if (!paction) @@ -786,34 +797,57 @@ int GetMoveArguments(FvwmWindow *fw, if (s1 != NULL && s2 != NULL) { + int n; retval = 0; if (fKeep == True && StrEquals(s1, "keep")) { retval++; } - else if ( - GetOnePositionArgument( - s1, pFinal->x, s.width, &(pFinal->x), - (float)scr_w / 100, scr_w, scr_pos.x, True)) + else { - retval++; + n = GetOnePositionArgument( + s1, pFinal->x, s.width, &(pFinal->x), + (float)scr_w / 100, scr_w, scr_pos.x, True); + if (n > 0) + { + retval++; + if (n == 2) + { + use_virt_x = True; + } + } } if (fKeep == True && StrEquals(s2, "keep")) { retval++; } - else if ( - GetOnePositionArgument( - s2, pFinal->y, s.height, &(pFinal->y), - (float)scr_h / 100, scr_h, scr_pos.y, False)) + else { - retval++; + n = GetOnePositionArgument( + s2, pFinal->y, s.height, &(pFinal->y), + (float)scr_h / 100, scr_h, scr_pos.y, False); + if (n > 0) + { + retval++; + if (n == 2) + { + use_virt_y = True; + } + } } - if (retval == 0) + if (retval < 2) { /* make sure warping is off for interactive moves */ *fWarp = False; } + else if (use_virt_x || use_virt_y) + { + /* Adjust position when using virtual screen. */ + struct monitor *m = FindScreenOfXY( + pFinal->x, pFinal->y); + pFinal->x -= (use_virt_x) ? m->virtual_scr.Vx : 0; + pFinal->y -= (use_virt_y) ? m->virtual_scr.Vy : 0; + } } else { diff --git a/fvwm/update.c b/fvwm/update.c index fbef3858d..770e54bfd 100644 --- a/fvwm/update.c +++ b/fvwm/update.c @@ -679,7 +679,6 @@ Bool update_fvwm_monitor(FvwmWindow *fw) EWMH_SetCurrentDesktop(fw->m); desk_add_fw(fw); BroadcastConfig(M_CONFIGURE_WINDOW, fw); - BroadcastMonitorList(NULL); return True; } diff --git a/fvwm/virtual.c b/fvwm/virtual.c index 5f2bca73b..142085ae1 100644 --- a/fvwm/virtual.c +++ b/fvwm/virtual.c @@ -2548,7 +2548,7 @@ void CMD_DesktopSize(F_CMD_ARGS) */ void CMD_GotoDesk(F_CMD_ARGS) { - struct monitor *m, *m_loop; + struct monitor *m = NULL, *m_loop; char *token; int new_desk; @@ -2623,7 +2623,7 @@ void CMD_GotoDeskAndPage(F_CMD_ARGS) int current_desk; Bool is_new_desk; char *token; - struct monitor *m; + struct monitor *m = NULL; token = PeekToken(action, NULL); if (StrEquals(token, "screen")) { @@ -2699,7 +2699,6 @@ void CMD_GotoDeskAndPage(F_CMD_ARGS) BroadcastRestackAllWindows(); } done: - BroadcastMonitorList(NULL); EWMH_SetCurrentDesktop(m); return; @@ -3152,4 +3151,4 @@ void CMD_DesktopName(F_CMD_ARGS) RB_FOREACH(m, monitors, &monitor_q) apply_desktops_monitor(m); -} \ No newline at end of file +} diff --git a/libs/FScreen.c b/libs/FScreen.c index 418b122b4..a7742f660 100644 --- a/libs/FScreen.c +++ b/libs/FScreen.c @@ -613,13 +613,13 @@ scan_screens(Display *dpy) if (!(m->flags & (MONITOR_FOUND|MONITOR_NEW))) { m->flags |= MONITOR_DISABLED; m->emit |= MONITOR_DISABLED; - } else if (m->flags & (MONITOR_FOUND|MONITOR_DISABLED)) { + } else if ((m->flags & (MONITOR_FOUND|MONITOR_DISABLED)) == + (MONITOR_FOUND|MONITOR_DISABLED)) { m->flags &= ~MONITOR_DISABLED; } else { - m->emit |= MONITOR_ENABLED; + m->flags |= MONITOR_ENABLED; } m->flags &= ~MONITOR_FOUND; - } /* Now that all monitors have been inserted, assign them a number from * 0 -> n so that they can be referenced in order. @@ -695,6 +695,22 @@ void FScreenInit(Display *dpy) exit(101); } +void +monitor_refresh_module(Display *dpy) +{ + struct monitor *m = NULL; + + RB_FOREACH(m, monitors, &monitor_q) + m->flags &= ~MONITOR_NEW; + + scan_screens(dpy); + + RB_FOREACH(m, monitors, &monitor_q) { + if (m->flags & MONITOR_NEW) + fprintf(stderr, "MON: %s is NEW...\n", m->si->name); + } +} + void monitor_dump_state(struct monitor *m) { @@ -785,17 +801,15 @@ struct monitor * FindScreenOfXY(int x, int y) { struct monitor *m; - int xa, ya; - int all_widths, all_heights; - - all_widths = monitor_get_all_widths(); - all_heights = monitor_get_all_heights(); + int all_widths = monitor_get_all_widths(); + int all_heights = monitor_get_all_heights(); - xa = abs(x); - ya = abs(y); - - xa %= all_widths; - ya %= all_heights; + x %= all_widths; + y %= all_heights; + if (x < 0) + x += all_widths; + if (y < 0) + y += all_heights; RB_FOREACH(m, monitors, &monitor_q) { /* If we have more than one screen configured, then don't match @@ -805,8 +819,8 @@ FindScreenOfXY(int x, int y) if (monitor_get_count() > 0 && strcmp(m->si->name, GLOBAL_SCREEN_NAME) == 0) continue; - if (xa >= m->si->x && xa < m->si->x + m->si->w && - ya >= m->si->y && ya < m->si->y + m->si->h) + if (x >= m->si->x && x < m->si->x + m->si->w && + y >= m->si->y && y < m->si->y + m->si->h) return (m); } @@ -1398,4 +1412,4 @@ int FScreenFetchMangledScreenFromUSPosHints(XSizeHints *hints) screen = 0; return screen; -} \ No newline at end of file +} diff --git a/libs/FScreen.h b/libs/FScreen.h index 2857941b8..2e701854a 100644 --- a/libs/FScreen.h +++ b/libs/FScreen.h @@ -173,6 +173,7 @@ void monitor_output_change(Display *, XRRScreenChangeNotifyEvent *); int monitor_get_all_widths(void); int monitor_get_all_heights(void); void monitor_assign_virtual(struct monitor *); +void monitor_refresh_module(Display *); void checkPanFrames(struct monitor *); #define FSCREEN_MANGLE_USPOS_HINTS_MAGIC ((short)-32109) diff --git a/modules/FvwmPager/FvwmPager.c b/modules/FvwmPager/FvwmPager.c index 4322eb3e9..58f1fddaa 100644 --- a/modules/FvwmPager/FvwmPager.c +++ b/modules/FvwmPager/FvwmPager.c @@ -118,7 +118,9 @@ Window BalloonView = None; rectangle pwindow = {0, 0, 0, 0}; rectangle icon = {-10000, -10000, 0, 0}; -int usposition = 0,uselabel = 1; +int usposition = 0; +Bool use_desk_label = True; +Bool use_monitor_label = False; int xneg = 0, yneg = 0; int icon_xneg = 0, icon_yneg = 0; extern DeskInfo *Desks; @@ -146,12 +148,14 @@ Bool is_transient = False; Bool do_ignore_next_button_release = False; Bool error_occured = False; Bool Swallowed = False; +Bool fp_new_block = False; static void SetDeskLabel(struct fpmonitor *, int desk, const char *label); static RETSIGTYPE TerminateHandler(int); void ExitPager(void); void list_monitor_focus(unsigned long *); struct fpmonitor *fpmonitor_new(struct monitor *); +void fpmonitor_disable(struct fpmonitor *); struct fpmonitor * fpmonitor_new(struct monitor *m) @@ -159,12 +163,22 @@ fpmonitor_new(struct monitor *m) struct fpmonitor *fp; fp = fxcalloc(1, sizeof(*fp)); + fp->CPagerWin = fxcalloc(1, ndesks * sizeof(*fp->CPagerWin)); fp->m = m; + fp->disabled = false; TAILQ_INSERT_TAIL(&fp_monitor_q, fp, entry); return (fp); } +void fpmonitor_disable(struct fpmonitor *fp) +{ + fp->disabled = true; + for (int i = 0; i < ndesks; i++) { + XMoveWindow(dpy, fp->CPagerWin[i], -32768,-32768); + } +} + struct fpmonitor * fpmonitor_by_name(const char *name) { @@ -193,17 +207,15 @@ fpmonitor_this(struct monitor *m_find) } if (monitor_to_track == NULL) m = monitor_get_current(); - - m = monitor_resolve_name(monitor_to_track); + else + m = monitor_resolve_name(monitor_to_track); if (m == NULL) m = monitor_get_current(); - if (m == NULL) - return (NULL); - if (m->flags & MONITOR_DISABLED) - return (NULL); search: + if (m == NULL || m->flags & MONITOR_DISABLED) + return (NULL); TAILQ_FOREACH(fp, &fp_monitor_q, entry) { if (fp->m == m) return (fp); @@ -376,7 +388,6 @@ int main(int argc, char **argv) flib_init_graphics(dpy); x_fd = XConnectionNumber(dpy); - flib_init_graphics(dpy); Scr.screen = DefaultScreen(dpy); Scr.Root = RootWindow(dpy, Scr.screen); @@ -408,6 +419,9 @@ int main(int argc, char **argv) MX_PROPERTY_CHANGE| MX_MONITOR_FOCUS); + RB_FOREACH(mon, monitors, &monitor_q) + (void)fpmonitor_new(mon); + ParseOptions(); if (is_transient) { @@ -448,15 +462,13 @@ int main(int argc, char **argv) if (BalloonFormatString == NULL) BalloonFormatString = fxstrdup("%i"); - RB_FOREACH(mon, monitors, &monitor_q) - (void)fpmonitor_new(mon); - /* Create a list of all windows */ /* Request a list of all windows, * wait for ConfigureWindow packets */ SendInfo(fd,"Send_WindowList",0); /* open a pager window */ + initialise_common_pager_fragments(); initialize_pager(); if (is_transient) @@ -766,14 +778,6 @@ void list_configure(unsigned long *body) t = Start; newm = monitor_by_output((int)cfgpacket->monitor_id); - if (newm == NULL) { - fvwm_debug(__func__, "monitor was null with ID: %d\n", - (int)cfgpacket->monitor_id); - fvwm_debug(__func__, "using current montior\n"); - - newm = monitor_get_current(); - } - while( (t != NULL) && (t->w != target_w)) { if (t->m != newm) { @@ -913,35 +917,39 @@ void list_new_page(unsigned long *body) struct fpmonitor *fp; m = monitor_by_output(mon_num); + /* Don't allow monitor_by_output to fallback to RB_MIN. */ + if (m->si->rr_output != mon_num) + return; if (monitor_to_track != NULL && strcmp(m->si->name, monitor_to_track) != 0) return; if ((fp = fpmonitor_this(m)) == NULL) - fp = fpmonitor_new(m); + return; - fp->virtual_scr.Vx = body[0]; - fp->virtual_scr.Vy = body[1]; - if (fp->m->virtual_scr.CurrentDesk != body[2]) - { - /* first handle the new desk */ - body[0] = body[2]; - list_new_desk(body); - } - if (fp->virtual_scr.VxPages != body[5] || fp->virtual_scr.VyPages != body[6]) - { - fp->virtual_scr.VxPages = body[5]; - fp->virtual_scr.VyPages = body[6]; - fp->virtual_scr.VWidth = fp->virtual_scr.VxPages * monitor_get_all_widths(); - fp->virtual_scr.VHeight = fp->virtual_scr.VyPages * monitor_get_all_heights(); - fp->virtual_scr.VxMax = fp->virtual_scr.VWidth - monitor_get_all_widths(); - fp->virtual_scr.VyMax = fp->virtual_scr.VHeight - monitor_get_all_heights(); - ReConfigure(); - } - MovePage(False); - MoveStickyWindow(True, False); - Hilight(FocusWin,True); + fp->virtual_scr.Vx = body[0]; + fp->virtual_scr.Vy = body[1]; + if (fp->m->virtual_scr.CurrentDesk != body[2]) { + /* first handle the new desk */ + body[0] = body[2]; + body[1] = mon_num; + list_new_desk(body); + } + if (fp->virtual_scr.VxPages != body[5] || fp->virtual_scr.VyPages != body[6]) + { + fp->virtual_scr.VxPages = body[5]; + fp->virtual_scr.VyPages = body[6]; + fp->virtual_scr.VWidth = fp->virtual_scr.VxPages * fpmonitor_get_all_widths(); + fp->virtual_scr.VHeight = fp->virtual_scr.VyPages * fpmonitor_get_all_heights(); + fp->virtual_scr.VxMax = fp->virtual_scr.VWidth - fpmonitor_get_all_widths(); + fp->virtual_scr.VyMax = fp->virtual_scr.VHeight - fpmonitor_get_all_heights(); + ReConfigure(); + } + + MovePage(False); + MoveStickyWindow(True, False); + Hilight(FocusWin,True); } /* @@ -956,15 +964,26 @@ void list_new_desk(unsigned long *body) int change_cs = -1; int change_ballooncs = -1; int change_highcs = -1; + int mon_num = body[1]; struct monitor *mout; struct fpmonitor *fp; - mout = monitor_by_output((int)body[1]); + mout = monitor_by_output(mon_num); + /* Don't allow monitor_by_output to fallback to RB_MIN. */ + if (mout->si->rr_output != mon_num) + return; + fp = fpmonitor_this(mout); if (fp == NULL) return; + /* Best to update the desk, even if the monitor isn't being + * tracked, as this could change. + */ + oldDesk = fp->m->virtual_scr.CurrentDesk; + fp->m->virtual_scr.CurrentDesk = (long)body[0]; + /* If the monitor for which the event was sent, does not match the monitor * itself, then don't change the FvwmPager's desk. Only do this if we're * tracking a specific monitor though. @@ -972,8 +991,9 @@ void list_new_desk(unsigned long *body) if (monitor_to_track != NULL && fp->m != mout) return; - oldDesk = fp->m->virtual_scr.CurrentDesk; - fp->m->virtual_scr.CurrentDesk = (long)body[0]; + if (monitor_mode == MONITOR_TRACKING_G) + monitor_assign_virtual(fp->m); + if (fAlwaysCurrentDesk && oldDesk != fp->m->virtual_scr.CurrentDesk) { PagerWindow *t; @@ -1151,6 +1171,7 @@ void list_lower(unsigned long *body) { PagerWindow *t; Window target_w; + struct fpmonitor *m; target_w = body[0]; t = Start; @@ -1162,8 +1183,11 @@ void list_lower(unsigned long *body) { if(t->PagerView != None) XLowerWindow(dpy,t->PagerView); - if (HilightDesks && (t->desk - desk1>=0) && (t->desk - desk1desk - desk1].CPagerWin); + if (HilightDesks && (t->desk - desk1>=0) && (t->desk - desk1CPagerWin[t->desk - desk1]); + } + } XLowerWindow(dpy,t->IconView); } } @@ -1516,27 +1540,72 @@ void list_config_info(unsigned long *body) } DrawGrid(val, True, None, NULL); } else if (StrEquals(token, "Monitor")) { - char *mname; - struct monitor *tm; + int dx, dy, Vx, Vy, VxMax, VyMax, CurrentDesk; + int scr_width, scr_height; + int flags; + char *mname; + struct monitor *tm; struct fpmonitor *fp; tline = GetNextToken(tline, &mname); + sscanf(tline, "%d %d %d %d %d %d %d %d %d %d", &flags, + &dx, &dy, &Vx, &Vy, &VxMax, &VyMax, &CurrentDesk, + &scr_width, &scr_height); + + monitor_refresh_module(dpy); + tm = monitor_resolve_name(mname); + if (tm == NULL) + return; - if (tm == NULL) { - m = fxcalloc(1, sizeof(*m)); - m->m = tm; - /* XXX: FIXME: Update virtual_scr??? */ - TAILQ_INSERT_TAIL(&fp_monitor_q, m, entry); - } - fp = fpmonitor_this(tm); - if (fp == NULL) + if (flags & MONITOR_DISABLED) { + fp = fpmonitor_by_name(mname); + if (fp != NULL) { + bool disabled = fp->disabled; + fpmonitor_disable(fp); + if (!disabled) + ReConfigure(); + } return; - fp->virtual_scr.VWidth = fp->virtual_scr.VxPages * monitor_get_all_widths(); - fp->virtual_scr.VHeight = fp->virtual_scr.VyPages * monitor_get_all_heights(); - fp->virtual_scr.VxMax = fp->virtual_scr.VWidth - monitor_get_all_widths(); - fp->virtual_scr.VyMax = fp->virtual_scr.VHeight - monitor_get_all_heights(); + } + + if ((fp = fpmonitor_this(tm)) == NULL) { + if (fp_new_block) + return; + fp_new_block = True; + fp = fpmonitor_new(tm); + fp->m->flags |= MONITOR_NEW; + } + + fp->disabled = false; + fp->scr_width = scr_width; + fp->scr_height = scr_height; + fp->m->dx = dx; + fp->m->dy = dy; + fp->m->virtual_scr.Vx = fp->virtual_scr.Vx = Vx; + fp->m->virtual_scr.Vy = fp->virtual_scr.Vy = Vy; + fp->m->virtual_scr.VxMax = fp->virtual_scr.VxMax = VxMax; + fp->m->virtual_scr.VyMax = fp->virtual_scr.VyMax = VyMax; + fp->m->virtual_scr.CurrentDesk = CurrentDesk; + + fp->virtual_scr.VxMax = dx * fpmonitor_get_all_widths() - fpmonitor_get_all_widths(); + fp->virtual_scr.VyMax = dy * fpmonitor_get_all_heights() - fpmonitor_get_all_heights(); + if (fp->virtual_scr.VxMax < 0) + fp->virtual_scr.VxMax = 0; + if (fp->virtual_scr.VyMax < 0) + fp->virtual_scr.VyMax = 0; + fp->virtual_scr.VWidth = fp->virtual_scr.VxMax + fpmonitor_get_all_widths(); + fp->virtual_scr.VHeight = fp->virtual_scr.VyMax + fpmonitor_get_all_heights(); + fp->virtual_scr.VxPages = fp->virtual_scr.VWidth / fpmonitor_get_all_widths(); + fp->virtual_scr.VyPages = fp->virtual_scr.VHeight / fpmonitor_get_all_heights(); + + if (fp->m != NULL && fp->m->flags & MONITOR_NEW) { + fp->m->flags &= ~MONITOR_NEW; + initialize_fpmonitor_windows(fp); + fp_new_block = False; + } + ReConfigure(); } else if (StrEquals(token, "DesktopSize")) { int dx, dy; struct fpmonitor *m; @@ -1544,17 +1613,24 @@ void list_config_info(unsigned long *body) sscanf(tline, "%d %d", &dx, &dy); TAILQ_FOREACH(m, &fp_monitor_q, entry) { - m->virtual_scr.VxMax = dx * monitor_get_all_widths() - monitor_get_all_widths(); - m->virtual_scr.VyMax = dy * monitor_get_all_heights() - monitor_get_all_heights(); + m->virtual_scr.VxMax = dx * fpmonitor_get_all_widths() - fpmonitor_get_all_widths(); + m->virtual_scr.VyMax = dy * fpmonitor_get_all_heights() - fpmonitor_get_all_heights(); if (m->virtual_scr.VxMax < 0) m->virtual_scr.VxMax = 0; if (m->virtual_scr.VyMax < 0) m->virtual_scr.VyMax = 0; - m->virtual_scr.VWidth = m->virtual_scr.VxMax + monitor_get_all_widths(); - m->virtual_scr.VHeight = m->virtual_scr.VyMax + monitor_get_all_heights(); - m->virtual_scr.VxPages = m->virtual_scr.VWidth / monitor_get_all_widths(); - m->virtual_scr.VyPages = m->virtual_scr.VHeight / monitor_get_all_heights(); + m->virtual_scr.VWidth = m->virtual_scr.VxMax + fpmonitor_get_all_widths(); + m->virtual_scr.VHeight = m->virtual_scr.VyMax + fpmonitor_get_all_heights(); + m->virtual_scr.VxPages = m->virtual_scr.VWidth / fpmonitor_get_all_widths(); + m->virtual_scr.VyPages = m->virtual_scr.VHeight / fpmonitor_get_all_heights(); } + } else if (StrEquals(token, "DesktopConfiguration")) { + int mmode, is_shared; + + sscanf(tline, "%d %d", &mmode, &is_shared); + + if (mmode > 0) + monitor_mode = mmode; } } @@ -1826,25 +1902,6 @@ ImagePath = NULL; } continue; } - else if (StrEquals(token, "Monitor")) { - char *mname; - struct monitor *m; - struct fpmonitor *fp; - - next = GetNextToken(next, &mname); - - RB_FOREACH(m, monitors, &monitor_q) { - if ((fp = fpmonitor_this(m)) == NULL) - fp = fpmonitor_new(m); - fp->virtual_scr.Vx = m->virtual_scr.Vx; - fp->virtual_scr.Vy = m->virtual_scr.Vy; - fp->virtual_scr.VxMax = m->virtual_scr.VxMax; - fp->virtual_scr.VyMax = m->virtual_scr.VyMax; - fp->virtual_scr.VWidth = fp->virtual_scr.VxPages * monitor_get_all_widths(); - fp->virtual_scr.VHeight = fp->virtual_scr.VyPages * monitor_get_all_heights(); - } - continue; - } tline2 = GetModuleResource(tline, &resource, MyName); if (!resource) @@ -1883,6 +1940,14 @@ ImagePath = NULL; } fvwm_debug(__func__, "Assigning monitor: %s\n", m->m->si->name); monitor_to_track = fxstrdup(m->m->si->name); + } else if(StrEquals(resource, "DeskLabels")) { + use_desk_label = True; + } else if(StrEquals(resource, "NoDeskLabels")) { + use_desk_label = False; + } else if(StrEquals(resource, "MonitorLabels")) { + use_monitor_label = True; + } else if(StrEquals(resource, "NoMonitorLabels")) { + use_monitor_label = False; } else if(StrEquals(resource,"Colorset")) { @@ -1978,7 +2043,8 @@ ImagePath = NULL; CopyStringWithQuotes(&font_string, next); if(strncasecmp(font_string,"none",4) == 0) { - uselabel = 0; + use_desk_label = False; + use_monitor_label = False; free(font_string); font_string = NULL; } @@ -2362,16 +2428,16 @@ ImagePath = NULL; struct fpmonitor *m; TAILQ_FOREACH(m, &fp_monitor_q, entry) { - m->virtual_scr.VxMax = dx * monitor_get_all_widths() - monitor_get_all_widths(); - m->virtual_scr.VyMax = dy * monitor_get_all_heights() - monitor_get_all_heights(); + m->virtual_scr.VxMax = dx * fpmonitor_get_all_widths() - fpmonitor_get_all_widths(); + m->virtual_scr.VyMax = dy * fpmonitor_get_all_heights() - fpmonitor_get_all_heights(); if (m->virtual_scr.VxMax < 0) m->virtual_scr.VxMax = 0; if (m->virtual_scr.VyMax < 0) m->virtual_scr.VyMax = 0; - m->virtual_scr.VWidth = m->virtual_scr.VxMax + monitor_get_all_widths(); - m->virtual_scr.VHeight = m->virtual_scr.VyMax + monitor_get_all_heights(); - m->virtual_scr.VxPages = m->virtual_scr.VWidth / monitor_get_all_widths(); - m->virtual_scr.VyPages = m->virtual_scr.VHeight / monitor_get_all_heights(); + m->virtual_scr.VWidth = m->virtual_scr.VxMax + fpmonitor_get_all_widths(); + m->virtual_scr.VHeight = m->virtual_scr.VyMax + fpmonitor_get_all_heights(); + m->virtual_scr.VxPages = m->virtual_scr.VWidth / fpmonitor_get_all_widths(); + m->virtual_scr.VyPages = m->virtual_scr.VHeight / fpmonitor_get_all_heights(); fvwm_debug(__func__, "%s: VxMax: %d, VyMax: %d, VWidth: %d, Vheight: %d, " @@ -2419,8 +2485,9 @@ void ExitPager(void) struct fpmonitor *fp, *fp1; TAILQ_FOREACH_SAFE(fp, &fp_monitor_q, entry, fp1) { - TAILQ_REMOVE(&fp_monitor_q, fp, entry); - free(fp); + TAILQ_REMOVE(&fp_monitor_q, fp, entry); + free(fp->CPagerWin); + free(fp); } if (is_transient) @@ -2431,4 +2498,4 @@ void ExitPager(void) } XUngrabKeyboard(dpy, CurrentTime); exit(0); -} \ No newline at end of file +} diff --git a/modules/FvwmPager/FvwmPager.h b/modules/FvwmPager/FvwmPager.h index 22f1a7bcc..5d3b89930 100644 --- a/modules/FvwmPager/FvwmPager.h +++ b/modules/FvwmPager/FvwmPager.h @@ -16,6 +16,8 @@ struct fpmonitor { struct monitor *m; + Window *CPagerWin; + struct { int VxMax; int VyMax; @@ -27,6 +29,9 @@ struct fpmonitor { int VHeight; } virtual_scr; + int scr_width; /* Size of DisplayWidth() */ + int scr_height; /* Size of DisplayHeight() */ + bool disabled; TAILQ_ENTRY(fpmonitor) entry; }; TAILQ_HEAD(fpmonitors, fpmonitor); @@ -103,14 +108,8 @@ typedef struct pager_window char *res_class; char *window_label; /* This is displayed inside the mini window */ FvwmPicture mini_icon; - int pager_view_x; - int pager_view_y; - int pager_view_width; - int pager_view_height; - int icon_view_x; - int icon_view_y; - int icon_view_width; - int icon_view_height; + rectangle pager_view; + rectangle icon_view; Window PagerView; Window IconView; @@ -129,7 +128,6 @@ typedef struct desk_info { Window w; Window title_w; - Window CPagerWin; FvwmPicture *bgPixmap; /* Pixmap used as background. */ BalloonWindow balloon; int colorset; @@ -138,9 +136,11 @@ typedef struct desk_info char *Dcolor; char *label; GC NormalGC; - GC DashedGC; /* used the the pages boundary lines */ + GC DashedGC; /* used for the pages boundary lines */ GC HiliteGC; /* used for hilighting the active desk */ GC rvGC; /* used for drawing hilighted desk title */ + unsigned long fp_mask; /* used for the fpmonitor window */ + XSetWindowAttributes fp_attr; /* used for the fpmonitor window */ } DeskInfo; typedef struct pager_string_list @@ -191,7 +191,9 @@ int My_XNextEvent(Display *dpy, XEvent *event); /* Stuff in x_pager.c */ void change_colorset(int colorset); +void initialise_common_pager_fragments(void); void initialize_pager(void); +void initialize_fpmonitor_windows(struct fpmonitor *); void initialize_viz_pager(void); Pixel GetColor(char *name); void DispatchEvent(XEvent *Event); @@ -201,7 +203,7 @@ void update_pr_transparent_windows(void); void MovePage(Bool is_new_desk); void DrawGrid(int desk,int erase,Window ew,XRectangle *r); void DrawIconGrid(int erase); -void SwitchToDesk(int Desk); +void SwitchToDesk(int Desk, struct fpmonitor *m); void SwitchToDeskAndPage(int Desk, XEvent *Event); void AddNewWindow(PagerWindow *prev); void MoveResizePagerView(PagerWindow *t, Bool do_force_redraw); @@ -225,5 +227,7 @@ void MapBalloonWindow(PagerWindow *t, Bool is_icon_view); void UnmapBalloonWindow(void); void DrawInBalloonWindow(int i); void HandleScrollDone(void); +int fpmonitor_get_all_widths(void); +int fpmonitor_get_all_heights(void); -#endif /* FVWMPAGER_H */ \ No newline at end of file +#endif /* FVWMPAGER_H */ diff --git a/modules/FvwmPager/x_pager.c b/modules/FvwmPager/x_pager.c index 58e291a8e..75feb0eef 100644 --- a/modules/FvwmPager/x_pager.c +++ b/modules/FvwmPager/x_pager.c @@ -52,7 +52,8 @@ extern int windowcolorset, activecolorset; extern Pixel win_back_pix, win_fore_pix, win_hi_back_pix, win_hi_fore_pix; extern Bool win_pix_set, win_hi_pix_set; extern rectangle pwindow; -extern int usposition,uselabel,xneg,yneg; +extern int usposition, xneg, yneg; +extern bool use_desk_label, use_monitor_label; extern int StartIconic; extern int MiniIcons; extern int LabelsBelow; @@ -122,11 +123,17 @@ static char s_g_bits[] = {0x01, 0x02, 0x04, 0x08}; Window icon_win; /* icon window */ static int MyVx, MyVy; /* copy of Scr.Vx/y for drag logic */ +static struct fpmonitor *ScrollFp = NULL; /* Stash monitor drag logic */ static rectangle CalcGeom(PagerWindow *, bool); -static rectangle set_vp_size_and_loc(void); -static void fvwmrec_to_pager(rectangle *, bool); -static void pagerrec_to_fvwm(rectangle *, bool); +static rectangle set_vp_size_and_loc(struct fpmonitor *, bool is_icon); +static struct fpmonitor *fpmonitor_from_xy(int x, int y); +static struct fpmonitor *fpmonitor_from_n(int n); +static struct fpmonitor *fpmonitor_from_desk(int desk); +static int fpmonitor_count(void); +static void set_desk_size(bool); +static void fvwmrec_to_pager(rectangle *, bool, struct fpmonitor *); +static void pagerrec_to_fvwm(rectangle *, bool, struct fpmonitor *); static char *GetBalloonLabel(const PagerWindow *pw,const char *fmt); extern void ExitPager(void); @@ -160,8 +167,13 @@ static void do_scroll(int sx, int sy, Bool do_send_message, ( psx != 0 || psy != 0 )) { if (monitor_to_track != NULL) - snprintf(screen, sizeof(screen), "screen %s", monitor_to_track); - snprintf(command, sizeof(command), "Scroll %s %dp %dp", screen, psx, psy); + snprintf(screen, sizeof(screen), "screen %s", + monitor_to_track); + else if (ScrollFp != NULL) + snprintf(screen, sizeof(screen), "screen %s", + ScrollFp->m->si->name); + snprintf(command, sizeof(command), "Scroll %s %dp %dp", + screen, psx, psy); SendText(fd, command, 0); messages_sent++; SendText(fd, "Send_Reply ScrollDone", 0); @@ -173,6 +185,7 @@ static void do_scroll(int sx, int sy, Bool do_send_message, void HandleScrollDone(void) { do_scroll(0, 0, True, True); + ScrollFp = NULL; } typedef struct @@ -212,24 +225,110 @@ static void discard_events(long event_type, Window w, XEvent *last_ev) return; } +int fpmonitor_get_all_widths(void) +{ + struct fpmonitor *fp = TAILQ_FIRST(&fp_monitor_q); + + if (fp->scr_width <= 0) + return (monitor_get_all_widths()); + + return (fp->scr_width); +} + +int fpmonitor_get_all_heights(void) +{ + struct fpmonitor *fp = TAILQ_FIRST(&fp_monitor_q); + + if (fp->scr_height <= 0) + return (monitor_get_all_heights()); + return (fp->scr_height); +} + +int fpmonitor_count(void) +{ + struct fpmonitor *fp; + int c = 0; + + TAILQ_FOREACH(fp, &fp_monitor_q, entry) + if (!fp->disabled) + c++; + return (c); +} + +static struct fpmonitor *fpmonitor_from_n(int n) +{ + struct fpmonitor *fp; + int c = 0; + + TAILQ_FOREACH(fp, &fp_monitor_q, entry) { + if (fp->disabled) + continue; + if (c == n) + return fp; + c++; + } + return fp; +} + +static struct fpmonitor *fpmonitor_from_desk(int desk) +{ + struct fpmonitor *fp; + + TAILQ_FOREACH(fp, &fp_monitor_q, entry) + if (!fp->disabled && fp->m->virtual_scr.CurrentDesk == desk) + return fp; + + return NULL; +} + +static struct fpmonitor *fpmonitor_from_xy(int x, int y) +{ + struct fpmonitor *fp; + + if (monitor_to_track == NULL && monitor_mode != MONITOR_TRACKING_G) { + x %= fpmonitor_get_all_widths(); + y %= fpmonitor_get_all_heights(); + + TAILQ_FOREACH(fp, &fp_monitor_q, entry) + if (x >= fp->m->si->x && + x < fp->m->si->x + fp->m->si->w && + y >= fp->m->si->y && + y < fp->m->si->y + fp->m->si->h) + return fp; + } else { + return fpmonitor_this(NULL); + } + + return NULL; +} + static rectangle CalcGeom(PagerWindow *t, bool is_icon) { - rectangle rec = {0,0,0,0}; + /* Place initial rectangle off screen. */ + rectangle rec = {-32768, -32768, 0, 0}; struct fpmonitor *fp = fpmonitor_this(NULL); + /* If the monitor we expect to find is disabled, then + * fpmonitor_this() will return NULL. + */ if (fp == NULL) - return (rec); + return rec; /* Only track windows on the appropriate monitor if per-monitor mode. */ if (monitor_to_track != NULL && t->m != fp->m) return rec; + else + fp = fpmonitor_this(t->m); + + if (fp == NULL) + return rec; rec.x = fp->virtual_scr.Vx + t->x; rec.y = fp->virtual_scr.Vy + t->y; rec.width = t->width; rec.height = t->height; - fvwmrec_to_pager(&rec, is_icon); + fvwmrec_to_pager(&rec, is_icon, fp); /* Set geometry to MinSize and snap to page boundary if needed */ if (rec.width < MinSize) @@ -314,8 +413,24 @@ void initialize_viz_pager(void) return; } +void set_desk_size(bool update_label) +{ + if (update_label) { + label_h = 0; + if (use_desk_label) + label_h += Ffont->height + 2; + if (use_monitor_label) + label_h += Ffont->height + 2; + } + + desk_w = (pwindow.width - Columns + 1) / Columns; + desk_h = (pwindow.height - Rows * label_h - Rows + 1) / Rows; + + return; +} + /* see also change colorset */ -void draw_desk_background(int i, int page_w, int page_h) +void draw_desk_background(int i, int page_w, int page_h, struct fpmonitor *fp) { if (Desks[i].colorset > -1) { @@ -327,7 +442,7 @@ void draw_desk_background(int i, int page_w, int page_h) dpy, Desks[i].NormalGC,Colorset[Desks[i].colorset].fg); XSetForeground( dpy, Desks[i].DashedGC,Colorset[Desks[i].colorset].fg); - if (uselabel) + if (label_h > 0) { if (CSET_IS_TRANSPARENT(Desks[i].colorset)) { @@ -347,7 +462,7 @@ void draw_desk_background(int i, int page_w, int page_h) Scr.NormalGC, True); } } - if (label_h != 0 && uselabel && !LabelsBelow && + if (label_h > 0 && !LabelsBelow && !CSET_IS_TRANSPARENT(Desks[i].colorset)) { SetWindowBackgroundWithOffset( @@ -385,12 +500,12 @@ void draw_desk_background(int i, int page_w, int page_h) if (HilightDesks) { SetWindowBackground( - dpy, Desks[i].CPagerWin, page_w, page_h, - &Colorset[Desks[i].highcolorset], Pdepth, - Scr.NormalGC, True); + dpy, fp->CPagerWin[i], page_w, page_h, + &Colorset[Desks[i].highcolorset], + Pdepth, Scr.NormalGC, True); } } - if (uselabel) + if (label_h > 0) { XClearArea(dpy,Desks[i].title_w, 0, 0, 0, 0,True); } @@ -452,15 +567,13 @@ void initialize_balloon_window(void) /* Computes pager size rectangle from fvwm size or visa versa */ static void -fvwmrec_to_pager(rectangle *rec, bool is_icon) +fvwmrec_to_pager(rectangle *rec, bool is_icon, struct fpmonitor *fp) { - struct fpmonitor *fp = fpmonitor_this(NULL); - if (fp == NULL) return; - int m_width = monitor_get_all_widths(); - int m_height = monitor_get_all_heights(); + int m_width = fpmonitor_get_all_widths(); + int m_height = fpmonitor_get_all_heights(); if (monitor_to_track != NULL) { /* Offset window location based on monitor location. */ @@ -490,15 +603,13 @@ fvwmrec_to_pager(rectangle *rec, bool is_icon) rec->height -= rec->y; } static void -pagerrec_to_fvwm(rectangle *rec, bool is_icon) +pagerrec_to_fvwm(rectangle *rec, bool is_icon, struct fpmonitor *fp) { - struct fpmonitor *fp = fpmonitor_this(NULL); - if (fp == NULL) return; - int m_width = monitor_get_all_widths(); - int m_height = monitor_get_all_heights(); + int m_width = fpmonitor_get_all_widths(); + int m_height = fpmonitor_get_all_heights(); int offset_x = 0, offset_y = 0; int scale_w = desk_w, scale_h = desk_h; @@ -525,165 +636,187 @@ pagerrec_to_fvwm(rectangle *rec, bool is_icon) } static rectangle -set_vp_size_and_loc(void) +set_vp_size_and_loc(struct fpmonitor *m, bool is_icon) { - rectangle vp; - struct fpmonitor *fp = fpmonitor_this(NULL); + int Vx = 0, Vy = 0, vp_w, vp_h; + rectangle vp = {0, 0, 0, 0}; + struct fpmonitor *fp = (m != NULL) ? m : fpmonitor_this(NULL); + int scale_w = desk_w, scale_h = desk_h; + if (is_icon) { + scale_w = icon.width; + scale_h = icon.height; + } + + Vx = fp->virtual_scr.Vx; + Vy = fp->virtual_scr.Vy; + vp_w = fp->virtual_scr.VWidth / fp->virtual_scr.VxPages; + vp_h = fp->virtual_scr.VHeight / fp->virtual_scr.VyPages; + if (m != NULL && monitor_to_track == NULL) { + Vx += fp->m->si->x; + Vy += fp->m->si->y; + vp_w = fp->m->si->w; + vp_h = fp->m->si->h; + } - vp.x = (fp->virtual_scr.Vx * desk_w) / - fp->virtual_scr.VWidth; - vp.y = (fp->virtual_scr.Vy * desk_h) / - fp->virtual_scr.VHeight; - vp.width = ((fp->virtual_scr.Vx + fp->virtual_scr.VWidth / - fp->virtual_scr.VxPages) * desk_w) / - fp->virtual_scr.VWidth - vp.x; - vp.height = ((fp->virtual_scr.Vy + fp->virtual_scr.VHeight / - fp->virtual_scr.VyPages) * desk_h) / - fp->virtual_scr.VHeight - vp.y; + vp.x = (Vx * scale_w) / fp->virtual_scr.VWidth; + vp.y = (Vy * scale_h) / fp->virtual_scr.VHeight; + vp.width = (Vx + vp_w) * scale_w / fp->virtual_scr.VWidth - vp.x; + vp.height = (Vy + vp_h) * scale_h / fp->virtual_scr.VHeight - vp.y; return vp; } -void initialize_pager(void) +void initialise_common_pager_fragments(void) { - XWMHints wmhints; - XClassHint class1; - XTextProperty name; - unsigned long valuemask; - XSetWindowAttributes attributes; - extern char *WindowBack, *WindowFore, *WindowHiBack, *WindowHiFore; - extern char *BalloonFont; - extern char *font_string, *smallFont; - rectangle vp; - int i = 0; - XGCValues gcv; - char dash_list[2]; - FlocaleFont *balloon_font; - struct fpmonitor *fp = fpmonitor_this(NULL); + extern char *WindowBack, *WindowFore, *WindowHiBack, *WindowHiFore; + extern char *font_string, *smallFont; - if (fp == NULL) - return; + /* I don't think that this is necessary - just let pager die */ + /* domivogt (07-mar-1999): But it is! A window being moved in the pager + * might die at any moment causing the Xlib calls to generate BadMatch + * errors. Without an error handler the pager will die! */ + XSetErrorHandler(FvwmErrorHandler); - int VxPages = fp->virtual_scr.VxPages, VyPages = fp->virtual_scr.VyPages; + wm_del_win = XInternAtom(dpy,"WM_DELETE_WINDOW",False); - /* I don't think that this is necessary - just let pager die */ - /* domivogt (07-mar-1999): But it is! A window being moved in the pager - * might die at any moment causing the Xlib calls to generate BadMatch - * errors. Without an error handler the pager will die! */ - XSetErrorHandler(FvwmErrorHandler); + /* load the font */ + /* Note: "font" is always created, whether labels are used or not + because a GC below is set to use a font. dje Dec 2001. + OK, I fixed the GC below, but now something else is blowing up. + Right now, I've got to do some Real Life stuff, so this kludge is + in place, its still better than I found it. + I hope that I've fixed this (olicha) + */ + Ffont = FlocaleLoadFont(dpy, font_string, MyName); - wm_del_win = XInternAtom(dpy,"WM_DELETE_WINDOW",False); + /* init our Flocale window string */ + FlocaleAllocateWinString(&FwinString); - /* load the font */ - /* Note: "font" is always created, whether labels are used or not - because a GC below is set to use a font. dje Dec 2001. - OK, I fixed the GC below, but now something else is blowing up. - Right now, I've got to do some Real Life stuff, so this kludge is - in place, its still better than I found it. - I hope that I've fixed this (olicha) - */ - Ffont = FlocaleLoadFont(dpy, font_string, MyName); + /* Check that shape extension exists. */ + if (FHaveShapeExtension && ShapeLabels) + { + ShapeLabels = (FShapesSupported) ? 1 : 0; + } - label_h = (uselabel) ? Ffont->height + 2 : 0; + if(smallFont != NULL) + { + FwindowFont = FlocaleLoadFont(dpy, smallFont, MyName); + } - /* init our Flocale window string */ - FlocaleAllocateWinString(&FwinString); + /* Load the colors */ + fore_pix = GetColor(PagerFore); + back_pix = GetColor(PagerBack); + hi_pix = GetColor(HilightC); - /* Check that shape extension exists. */ - if (FHaveShapeExtension && ShapeLabels) - { - ShapeLabels = (FShapesSupported) ? 1 : 0; - } + if (windowcolorset >= 0) + { + win_back_pix = Colorset[windowcolorset].bg; + win_fore_pix = Colorset[windowcolorset].fg; + win_pix_set = True; + } + else if (WindowBack && WindowFore) + { + win_back_pix = GetColor(WindowBack); + win_fore_pix = GetColor(WindowFore); + win_pix_set = True; + } - if(smallFont != NULL) - { - FwindowFont = FlocaleLoadFont(dpy, smallFont, MyName); - } + if (activecolorset >= 0) + { + win_hi_back_pix = Colorset[activecolorset].bg; + win_hi_fore_pix = Colorset[activecolorset].fg; + win_hi_pix_set = True; + } + else if (WindowHiBack && WindowHiFore) + { + win_hi_back_pix = GetColor(WindowHiBack); + win_hi_fore_pix = GetColor(WindowHiFore); + win_hi_pix_set = True; + } - /* Load the colors */ - fore_pix = GetColor(PagerFore); - back_pix = GetColor(PagerBack); - hi_pix = GetColor(HilightC); + /* Load pixmaps for mono use */ + if(Pdepth<2) + { + Scr.gray_pixmap = XCreatePixmapFromBitmapData(dpy, Scr.Pager_w, + g_bits, g_width,g_height, fore_pix,back_pix,Pdepth); + Scr.light_gray_pixmap = XCreatePixmapFromBitmapData(dpy, + Scr.Pager_w,l_g_bits,l_g_width, l_g_height, + fore_pix,back_pix,Pdepth); + Scr.sticky_gray_pixmap = XCreatePixmapFromBitmapData(dpy, + Scr.Pager_w,s_g_bits,s_g_width, s_g_height, + fore_pix,back_pix,Pdepth); + } - if (windowcolorset >= 0) - { - win_back_pix = Colorset[windowcolorset].bg; - win_fore_pix = Colorset[windowcolorset].fg; - win_pix_set = True; - } - else if (WindowBack && WindowFore) - { - win_back_pix = GetColor(WindowBack); - win_fore_pix = GetColor(WindowFore); - win_pix_set = True; - } + /* Size the window */ + if(Rows < 0) + { + if(Columns <= 0) + { + Columns = ndesks; + Rows = 1; + } + else + { + Rows = ndesks/Columns; + if(Rows*Columns < ndesks) + Rows++; + } + } + if(Columns < 0) + { + if (Rows == 0) + Rows = 1; + Columns = ndesks/Rows; + if(Rows*Columns < ndesks) + Columns++; + } - if (activecolorset >= 0) - { - win_hi_back_pix = Colorset[activecolorset].bg; - win_hi_fore_pix = Colorset[activecolorset].fg; - win_hi_pix_set = True; - } - else if (WindowHiBack && WindowHiFore) - { - win_hi_back_pix = GetColor(WindowHiBack); - win_hi_fore_pix = GetColor(WindowHiFore); - win_hi_pix_set = True; - } + if(Rows*Columns < ndesks) + { + if (Columns == 0) + Columns = 1; + Rows = ndesks/Columns; + if (Rows*Columns < ndesks) + Rows++; + } + set_desk_size(true); +} - /* Load pixmaps for mono use */ - if(Pdepth<2) - { - Scr.gray_pixmap = - XCreatePixmapFromBitmapData(dpy,Scr.Pager_w,g_bits, g_width,g_height, - fore_pix,back_pix,Pdepth); - Scr.light_gray_pixmap = - XCreatePixmapFromBitmapData(dpy,Scr.Pager_w,l_g_bits,l_g_width, - l_g_height, - fore_pix,back_pix,Pdepth); - Scr.sticky_gray_pixmap = - XCreatePixmapFromBitmapData(dpy,Scr.Pager_w,s_g_bits,s_g_width, - s_g_height, - fore_pix,back_pix,Pdepth); - } +void initialize_fpmonitor_windows(struct fpmonitor *fp) +{ + rectangle vp = set_vp_size_and_loc(fp, false); + for (int i = 0; i < ndesks; i++) { + fp->CPagerWin[i] = XCreateWindow(dpy, Desks[i].w, + -32768, -32768, vp.width, vp.height, 0, + CopyFromParent, InputOutput, + CopyFromParent, Desks[i].fp_mask, + &Desks[i].fp_attr); + draw_desk_background(i, vp.width, vp.height, fp); + XMapRaised(dpy, fp->CPagerWin[i]); + } +} - /* Size the window */ - if(Rows < 0) - { - if(Columns <= 0) - { - Columns = ndesks; - Rows = 1; - } - else - { - Rows = ndesks/Columns; - if(Rows*Columns < ndesks) - Rows++; - } - } - if(Columns < 0) - { - if (Rows == 0) - Rows = 1; - Columns = ndesks/Rows; - if(Rows*Columns < ndesks) - Columns++; - } +void initialize_pager(void) +{ + XWMHints wmhints; + XClassHint class1; + XTextProperty name; + unsigned long valuemask; + XSetWindowAttributes attributes; + int i = 0; + XGCValues gcv; + extern char *BalloonFont; + char dash_list[2]; + FlocaleFont *balloon_font; + struct fpmonitor *fp = fpmonitor_this(NULL); + struct fpmonitor *m; - if(Rows*Columns < ndesks) - { - if (Columns == 0) - Columns = 1; - Rows = ndesks/Columns; - if (Rows*Columns < ndesks) - Rows++; - } + int VxPages = fp->virtual_scr.VxPages, VyPages = fp->virtual_scr.VyPages; /* Set window size if not fully set by user to match */ /* aspect ratio of monitor(s) being shown. */ if ( pwindow.width == 0 || pwindow.height == 0 ) { - int vWidth = monitor_get_all_widths(); - int vHeight = monitor_get_all_heights(); + int vWidth = fpmonitor_get_all_widths(); + int vHeight = fpmonitor_get_all_heights(); if (monitor_to_track != NULL) { vWidth = fp->m->si->w; vHeight = fp->m->si->h; @@ -702,8 +835,7 @@ void initialize_pager(void) label_h * Rows + Rows; } } - desk_w = (pwindow.width - Columns + 1) / Columns; - desk_h = (pwindow.height - Rows * label_h - Rows + 1) / Rows; + set_desk_size(false); if (is_transient) { @@ -731,11 +863,11 @@ void initialize_pager(void) if (xneg) { sizehints.win_gravity = NorthEastGravity; - pwindow.x = monitor_get_all_widths() - pwindow.width + pwindow.x; + pwindow.x = fpmonitor_get_all_widths() - pwindow.width + pwindow.x; } if (yneg) { - pwindow.y = monitor_get_all_heights() - pwindow.height + pwindow.y; + pwindow.y = fpmonitor_get_all_heights() - pwindow.height + pwindow.y; if(sizehints.win_gravity == NorthEastGravity) sizehints.win_gravity = SouthEastGravity; else @@ -818,11 +950,11 @@ void initialize_pager(void) if (icon.x != -10000) { if (icon_xneg) - icon.x = monitor_get_all_widths() + icon.x - icon.width; + icon.x = fpmonitor_get_all_widths() + icon.x - icon.width; if (icon.y != -10000) { if (icon_yneg) - icon.y = monitor_get_all_heights() + icon.y - icon.height; + icon.y = fpmonitor_get_all_heights() + icon.y - icon.height; } else { @@ -867,13 +999,12 @@ void initialize_pager(void) balloon_font = FlocaleLoadFont(dpy, BalloonFont, MyName); - vp = set_vp_size_and_loc(); for(i=0;ifont) { + if (label_h > 0 && Ffont && Ffont->font) { gcv.font = Ffont->font->fid; Desks[i].NormalGC = fvwmlib_XCreateGC(dpy, Scr.Pager_w, GCForeground | GCFont, &gcv); @@ -897,7 +1028,7 @@ void initialize_pager(void) gcv.foreground = (Desks[i].highcolorset < 0) ? fore_pix : Colorset[Desks[i].highcolorset].fg; - if (uselabel && Ffont && Ffont->font) { + if (label_h > 0 && Ffont && Ffont->font) { Desks[i].rvGC = fvwmlib_XCreateGC(dpy, Scr.Pager_w, GCForeground | GCFont, &gcv); } else { @@ -940,16 +1071,12 @@ void initialize_pager(void) : Colorset[Desks[i].colorset].fg; attributes.event_mask = (ExposureMask | ButtonReleaseMask); Desks[i].title_w = XCreateWindow( - dpy, Scr.Pager_w, vp.x - 1, vp.y - 1, vp.width, vp.height, 1, + dpy, Scr.Pager_w, -1, -1, desk_w, desk_h + label_h, 1, CopyFromParent, InputOutput, CopyFromParent, valuemask, &attributes); attributes.event_mask = (ExposureMask | ButtonReleaseMask | ButtonPressMask |ButtonMotionMask); - /* or just: desk_h = h - label_h; */ - desk_h = (pwindow.height - Rows * label_h - Rows + 1) / Rows; valuemask &= ~(CWBackPixel); - - if (Desks[i].colorset > -1 && Colorset[Desks[i].colorset].pixmap) { @@ -979,8 +1106,8 @@ void initialize_pager(void) } Desks[i].w = XCreateWindow( - dpy, Desks[i].title_w, vp.x - 1, LabelsBelow ? -1 : label_h - 1, - vp.width, desk_h, 1, CopyFromParent, InputOutput, CopyFromParent, + dpy, Desks[i].title_w, -1, LabelsBelow ? -1 : label_h - 1, + desk_w, desk_h, 1, CopyFromParent, InputOutput, CopyFromParent, valuemask, &attributes); if (HilightDesks) @@ -1006,19 +1133,14 @@ void initialize_pager(void) attributes.background_pixel = (Desks[i].highcolorset < 0) ? hi_pix : Colorset[Desks[i].highcolorset].bg; } - - Desks[i].CPagerWin=XCreateWindow(dpy, Desks[i].w, -32768, -32768, - vp.width, vp.height, 0, - CopyFromParent, InputOutput, - CopyFromParent, valuemask, &attributes); - draw_desk_background(i, vp.width, vp.height); - XMapRaised(dpy,Desks[i].CPagerWin); } else { - draw_desk_background(i, 0, 0); + draw_desk_background(i, 0, 0, fp); } + Desks[i].fp_mask = valuemask; + Desks[i].fp_attr = attributes; XMapRaised(dpy,Desks[i].w); XMapRaised(dpy,Desks[i].title_w); @@ -1026,6 +1148,10 @@ void initialize_pager(void) Desks[i].balloon.Ffont = balloon_font; Desks[i].balloon.height = Desks[i].balloon.Ffont->height + 1; } + + TAILQ_FOREACH(m, &fp_monitor_q, entry) { + initialize_fpmonitor_windows(m); + } initialize_balloon_window(); XMapRaised(dpy,Scr.Pager_w); } @@ -1039,7 +1165,7 @@ void UpdateWindowShape(void) XRectangle *shape; struct fpmonitor *fp = fpmonitor_this(NULL); - if (!fp || !ShapeLabels || !uselabel || label_h<=0) + if (!fp || !ShapeLabels || label_h == 0) return; shape_count = @@ -1197,16 +1323,52 @@ void DispatchEvent(XEvent *Event) } /* Flush any pending scroll operations */ do_scroll(0, 0, True, False); + ScrollFp = NULL; } else if((Event->xbutton.button == 1)|| (Event->xbutton.button == 2)) { + /* Location of monitor labels. */ + int m_count = fpmonitor_count(); + int ymin = 0, ymax = label_h; + if (use_desk_label) + ymin = ymax / 2; + if (LabelsBelow) { + ymin += desk_h; + ymax += desk_h; + } + for(i=0;ixany.window == Desks[i].w) - SwitchToDeskAndPage(i,Event); - else if(Event->xany.window == Desks[i].title_w) - SwitchToDesk(i); + if (Event->xany.window == Desks[i].w) + { + SwitchToDeskAndPage(i, Event); + break; + } + /* Check for clicks on monitor labels first, since these clicks + * always indicate what monitor to switch to in all modes. + */ + else if (use_monitor_label && monitor_to_track == NULL && + Event->xany.window == Desks[i].title_w && + Event->xbutton.y >= ymin && Event->xbutton.y <= ymax) + { + struct fpmonitor *fp2 = fpmonitor_from_n( + m_count * Event->xbutton.x / desk_w); + SwitchToDesk(i, fp2); + break; + } + /* Title clicks only change desk in global configuration, or when the + * pager is being asked to track a specific monitor. Or, regardless + * of the DesktopConfiguration setting, there is only one monitor in + * use. + */ + else if(Event->xany.window == Desks[i].title_w && + ((monitor_mode == MONITOR_TRACKING_G && !is_tracking_shared) || + (monitor_to_track != NULL) || (m_count == 1))) + { + SwitchToDesk(i, NULL); + break; + } } if(Event->xany.window == icon_win) { @@ -1232,9 +1394,6 @@ void DispatchEvent(XEvent *Event) } else if (Event->xbutton.button == 3) { - /* save initial virtual desk position for drag */ - MyVx=fp->virtual_scr.Vx; - MyVy=fp->virtual_scr.Vy; for(i=0;ixany.window == Desks[i].w) @@ -1244,11 +1403,23 @@ void DispatchEvent(XEvent *Event) { /* pointer is on a different screen - that's okay here */ } + if (monitor_mode == MONITOR_TRACKING_G && is_tracking_shared) + fp = fpmonitor_from_desk(i + desk1); + else + fp = fpmonitor_from_xy(x * fp->virtual_scr.VWidth / desk_w, + y * fp->virtual_scr.VHeight / desk_h); + + if (fp == NULL) + break; + /* Save initial virtual desk info. */ + ScrollFp = fp; + MyVx = fp->virtual_scr.Vx; + MyVy = fp->virtual_scr.Vy; Scroll(x, y, fp->m->virtual_scr.CurrentDesk, False); if (fp->m->virtual_scr.CurrentDesk != i + desk1) { Wait = 0; - SwitchToDesk(i); + SwitchToDesk(i, fp); } break; } @@ -1260,6 +1431,24 @@ void DispatchEvent(XEvent *Event) { /* pointer is on a different screen - that's okay here */ } + struct fpmonitor *fp2 = fpmonitor_this(NULL); + if (monitor_mode == MONITOR_TRACKING_G && is_tracking_shared) + fp = fp2; + else { + fp = fpmonitor_from_xy( + x * fp->virtual_scr.VWidth / icon.width, + y * fp->virtual_scr.VHeight / icon.height); + /* Make sure monitor is on current desk. */ + if (fp->m->virtual_scr.CurrentDesk != + fp2->m->virtual_scr.CurrentDesk) + break; + } + if (fp == NULL) + break; + /* Save initial virtual desk info. */ + ScrollFp = fp; + MyVx = fp->virtual_scr.Vx; + MyVy = fp->virtual_scr.Vy; Scroll(x, y, -1, True); } } @@ -1348,6 +1537,16 @@ void HandleEnterNotify(XEvent *Event) } +#if 0 +/* JS This code was getting in my way, and I'm not quite sure what + * it was doing. I believe it was meant to just redraw part of the + * desk label exposed, but with the addition of monitor labels, the + * logic is a bit more complicated. Just redraw the whole label since + * the rest of the grid is being redrawn anyways. This simplifies things + * drastically, and this optimization might not have noticeable gain. + * If this functionality is added back, DrawGrid needs to be correctly + * updated to deal with the bound logic. + */ XRectangle get_expose_bound(XEvent *Event) { XRectangle r; @@ -1370,12 +1569,12 @@ XRectangle get_expose_bound(XEvent *Event) r.height = ey2-ey; return r; } +#endif void HandleExpose(XEvent *Event) { int i; PagerWindow *t; - XRectangle r; /* it will be good to have full "clipping redraw". Do that for * desk label only for now */ @@ -1385,8 +1584,9 @@ void HandleExpose(XEvent *Event) if (Event->xany.window == Desks[i].w || Event->xany.window == Desks[i].title_w) { - r = get_expose_bound(Event); - DrawGrid(i, 0, Event->xany.window, &r); + //XRectangle r = get_expose_bound(Event); + //DrawGrid(i, 0, Event->xany.window, &r); + DrawGrid(i, 0, Event->xany.window, NULL); return; } } @@ -1429,6 +1629,7 @@ void ReConfigure(void) rectangle vp = {0, 0, 0, 0}; int i = 0, j = 0, k = 0; struct fpmonitor *fp = fpmonitor_this(NULL); + struct fpmonitor *m; if (fp == NULL) return; @@ -1438,9 +1639,7 @@ void ReConfigure(void) { return; } - desk_w = (pwindow.width - Columns + 1) / Columns; - desk_h = (pwindow.height - Rows * label_h - Rows + 1) / Rows; - vp = set_vp_size_and_loc(); + set_desk_size(false); for(k=0;km->virtual_scr.CurrentDesk - desk1) - XMoveResizeWindow(dpy, Desks[i].CPagerWin, + TAILQ_FOREACH(m, &fp_monitor_q, entry) { + if (m->disabled) + continue; + vp = set_vp_size_and_loc(m, false); + if (i == m->m->virtual_scr.CurrentDesk - desk1 && + (monitor_to_track == NULL || + strcmp(m->m->si->name, monitor_to_track) == 0)) + { + XMoveResizeWindow(dpy, m->CPagerWin[i], vp.x, vp.y, vp.width, vp.height); - else - XMoveResizeWindow(dpy, Desks[i].CPagerWin, + } else { + XMoveResizeWindow(dpy, m->CPagerWin[i], -32768, -32768, vp.width, vp.height); + } + draw_desk_background(i, vp.width, vp.height, m); + } + } else { + vp = set_vp_size_and_loc(NULL, false); + draw_desk_background(i, vp.width, vp.height, fp); } - draw_desk_background(i, vp.width, vp.height); } } } @@ -1491,15 +1702,17 @@ void update_pr_transparent_subwindows(int i) int cset; rectangle vp; PagerWindow *t; - - vp = set_vp_size_and_loc(); + struct fpmonitor *m; if (CSET_IS_TRANSPARENT_PR(Desks[i].highcolorset) && HilightDesks) { - SetWindowBackground( - dpy, Desks[i].CPagerWin, vp.width, vp.height, - &Colorset[Desks[i].highcolorset], - Pdepth, Scr.NormalGC, True); + TAILQ_FOREACH(m, &fp_monitor_q, entry) { + vp = set_vp_size_and_loc(m, false); + SetWindowBackground( + dpy, m->CPagerWin[i], vp.width, vp.height, + &Colorset[Desks[i].highcolorset], + Pdepth, Scr.NormalGC, True); + } } t = Start; @@ -1513,15 +1726,15 @@ void update_pr_transparent_subwindows(int i) if (t->PagerView != None) { SetWindowBackground( - dpy, t->PagerView, t->pager_view_width, - t->pager_view_height, + dpy, t->PagerView, t->pager_view.width, + t->pager_view.height, &Colorset[cset], Pdepth, Scr.NormalGC, True); } if (t->IconView) { SetWindowBackground( - dpy, t->IconView, t->icon_view_width, - t->icon_view_height, + dpy, t->IconView, t->icon_view.width, + t->icon_view.height, &Colorset[cset], Pdepth, Scr.NormalGC, True); } } @@ -1533,8 +1746,7 @@ void update_pr_transparent_windows(void) int i,j,k,cset; rectangle vp; PagerWindow *t; - - vp = set_vp_size_and_loc(); + struct fpmonitor *m; for(k=0;kCPagerWin[i], + vp.width, vp.height, + &Colorset[Desks[i]. + highcolorset], + Pdepth, Scr.NormalGC, + True); + } } } } @@ -1576,15 +1796,15 @@ void update_pr_transparent_windows(void) if (t->PagerView != None) { SetWindowBackground( - dpy, t->PagerView, t->pager_view_width, - t->pager_view_height, + dpy, t->PagerView, t->pager_view.width, + t->pager_view.height, &Colorset[cset], Pdepth, Scr.NormalGC, True); } if (t->desk && t->IconView) { SetWindowBackground( - dpy, t->IconView, t->icon_view_width, - t->icon_view_height, + dpy, t->IconView, t->icon_view.width, + t->icon_view.height, &Colorset[cset], Pdepth, Scr.NormalGC, True); } } @@ -1608,34 +1828,37 @@ void MovePage(Bool is_new_desk) char str[100],*sptr; static int icon_desk_shown = -1000; struct fpmonitor *fp = fpmonitor_this(NULL); + struct fpmonitor *m; if (fp == NULL) return; Wait = 0; - vp = set_vp_size_and_loc(); for(i=0;im->virtual_scr.CurrentDesk - desk1) - { - XMoveResizeWindow( - dpy, Desks[i].CPagerWin, vp.x, vp.y, vp.width, vp.height); - XLowerWindow(dpy,Desks[i].CPagerWin); - if (CSET_IS_TRANSPARENT(Desks[i].highcolorset)) + TAILQ_FOREACH(m, &fp_monitor_q, entry) { + if (!m->disabled && i == m->m->virtual_scr.CurrentDesk - desk1 && + (monitor_to_track == NULL || + strcmp(m->m->si->name, monitor_to_track) == 0)) { - SetWindowBackground( - dpy, Desks[i].CPagerWin, vp.width, vp.height, - &Colorset[Desks[i].highcolorset], Pdepth, - Scr.NormalGC, True); + vp = set_vp_size_and_loc(m, false); + XMoveResizeWindow(dpy, m->CPagerWin[i], + vp.x, vp.y, vp.width, vp.height); + XLowerWindow(dpy, m->CPagerWin[i]); + if (CSET_IS_TRANSPARENT(Desks[i].highcolorset)) + { + SetWindowBackground( + dpy, m->CPagerWin[i], vp.width, vp.height, + &Colorset[Desks[i].highcolorset], Pdepth, + Scr.NormalGC, True); + } + } else { + XMoveWindow(dpy, m->CPagerWin[i], -32768,-32768); } } - else - { - XMoveWindow(dpy, Desks[i].CPagerWin, -32768,-32768); - } } } DrawIconGrid(1); @@ -1666,14 +1889,14 @@ void MovePage(Bool is_new_desk) void ReConfigureAll(void) { - PagerWindow *t; + PagerWindow *t; - t = Start; - while(t!= NULL) - { - MoveResizePagerView(t, True); - t = t->next; - } + t = Start; + while(t != NULL) { + MoveResizePagerView(t, True); + t = t->next; + } + ReConfigureIcons(False); } void ReConfigureIcons(Bool do_reconfigure_desk_only) @@ -1690,10 +1913,7 @@ void ReConfigureIcons(Bool do_reconfigure_desk_only) if (do_reconfigure_desk_only && t->desk != fp->m->virtual_scr.CurrentDesk) continue; rec = CalcGeom(t, true); - t->icon_view_x = rec.x; - t->icon_view_y = rec.y; - t->icon_view_width = rec.width; - t->icon_view_height = rec.height; + t->icon_view = rec; if ((fp->m->virtual_scr.CurrentDesk != t->desk) || (HideSmallWindows && (rec.width == MinSize || rec.height == MinSize))) { @@ -1711,11 +1931,9 @@ void ReConfigureIcons(Bool do_reconfigure_desk_only) */ void DrawGrid(int desk, int erase, Window ew, XRectangle *r) { - int y, y1, y2, x, x1, x2,d,w; + int y, y1, y2, x, x1, x2, d, w; char str[15], *ptr; int cs; - XRectangle bound; - Region region = 0; struct fpmonitor *fp = fpmonitor_this(NULL); if (fp == NULL) @@ -1727,7 +1945,7 @@ void DrawGrid(int desk, int erase, Window ew, XRectangle *r) /* desk grid */ if (!ew || ew == Desks[desk].w) { - x = monitor_get_all_widths(); + x = fpmonitor_get_all_widths(); y1 = 0; y2 = desk_h; while (x < fp->virtual_scr.VWidth) @@ -1739,9 +1957,9 @@ void DrawGrid(int desk, int erase, Window ew, XRectangle *r) dpy,Desks[desk].w,Desks[desk].DashedGC, x1,y1,x1,y2); } - x += monitor_get_all_widths(); + x += fpmonitor_get_all_widths(); } - y = monitor_get_all_heights(); + y = fpmonitor_get_all_heights(); x1 = 0; x2 = desk_w; while(y < fp->virtual_scr.VHeight) @@ -1753,7 +1971,7 @@ void DrawGrid(int desk, int erase, Window ew, XRectangle *r) dpy,Desks[desk].w,Desks[desk].DashedGC, x1,y1,x2,y1); } - y += monitor_get_all_heights(); + y += fpmonitor_get_all_heights(); } } @@ -1762,103 +1980,139 @@ void DrawGrid(int desk, int erase, Window ew, XRectangle *r) return; } - /* desk label */ - if (r) - { - bound.x = r->x; - bound.y = r->y; - bound.width = r->width; - bound.height = r->height; - region = XCreateRegion(); - XUnionRectWithRegion (&bound, region, region); - } - else - { - bound.x = 0; - bound.y = (LabelsBelow ? desk_h : 0); - bound.width = desk_w; - bound.height = label_h; + /* desk label location */ + y1 = (LabelsBelow) ? desk_h : 0; + d = desk1 + desk; + int m_count = 1; + int y_loc = y1; + int height = label_h; + if (use_desk_label) { + height /= 2; + y_loc += height; } + if (use_monitor_label && monitor_to_track == NULL) + m_count = fpmonitor_count(); if (FftSupport) { erase = True; } - if(((fp->m->virtual_scr.CurrentDesk - desk1) == desk) && !ShapeLabels) + if (!ShapeLabels && use_desk_label && !use_monitor_label && + (fp->m->virtual_scr.CurrentDesk == d)) { - if (uselabel) - { - XFillRectangle( - dpy,Desks[desk].title_w,Desks[desk].HiliteGC, - bound.x, bound.y, bound.width, bound.height); - } + XFillRectangle(dpy, + Desks[desk].title_w, Desks[desk].HiliteGC, + 0, y1, desk_w, label_h); } - else + else if (label_h > 0 && erase) { - if(uselabel && erase) - { - XClearArea(dpy,Desks[desk].title_w, - bound.x, bound.y, bound.width, bound.height, - False); - } + XClearArea(dpy, Desks[desk].title_w, + 0, y1, desk_w, label_h, False); } - d = desk1+desk; - ptr = Desks[desk].label; - w = FlocaleTextWidth(Ffont,ptr,strlen(ptr)); - if( w > desk_w) - { - snprintf(str,sizeof(str),"%d",d); - ptr = str; - w = FlocaleTextWidth(Ffont,ptr,strlen(ptr)); + /* Draw monitor labels grid lines. */ + if (use_monitor_label) { + XDrawLine( + dpy, Desks[desk].title_w, Desks[desk].NormalGC, + 0, y_loc, desk_w, y_loc); + + for (int i = 1; i < m_count; i++) + XDrawLine(dpy, + Desks[desk].title_w, + Desks[desk].NormalGC, + i * desk_w / m_count, + y_loc, i * desk_w / m_count, + y_loc + height); } - if((w <= desk_w)&&(uselabel)) - { - FwinString->str = ptr; - FwinString->win = Desks[desk].title_w; - if(desk == (fp->m->virtual_scr.CurrentDesk - desk1)) - { - cs = Desks[desk].highcolorset; - FwinString->gc = Desks[desk].rvGC; - } - else - { - cs = Desks[desk].colorset; - FwinString->gc = Desks[desk].NormalGC; - } - FwinString->flags.has_colorset = False; - if (cs >= 0) - { - FwinString->colorset = &Colorset[cs]; - FwinString->flags.has_colorset = True; + if (use_desk_label) { + ptr = Desks[desk].label; + w = FlocaleTextWidth(Ffont, ptr, strlen(ptr)); + if (w > desk_w) { + snprintf(str, sizeof(str), "D%d", d); + ptr = str; + w = FlocaleTextWidth(Ffont, ptr, strlen(ptr)); } - FwinString->x = (desk_w - w)/2; - FwinString->y = (LabelsBelow ? - desk_h + Ffont->ascent + 1 : Ffont->ascent + 1); - if (region) - { - FwinString->flags.has_clip_region = True; - FwinString->clip_region = region; - XSetRegion(dpy, FwinString->gc, region); - } - else - { + if (w <= desk_w) { + FwinString->str = ptr; + FwinString->win = Desks[desk].title_w; + if (!use_monitor_label && + fp->m->virtual_scr.CurrentDesk == d) + { + cs = Desks[desk].highcolorset; + FwinString->gc = Desks[desk].rvGC; + } else { + cs = Desks[desk].colorset; + FwinString->gc = Desks[desk].NormalGC; + } + + FwinString->flags.has_colorset = False; + if (cs >= 0) + { + FwinString->colorset = &Colorset[cs]; + FwinString->flags.has_colorset = True; + } + FwinString->x = (desk_w - w)/2; + FwinString->y = y1 + Ffont->ascent + 1; FwinString->flags.has_clip_region = False; + FlocaleDrawString(dpy, Ffont, FwinString, 0); } - FlocaleDrawString(dpy, Ffont, FwinString, 0); - if (region) - { - XDestroyRegion(region); - FwinString->flags.has_clip_region = False; - FwinString->clip_region = None; - XSetClipMask(dpy, FwinString->gc, None); + } + + if (use_monitor_label) { + struct fpmonitor *tm; + int loop = 0; + int label_width = desk_w / m_count; + + fp = fpmonitor_this(NULL); + TAILQ_FOREACH(tm, &fp_monitor_q, entry) { + if (tm->disabled) + continue; + if (monitor_to_track != NULL && fp != tm) + continue; + + snprintf(str, sizeof(str), "%s", tm->m->si->name); + ptr = str; + w = FlocaleTextWidth(Ffont, ptr, strlen(ptr)); + if (w > label_width) { + snprintf(str, sizeof(str), "%d", loop + 1); + ptr = str; + w = FlocaleTextWidth(Ffont, ptr, strlen(ptr)); + } + if (w <= label_width) { + FwinString->str = ptr; + FwinString->win = Desks[desk].title_w; + if (tm->m->virtual_scr.CurrentDesk == d) { + cs = Desks[desk].highcolorset; + FwinString->gc = Desks[desk].rvGC; + XFillRectangle( + dpy,Desks[desk].title_w, + Desks[desk].HiliteGC, + loop * label_width, y_loc, + label_width, height); + } else { + cs = Desks[desk].colorset; + FwinString->gc = Desks[desk].NormalGC; + } + + FwinString->flags.has_colorset = False; + if (cs >= 0) + { + FwinString->colorset = &Colorset[cs]; + FwinString->flags.has_colorset = True; + } + FwinString->x = loop * label_width + + (label_width - w)/2; + FwinString->y = y_loc + Ffont->ascent + 1; + FlocaleDrawString(dpy, Ffont, FwinString, 0); + } + loop++; } } if (FShapesSupported) { - UpdateWindowShape (); + UpdateWindowShape(); } } @@ -1908,26 +2162,31 @@ void DrawIconGrid(int erase) 0, i * rec.height, icon.width, i * rec.height); } - rec.x = (fp->virtual_scr.Vx * rec.width) / monitor_get_all_widths(); - rec.y = (fp->virtual_scr.Vy * rec.height) / monitor_get_all_heights(); - if (HilightDesks) { - if (HilightPixmap) { - XCopyArea(dpy, HilightPixmap->picture, icon_win, - Scr.NormalGC, 0, 0, rec.width, rec.height, - rec.x, rec.y); - } else { - XFillRectangle(dpy, icon_win, Desks[tmp].HiliteGC, - rec.x, rec.y, rec.width, rec.height); + TAILQ_FOREACH(fp, &fp_monitor_q, entry) { + if (fp->disabled || + fp->m->virtual_scr.CurrentDesk != tmp || + (monitor_to_track != NULL && + strcmp(fp->m->si->name, monitor_to_track) != 0)) + continue; + rec = set_vp_size_and_loc(fp, true); + if (HilightPixmap) { + XCopyArea(dpy, HilightPixmap->picture, icon_win, + Scr.NormalGC, 0, 0, rec.width, rec.height, + rec.x, rec.y); + } else { + XFillRectangle(dpy, icon_win, Desks[tmp].HiliteGC, + rec.x, rec.y, rec.width, rec.height); + } } } } -void SwitchToDesk(int Desk) +void SwitchToDesk(int Desk, struct fpmonitor *m) { char command[256]; - struct fpmonitor *fp = fpmonitor_this(NULL); + struct fpmonitor *fp = (m == NULL) ? fpmonitor_this(NULL) : m; if (fp == NULL) { fprintf(stderr, "%s: couldn't find monitor (fp is NULL)\n", @@ -1942,64 +2201,65 @@ void SwitchToDesk(int Desk) void SwitchToDeskAndPage(int Desk, XEvent *Event) { - char command[256]; - struct fpmonitor *fp = fpmonitor_this(NULL); + char command[256]; + int vx, vy; + struct fpmonitor *fp = fpmonitor_this(NULL); - if (fp == NULL) { - fprintf(stderr, "%s: couldn't find monitor (fp is NULL)\n", __func__); - return; - } + if (fp == NULL) { + fprintf(stderr, "%s: couldn't find monitor (fp is NULL)\n", + __func__); + return; + } - if (fp->m->virtual_scr.CurrentDesk != (Desk + desk1)) - { - int vx, vy; - /* patch to let mouse button 3 change desks and do not cling to a page */ - if (desk_w == 0) - vx = 0; - else - vx = Event->xbutton.x * fp->virtual_scr.VWidth / (desk_w * monitor_get_all_widths()); - if (desk_h == 0) - vy = 0; - else - vy = Event->xbutton.y * fp->virtual_scr.VHeight / (desk_h * monitor_get_all_heights()); - fp->m->virtual_scr.Vx = vx * monitor_get_all_widths(); - fp->m->virtual_scr.Vy = vy * monitor_get_all_heights(); - snprintf(command, sizeof(command), "GotoDeskAndPage screen %s %d %d %d", - fp->m->si->name, Desk + desk1, vx, vy); - SendText(fd, command, 0); + /* Determine which monitor occupied the clicked region. */ + Desk += desk1; + vx = (desk_w == 0) ? 0 : + Event->xbutton.x * fp->virtual_scr.VWidth / desk_w; + vy = (desk_h == 0) ? 0 : + Event->xbutton.y * fp->virtual_scr.VHeight / desk_h; - } - else - { - int x, y; - if (desk_w == 0) - x = 0; - else - x = Event->xbutton.x * fp->virtual_scr.VWidth / (desk_w * monitor_get_all_widths()); - if (desk_h == 0) - y = 0; - else - y = Event->xbutton.y * fp->virtual_scr.VHeight / (desk_h * monitor_get_all_heights()); - - /* Fix for buggy XFree86 servers that report button release events - * incorrectly when moving fast. Not perfect, but should at least prevent - * that we get a random page. */ - if (x < 0) - x = 0; - if (y < 0) - y = 0; - if (x * monitor_get_all_widths() > fp->virtual_scr.VxMax) - x = fp->virtual_scr.VxMax / monitor_get_all_widths(); - if (y * monitor_get_all_heights() > fp->virtual_scr.VyMax) - y = fp->virtual_scr.VyMax / monitor_get_all_heights(); - snprintf(command, sizeof(command), "GotoPage screen %s %d %d", fp->m->si->name, x, y); - SendText(fd, command, 0); - } - Wait = 1; + if (monitor_mode == MONITOR_TRACKING_G && is_tracking_shared) + fp = fpmonitor_from_desk(Desk); + else + fp = fpmonitor_from_xy(vx, vy); + if (fp == NULL) + return; + + /* Fix for buggy XFree86 servers that report button release + * events incorrectly when moving fast. Not perfect, but + * should at least prevent that we get a random page. + */ + if (vx < 0) + vx = 0; + if (vy < 0) + vy = 0; + if (vx > fp->virtual_scr.VxMax) + vx = fp->virtual_scr.VxMax; + if (vy > fp->virtual_scr.VyMax) + vy = fp->virtual_scr.VyMax; + vx /= fpmonitor_get_all_widths(); + vy /= fpmonitor_get_all_heights(); + + + if (fp->m->virtual_scr.CurrentDesk != Desk) { + /* patch to let mouse button 3 change desks and not cling */ + fp->m->virtual_scr.Vx = vx; + fp->m->virtual_scr.Vy = vy; + snprintf(command, sizeof(command), + "GotoDeskAndPage screen %s %d %d %d", + fp->m->si->name, Desk, vx, vy); + SendText(fd, command, 0); + } else { + snprintf(command, sizeof(command), + "GotoPage screen %s %d %d", fp->m->si->name, vx, vy); + SendText(fd, command, 0); + } + Wait = 1; } void IconSwitchPage(XEvent *Event) { + int vx, vy; char command[34]; struct fpmonitor *fp = fpmonitor_this(NULL); @@ -2008,12 +2268,21 @@ void IconSwitchPage(XEvent *Event) return; } + /* Determine which monitor occupied the clicked region. */ + vx = (icon.width == 0) ? 0 : Event->xbutton.x * fp->virtual_scr.VWidth / + icon.width; + vy = (icon.height == 0) ? 0 : Event->xbutton.y * fp->virtual_scr.VHeight / + icon.height; + fp = fpmonitor_from_xy(vx, vy); + if (fp == NULL) + return; + snprintf(command,sizeof(command),"GotoPage screen %s %d %d", fp->m->si->name, Event->xbutton.x * fp->virtual_scr.VWidth / - (icon.width * monitor_get_all_widths()), + (icon.width * fpmonitor_get_all_widths()), Event->xbutton.y * fp->virtual_scr.VHeight / - (icon.height * monitor_get_all_heights())); + (icon.height * fpmonitor_get_all_heights())); SendText(fd, command, 0); Wait = 1; } @@ -2025,17 +2294,14 @@ void AddNewWindow(PagerWindow *t) XSetWindowAttributes attributes; rectangle rec; int i; - struct fpmonitor *fp = fpmonitor_this(NULL); + struct fpmonitor *fp = fpmonitor_this(t->m); if (fp == NULL) return; i = t->desk - desk1; rec = CalcGeom(t, false); - t->pager_view_x = rec.x; - t->pager_view_y = rec.y; - t->pager_view_width = rec.width; - t->pager_view_height = rec.height; + t->pager_view = rec; valuemask = CWBackPixel | CWEventMask; attributes.background_pixel = t->back; attributes.event_mask = ExposureMask; @@ -2084,10 +2350,7 @@ void AddNewWindow(PagerWindow *t) } rec = CalcGeom(t, true); - t->icon_view_x = rec.x; - t->icon_view_y = rec.y; - t->icon_view_width = rec.width; - t->icon_view_height = rec.height; + t->icon_view = rec; if((fp->m->virtual_scr.CurrentDesk != t->desk) || (HideSmallWindows && (rec.width == MinSize || rec.height == MinSize))) @@ -2096,7 +2359,7 @@ void AddNewWindow(PagerWindow *t) rec.y = -32768; } t->IconView = XCreateWindow( - dpy,icon_win, rec.x, rec.y, rec.width, rec.height, 0, + dpy, icon_win, rec.x, rec.y, rec.width, rec.height, 0, CopyFromParent, InputOutput, CopyFromParent, valuemask, &attributes); if (windowcolorset > -1) @@ -2138,7 +2401,7 @@ void ChangeDeskForWindow(PagerWindow *t,long newdesk) rectangle rec; int i; Bool size_changed = False; - struct fpmonitor *fp = fpmonitor_this(NULL); + struct fpmonitor *fp = fpmonitor_this(t->m); if (fp == NULL) return; @@ -2153,12 +2416,9 @@ void ChangeDeskForWindow(PagerWindow *t,long newdesk) } rec = CalcGeom(t, false); - size_changed = (t->pager_view_width != rec.width || - t->pager_view_height != rec.height); - t->pager_view_x = rec.x; - t->pager_view_y = rec.y; - t->pager_view_width = rec.width; - t->pager_view_height = rec.height; + size_changed = (t->pager_view.width != rec.width || + t->pager_view.height != rec.height); + t->pager_view = rec; if (HideSmallWindows && (rec.width == MinSize || rec.height == MinSize)) { @@ -2177,7 +2437,7 @@ void ChangeDeskForWindow(PagerWindow *t,long newdesk) if (cset > -1 && (size_changed || CSET_IS_TRANSPARENT(cset))) { SetWindowBackground( - dpy, t->PagerView, t->pager_view_width, t->pager_view_height, + dpy, t->PagerView, t->pager_view.width, t->pager_view.height, &Colorset[cset], Pdepth, Scr.NormalGC, True); } } @@ -2189,12 +2449,9 @@ void ChangeDeskForWindow(PagerWindow *t,long newdesk) t->desk = i+desk1; rec = CalcGeom(t, true); - size_changed = (t->icon_view_width != rec.width || - t->icon_view_height != rec.height); - t->icon_view_x = rec.x; - t->icon_view_y = rec.y; - t->icon_view_width = rec.width; - t->icon_view_height = rec.height; + size_changed = (t->icon_view.width != rec.width || + t->icon_view.height != rec.height); + t->icon_view = rec; if (HideSmallWindows && (rec.width == MinSize || rec.height == MinSize)) { rec.x = -32768; @@ -2211,7 +2468,7 @@ void ChangeDeskForWindow(PagerWindow *t,long newdesk) if (cset > -1 && (size_changed || CSET_IS_TRANSPARENT(cset))) { SetWindowBackground( - dpy, t->IconView, t->icon_view_width, t->icon_view_height, + dpy, t->IconView, t->icon_view.width, t->icon_view.height, &Colorset[cset], Pdepth, Scr.NormalGC, True); } } @@ -2222,7 +2479,7 @@ void MoveResizePagerView(PagerWindow *t, Bool do_force_redraw) rectangle rec; Bool size_changed; Bool position_changed; - struct fpmonitor *fp = fpmonitor_this(NULL); + struct fpmonitor *fp = fpmonitor_this(t->m); if (fp == NULL) return; @@ -2245,13 +2502,10 @@ void MoveResizePagerView(PagerWindow *t, Bool do_force_redraw) } rec = CalcGeom(t, false); - position_changed = (t->pager_view_x != rec.x || t->pager_view_y != rec.y); - size_changed = (t->pager_view_width != rec.width || - t->pager_view_height != rec.height); - t->pager_view_x = rec.x; - t->pager_view_y = rec.y; - t->pager_view_width = rec.width; - t->pager_view_height = rec.height; + position_changed = (t->pager_view.x != rec.x || t->pager_view.y != rec.y); + size_changed = (t->pager_view.width != rec.width || + t->pager_view.height != rec.height); + t->pager_view = rec; if (t->PagerView != None) { if (size_changed || position_changed || do_force_redraw) @@ -2268,7 +2522,7 @@ void MoveResizePagerView(PagerWindow *t, Bool do_force_redraw) if (cset > -1 && (size_changed || CSET_IS_TRANSPARENT(cset))) { SetWindowBackground( - dpy, t->PagerView, t->pager_view_width, t->pager_view_height, + dpy, t->PagerView, t->pager_view.width, t->pager_view.height, &Colorset[cset], Pdepth, Scr.NormalGC, True); } } @@ -2281,13 +2535,10 @@ void MoveResizePagerView(PagerWindow *t, Bool do_force_redraw) } rec = CalcGeom(t, true); - position_changed = (t->icon_view_x != rec.x || t->icon_view_y != rec.y); - size_changed = (t->icon_view_width != rec.width || - t->icon_view_height != rec.height); - t->icon_view_x = rec.x; - t->icon_view_y = rec.y; - t->icon_view_width = rec.width; - t->icon_view_height = rec.height; + position_changed = (t->icon_view.x != rec.x || t->icon_view.y != rec.y); + size_changed = (t->icon_view.width != rec.width || + t->icon_view.height != rec.height); + t->icon_view = rec; if (fp->m->virtual_scr.CurrentDesk == t->desk) { int cset; @@ -2302,7 +2553,7 @@ void MoveResizePagerView(PagerWindow *t, Bool do_force_redraw) if (cset > -1 && (size_changed || CSET_IS_TRANSPARENT(cset))) { SetWindowBackground( - dpy, t->IconView, t->icon_view_width, t->icon_view_height, + dpy, t->IconView, t->icon_view.width, t->icon_view.height, &Colorset[cset], Pdepth, Scr.NormalGC, True); } } @@ -2316,13 +2567,13 @@ void MoveResizePagerView(PagerWindow *t, Bool do_force_redraw) void MoveStickyWindow(Bool is_new_page, Bool is_new_desk) { PagerWindow *t; - struct fpmonitor *fp = fpmonitor_this(NULL); - - if (fp == NULL) - return; + struct fpmonitor *fp; for (t = Start; t != NULL; t = t->next) { + fp = fpmonitor_this(t->m); + if (fp == NULL) + continue; if ( is_new_desk && t->desk != fp->m->virtual_scr.CurrentDesk && ((IS_ICONIFIED(t) && IS_ICON_STICKY_ACROSS_DESKS(t)) || @@ -2402,11 +2653,11 @@ void Hilight(PagerWindow *t, int on) if (t->PagerView != None) { SetWindowBackground( - dpy, t->PagerView, t->pager_view_width, t->pager_view_height, + dpy, t->PagerView, t->pager_view.width, t->pager_view.height, &Colorset[cset], Pdepth, Scr.NormalGC, True); } SetWindowBackground( - dpy, t->IconView, t->icon_view_width, t->icon_view_height, + dpy, t->IconView, t->icon_view.width, t->icon_view.height, &Colorset[cset], Pdepth, Scr.NormalGC, True); } } @@ -2418,7 +2669,7 @@ void Scroll(int x, int y, int Desk, Bool do_scroll_icon) static int last_sx = -999999; static int last_sy = -999999; int window_w = desk_w, window_h = desk_h, sx, sy, adjx, adjy; - struct fpmonitor *fp = fpmonitor_this(NULL); + struct fpmonitor *fp = ScrollFp; if (fp == NULL) return; @@ -2433,9 +2684,17 @@ void Scroll(int x, int y, int Desk, Bool do_scroll_icon) window_w = icon.width; window_h = icon.height; } + /* center around mouse */ - adjx = (window_w / (1 + fp->virtual_scr.VxMax / monitor_get_all_widths())); - adjy = (window_h / (1 + fp->virtual_scr.VyMax / monitor_get_all_heights())); + if (monitor_mode == MONITOR_TRACKING_G && !is_tracking_shared) { + adjx = window_w / fp->virtual_scr.VxPages; + adjy = window_h / fp->virtual_scr.VyPages; + } else { + adjx = (2 * fp->m->si->x + fp->m->si->w) * window_w / + fp->virtual_scr.VWidth; + adjy = (2 * fp->m->si->y + fp->m->si->h) * window_h / + fp->virtual_scr.VHeight; + } x -= adjx/2; y -= adjy/2; @@ -2449,13 +2708,13 @@ void Scroll(int x, int y, int Desk, Bool do_scroll_icon) y = 0; } - if (x > window_w - adjx) + if (x > window_w) { - x = window_w - adjx; + x = window_w; } - if (y > window_h - adjy) + if (y > window_h) { - y = window_h - adjy; + y = window_h; } sx = 0; @@ -2515,10 +2774,7 @@ void MoveWindow(XEvent *Event) int JunkX, JunkY; unsigned JunkMask; int do_switch_desk_later = 0; - struct fpmonitor *fp = fpmonitor_this(NULL); - - if (fp == NULL) - return; + struct fpmonitor *fp; rectangle rec; t = Start; @@ -2541,16 +2797,17 @@ void MoveWindow(XEvent *Event) if (NewDesk < 0 || NewDesk >= ndesks) return; + fp = fpmonitor_this(t->m); rec.x = fp->virtual_scr.Vx + t->x; rec.y = fp->virtual_scr.Vy + t->y; rec.width = t->width; rec.height = t->height; - fvwmrec_to_pager(&rec, false); + fvwmrec_to_pager(&rec, false, fp); - rec.x = rec.x + (desk_w + 1) * (NewDesk % Columns); - rec.y = rec.y + label_h + (desk_h + label_h + 1) * (NewDesk / Columns); - if (LabelsBelow) - rec.y -= label_h; + rec.x += (desk_w + 1) * (NewDesk % Columns); + rec.y += (desk_h + label_h + 1) * (NewDesk / Columns); + if (!LabelsBelow) + rec.y += label_h; XReparentWindow(dpy, t->PagerView, Scr.Pager_w, rec.x, rec.y); XRaiseWindow(dpy, t->PagerView); @@ -2558,6 +2815,7 @@ void MoveWindow(XEvent *Event) XTranslateCoordinates(dpy, Event->xany.window, t->PagerView, Event->xbutton.x, Event->xbutton.y, &rec.x, &rec.y, &dumwin); + xi = rec.x; yi = rec.y; while (!finished) { @@ -2655,53 +2913,50 @@ void MoveWindow(XEvent *Event) } XTranslateCoordinates(dpy, Scr.Pager_w, Desks[NewDesk].w, - x - rec.x, y - rec.y, &rec.x, &rec.y, &dumwin); - - pagerrec_to_fvwm(&rec, false); - rec.x = rec.x - fp->virtual_scr.Vx; - rec.y = rec.y - fp->virtual_scr.Vy; - - if (NewDesk + desk1 != t->desk) { - if ((IS_ICONIFIED(t) && IS_ICON_STICKY_ACROSS_DESKS(t)) - || (IS_STICKY_ACROSS_DESKS(t))) { - NewDesk = fp->m->virtual_scr.CurrentDesk - desk1; - if (t->desk != fp->m->virtual_scr.CurrentDesk) - ChangeDeskForWindow(t,fp->m->virtual_scr.CurrentDesk); - } - else if (NewDesk + desk1 != fp->m->virtual_scr.CurrentDesk) { - snprintf(command, sizeof(command), "Silent MoveToDesk 0 %d", - NewDesk + desk1); - SendText(fd, command, t->w); - t->desk = NewDesk + desk1; - } else { - do_switch_desk_later = 1; - } + x - rec.x, y - rec.y, &rec.x, &rec.y, + &dumwin); + + fp = fpmonitor_from_xy(rec.x * fp->virtual_scr.VWidth / desk_w, + rec.y * fp->virtual_scr.VHeight / desk_h); + if (fp == NULL) + fp = fpmonitor_this(NULL); + pagerrec_to_fvwm(&rec, false, fp); + + if (NewDesk + desk1 != t->desk && + ((IS_ICONIFIED(t) && IS_ICON_STICKY_ACROSS_DESKS(t)) + || (IS_STICKY_ACROSS_DESKS(t)))) + { + NewDesk = fp->m->virtual_scr.CurrentDesk - desk1; + if (t->desk != fp->m->virtual_scr.CurrentDesk) + ChangeDeskForWindow(t, + fp->m->virtual_scr.CurrentDesk); + } else { + do_switch_desk_later = 1; } - if (NewDesk >= 0 && NewDesk < ndesks) - { - XReparentWindow(dpy, t->PagerView, - Desks[NewDesk].w, rec.x, rec.y); - t->desk = NewDesk; - XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True); - if (moved) { - char buf[64]; - /* XXX: Note the use of ewmhiwa to disable - * clipping the coordinates to the wrong area! - */ - snprintf(buf, sizeof(buf), "Silent Move +%dp +%dp ewmhiwa", - rec.x, rec.y); - SendText(fd, buf, t->w); - XSync(dpy,0); - } else { - MoveResizePagerView(t, True); - } - SendText(fd, "Silent Raise", t->w); + XReparentWindow(dpy, t->PagerView, + Desks[NewDesk].w, rec.x, rec.y); + XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True); + if (moved) { + char buf[64]; + /* XXX: Note the use of ewmhiwa to disable + * clipping the coordinates to the wrong area! + */ + snprintf(buf, sizeof(buf), + "Silent Move v+%dp v+%dp ewmhiwa", + rec.x, rec.y); + SendText(fd, buf, t->w); + XSync(dpy,0); + t->m = fp->m; + } else { + MoveResizePagerView(t, True); } + SendText(fd, "Silent Raise", t->w); if (do_switch_desk_later) { - snprintf(command, sizeof(command), "Silent MoveToDesk 0 %d", NewDesk + - desk1); + snprintf(command, sizeof(command), + "Silent MoveToDesk 0 %d", + NewDesk + desk1); SendText(fd, command, t->w); t->desk = NewDesk + desk1; } @@ -2769,13 +3024,13 @@ static void draw_window_border(PagerWindow *t, Window w, int width, int height) void BorderWindow(PagerWindow *t) { draw_window_border( - t, t->PagerView, t->pager_view_width, t->pager_view_height); + t, t->PagerView, t->pager_view.width, t->pager_view.height); } void BorderIconWindow(PagerWindow *t) { draw_window_border( - t, t->IconView, t->icon_view_width, t->icon_view_height); + t, t->IconView, t->icon_view.width, t->icon_view.height); } /* draw the window label with simple greedy wrapping */ @@ -2799,7 +3054,7 @@ static void label_window_wrap(PagerWindow *t) p = end; width = FlocaleTextWidth(FwindowFont, next, p - next ); - if (width > t->pager_view_width - cur_width - space_width - 2*label_border) + if (width > t->pager_view.width - cur_width - space_width - 2*label_border) break; cur_width += width + space_width; next = *p ? p + 1 : p; @@ -2813,7 +3068,7 @@ static void label_window_wrap(PagerWindow *t) len = FlocaleStringNumberOfBytes(FwindowFont, next); width = FlocaleTextWidth(FwindowFont, next, len); - if (width > t->pager_view_width - cur_width - 2*label_border && cur != next) + if (width > t->pager_view.width - cur_width - 2*label_border && cur != next) break; next += len; @@ -2974,12 +3229,12 @@ static void do_picture_window( void PictureWindow (PagerWindow *t) { - do_picture_window(t, t->PagerView, t->pager_view_width, t->pager_view_height); + do_picture_window(t, t->PagerView, t->pager_view.width, t->pager_view.height); } void PictureIconWindow (PagerWindow *t) { - do_picture_window(t, t->IconView, t->icon_view_width, t->icon_view_height); + do_picture_window(t, t->IconView, t->icon_view.width, t->icon_view.height); } void IconMoveWindow(XEvent *Event, PagerWindow *t) @@ -2992,19 +3247,20 @@ void IconMoveWindow(XEvent *Event, PagerWindow *t) int JunkX, JunkY; unsigned JunkMask; rectangle rec; - struct fpmonitor *fp = fpmonitor_this(NULL); - - if (fp == NULL) - return; + struct fpmonitor *fp; if (t == NULL || !t->allowed_actions.is_movable) return; + fp = fpmonitor_this(t->m); rec.x = fp->virtual_scr.Vx + t->x; rec.y = fp->virtual_scr.Vy + t->y; rec.width = t->width; rec.height = t->height; - fvwmrec_to_pager(&rec, true); + if (fp == NULL) + return; + + fvwmrec_to_pager(&rec, true, fp); XRaiseWindow(dpy, t->IconView); @@ -3058,14 +3314,19 @@ void IconMoveWindow(XEvent *Event, PagerWindow *t) } else { rec.x = x - rec.x; rec.y = y - rec.y; - pagerrec_to_fvwm(&rec, true); - rec.x = rec.x - fp->virtual_scr.Vx; - rec.y = rec.y - fp->virtual_scr.Vy; if (moved) { char buf[64]; - snprintf(buf, sizeof(buf), "Silent Move +%dp +%dp ewmhiwa", - rec.x, rec.y); + fp = fpmonitor_from_xy( + rec.x * fp->virtual_scr.VWidth / icon.width, + rec.y * fp->virtual_scr.VHeight / icon.height); + if (fp == NULL) + fp = fpmonitor_this(NULL); + pagerrec_to_fvwm(&rec, true, fp); + t->m = fp->m; + snprintf(buf, sizeof(buf), + "Silent Move v+%dp v+%dp ewmhiwa", + rec.x, rec.y); SendText(fd, buf, t->w); XSync(dpy, 0); } else { @@ -3160,14 +3421,14 @@ void MapBalloonWindow(PagerWindow *t, Bool is_icon_view) if (!is_icon_view) { view = t->PagerView; - view_width = t->pager_view_width; - view_height = t->pager_view_height; + view_width = t->pager_view.width; + view_height = t->pager_view.height; } else { view = t->IconView; - view_width = t->icon_view_width; - view_height = t->icon_view_height; + view_width = t->icon_view.width; + view_height = t->icon_view.height; } BalloonView = view; /* associate balloon with its pager window */ @@ -3235,7 +3496,7 @@ void MapBalloonWindow(PagerWindow *t, Bool is_icon_view) } /* too close to bottom ... make yoffset -ve */ else if ( new_g.y + new_g.height > - monitor_get_all_heights() - (2 * BalloonBorderWidth) - 2 ) + fpmonitor_get_all_heights() - (2 * BalloonBorderWidth) - 2 ) { y = - BalloonYOffset + 1 - new_g.height - (2 * BalloonBorderWidth); @@ -3249,9 +3510,9 @@ void MapBalloonWindow(PagerWindow *t, Bool is_icon_view) } /* too close to right */ else if (new_g.x + new_g.width > - monitor_get_all_widths() - (2 * BalloonBorderWidth) - 2 ) + fpmonitor_get_all_widths() - (2 * BalloonBorderWidth) - 2 ) { - new_g.x = monitor_get_all_widths() - new_g.width - + new_g.x = fpmonitor_get_all_widths() - new_g.width - (2 * BalloonBorderWidth) - 2; } /* make changes to window */ @@ -3374,11 +3635,11 @@ static void set_window_colorset_background( if (t->PagerView != None) { SetWindowBackground( - dpy, t->PagerView, t->pager_view_width, t->pager_view_height, + dpy, t->PagerView, t->pager_view.width, t->pager_view.height, csetp, Pdepth, Scr.NormalGC, True); } SetWindowBackground( - dpy, t->IconView, t->icon_view_width, t->icon_view_height, + dpy, t->IconView, t->icon_view.width, t->icon_view.height, csetp, Pdepth, Scr.NormalGC, True); return; @@ -3390,6 +3651,7 @@ void change_colorset(int colorset) int i; PagerWindow *t; struct fpmonitor *fp = fpmonitor_this(NULL); + struct fpmonitor *m; /* just in case */ if (colorset < 0) @@ -3404,16 +3666,18 @@ void change_colorset(int colorset) XSetForeground(dpy, Desks[i].rvGC, Colorset[colorset].fg); if (HilightDesks) { - if (uselabel && (i == fp->m->virtual_scr.CurrentDesk)) + if (label_h > 0 && fp->m->virtual_scr.CurrentDesk == i) { SetWindowBackground( dpy, Desks[i].title_w, desk_w, desk_h, &Colorset[colorset], Pdepth, Scr.NormalGC, True); } - SetWindowBackground( - dpy, Desks[i].CPagerWin, 0, 0, &Colorset[colorset], Pdepth, - Scr.NormalGC, True); - XLowerWindow(dpy,Desks[i].CPagerWin); + TAILQ_FOREACH(m, &fp_monitor_q, entry) { + SetWindowBackground( + dpy, m->CPagerWin[i], 0, 0, &Colorset[colorset], Pdepth, + Scr.NormalGC, True); + XLowerWindow(dpy, m->CPagerWin[i]); + } } } @@ -3423,13 +3687,13 @@ void change_colorset(int colorset) XSetWindowBorder(dpy, Desks[i].w, Colorset[colorset].fg); XSetForeground(dpy, Desks[i].NormalGC,Colorset[colorset].fg); XSetForeground(dpy, Desks[i].DashedGC,Colorset[colorset].fg); - if (uselabel) + if (label_h > 0) { SetWindowBackground( dpy, Desks[i].title_w, desk_w, desk_h + label_h, &Colorset[colorset], Pdepth, Scr.NormalGC, True); } - if (label_h != 0 && uselabel && !LabelsBelow && + if (label_h != 0 && label_h > 0 && !LabelsBelow && !CSET_IS_TRANSPARENT_PR(Desks[i].colorset)) { SetWindowBackgroundWithOffset( @@ -3444,7 +3708,7 @@ void change_colorset(int colorset) } update_pr_transparent_subwindows(i); } - else if (Desks[i].highcolorset == colorset && uselabel) + else if (Desks[i].highcolorset == colorset && label_h > 0) { SetWindowBackground( dpy, Desks[i].title_w, 0, 0, &Colorset[Desks[i].colorset], Pdepth,