OpenBSD FVWM 2.2.5: GPL Code Replacement ========================================= Replaces GPL-licensed code with permissive-licensed equivalents. Files rewritten to remove GPL dependencies: fvwm/COPYING License text replaced fvwm/fvwm/fvwm2.1 Man page (GPL references removed) fvwm/libs/ColorUtils.c Color utilities rewritten fvwm/modules/FvwmBacker/root_bits.c Root pixmap code rewritten fvwm/modules/FvwmRearrange/FvwmRearrange.1 Man page rewritten fvwm/modules/FvwmRearrange/FvwmRearrange.c Module rewritten These files contained code derived from GPL-licensed sources. They have been rewritten to use only permissive-licensed code compatible with the OpenBSD base system. To apply: cd && patch -p0 < this-file Index: fvwm/COPYING =================================================================== RCS file: /cvs/src/xenocara/app/fvwm/COPYING,v retrieving revision 1.1 diff -u -r1.1 fvwm/COPYING --- fvwm/COPYING +++ fvwm/COPYING @@ -1,3 +1,8 @@ +FVWM Licensing Terms and Conditions +=================================== + +General Terms +------------- Permission is granted to distribute all software within this distribution freely as long as the individual copyrights, copyright notices and associated disclaimers remain intact @@ -11,29 +16,9 @@ THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ----------------------------------------------------------------------- - -In addition - with the exception of the following directories -and all files within: - - modules/FvwmRearrange - extras/FvwmPipe - modules/FvwmAnimate - modules/FvwmAudio - modules/FvwmEvents - -- permission is granted to use this software for any purpose, as -long as the individual copyrights, copyright notices and -associated disclaimers remain intact in the sources and the -supporting documentation. The following pieces of software are -exempt from this statement. - -The modules modules/FvwmAnimate, modules/FvwmAudio and modules/FvwmEvents -are subject to the GNU public license (see below). - ----------------------------------------------------------------------- - -The copyrights of the fvwm main module are: +FVWM Main Module +---------------- +The FVWM main module is distributed under the following license: fvwm is copyright 1988 by Evans and Sutherland Computer Corporation, Salt Lake City, Utah, and 1989 by the Massachusetts @@ -58,314 +43,25 @@ USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------- - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +Additional Component Licenses +----------------------------- +The following pieces of software are distributed under the ISC License: + libs/ColorUtils.c + modules/FvwmRearrange + modules/FvwmBacker/root_bits.c + +ISC License +----------- + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. Index: fvwm/fvwm/fvwm2.1 =================================================================== RCS file: /cvs/src/xenocara/app/fvwm/fvwm/fvwm2.1,v retrieving revision 1.1 diff -u -r1.1 fvwm/fvwm/fvwm2.1 --- fvwm/fvwm/fvwm2.1 +++ fvwm/fvwm/fvwm2.1 @@ -1,2899 +1,369 @@ -.\" $OpenBSD: fvwm2.1,v 1.2 2019/10/19 16:39:49 matthieu Exp $ -.\" t -.\" @(#)fvwm2.1 8/11/1998 -.de EX \"Begin example -.ne 5 -.if n .sp 1 -.if t .sp .5 -.nf -.in +.5i -.. -.de EE -.fi -.in -.5i -.if n .sp 1 -.if t .sp .5 -.. -.ta .3i .6i .9i 1.2i 1.5i 1.8i -.TH FVWM 1 "late 20th century" "fvwm 2.xx" -.UC -.SH NAME -fvwm \- F(?) Virtual Window Manager (version 2.xx) for X11 -.SH SYNOPSIS -\fBfvwm\fP [ \fIoptions\fP ] -.SH DESCRIPTION -\fIFvwm\fP is a window manager for X11. It is a derivative of -\fItwm\fP, redesigned to minimize memory consumption, provide a 3-D -look to window frames, and provide a simple virtual desktop. Version -2.xx uses only slightly more memory than 1.xx, mostly due to some -global options being able to be window specific now. - -Fvwm provides both a large virtual desktop and multiple disjoint -desktops which can be used separately or together. The virtual desktop -allows you to pretend that your video screen is really quite large, -and you can scroll around within the desktop. The multiple disjoint -desktops allow you to pretend that you really have several screens to -work at, but each screen is completely unrelated to the others. - -Fvwm provides keyboard accelerators which allow you to perform most -window-manager functions, including moving and resizing windows, and -operating the window-manager's menus, using keyboard shortcuts. - -Fvwm has also blurred the distinction between configuration commands -and built-in commands that most window-managers make. Configuration -commands typically set fonts, colors, menu contents, key and mouse -function bindings, while built-in commands typically do things like -raise and lower windows. Fvwm makes no such distinction, and allows, -to the extent that is practical, anything to be changed at any time. - -Other noteworthy differences between Fvwm and other X11 window managers -are the introduction of the SloppyFocus and per-window focus methods. -SloppyFocus is focus-follows-mouse, but focus is not removed from -windows when the mouse leaves a window and enters the root window. -When sloppy focus is used as the default focus style, it is nice to -make windows in which you do not typically type into (xmag, -xload, xclock, xbiff, etc) click-to-focus, so that your terminal -window doesn't lose focus unnecessarily. - -.SH COPYRIGHTS -Since \fIfvwm\fP is derived from \fItwm\fP code it shares \fItwm\fP's -copyrights. Since nearly every line of twm code has been changed, the -twm copyright has been removed from most of the individual code files. -I do still recognize the influence of twm code in the overall package, -so fvwm's copyright is still considered to be the same as twm's. - -Please consult the COPYING file that has come with your distribution -for details. - -.SH ANATOMY OF A WINDOW -\fIFvwm\fP puts a decorative border around most windows. This border -consists of a bar on each side and a small "L" shaped section on each -corner. There is an additional top bar called the title bar which is -used to display the name of the window. In addition, there are up to -10 title-bar buttons. The top, side, and bottom bars are collectively -known as the side-bars. The corner pieces are called the frame. - -Unless the standard defaults files are modified, pressing mouse button -1 in the title or side-bars will begin a move operation on the -window. Pressing button 1 in the corner frame pieces will begin a -resize operation. Pressing button 2 anywhere in the border brings up -an extensive list of window operations. - -Up to ten title-bar buttons may exist. Their use is completely user -definable. The default configuration has a title-bar button on each -side of the title-bar. The one on the left is used to bring up a list -of window options, regardless of which mouse button is used. The one -on the right is used to iconify the window. The number of title-bar -buttons used depends on which ones have mouse actions bound to -them. See the section on the "Mouse" configuration parameter below. - - -.SH THE VIRTUAL DESKTOP -\fIFvwm\fP provides multiple virtual desktops for users who wish to -use them. The screen is a viewport onto a desktop which may be larger -than the screen. Several distinct desktops can be accessed (concept: -one desktop for each project, or one desktop for each application, -when view applications are distinct). Since each desktop can be -larger than the physical screen, divided into m by n pages which are -each the size of the physical screen, windows which are larger than -the screen or large groups of related windows can easily be viewed. - -The (m by n) size (i.e. number of pages) of the virtual desktops can be -changed any time, by using the DeskTopSize built-in command. All -virtual desktops must be (are) the same size. The total number of -distinct desktops need not be specified, but is limited to -approximately 4 billion total. All windows on a range of desktops can -be viewed in the Pager, a miniature view of the desktops. The pager -is an accessory program, called a module, which is not essential for -the window manager to operate. Windows may also be listed, along with -their geometries, in a window list, accessible as a pop-up menu, or as -a separate window, called the FvwmWinList (another module). - -"Sticky" windows are windows which transcend the virtual desktop by -"Sticking to the screen's glass." They always stay put on the screen. -This is convenient for things like clocks and xbiff's, so you only need -to run one such gadget and it always stays with you. Icons can also be -made to stick to the glass, if desired. - -Window geometries are specified relative to the current viewport. That -is: -.EX -xterm -geometry +0+0 -.EE -will always show up in the upper-left hand -corner of the visible portion of the screen. It is permissible to -specify geometries which place windows on the virtual desktop, but off -the screen. For example, if the visible screen is 1000 by 1000 pixels, -and the desktop size is 3x3, and the current viewport is at the upper -left hand corner of the desktop, then invoking: -.EX -xterm -geometry +1000+1000 -.EE -will place the window just off of the lower right hand corner of the -screen. It can be found by moving the mouse to the lower right hand -corner of the screen and waiting for it to scroll into view. - -A geometry specified as something like: -.EX -xterm -geometry -5-5 -.EE -will -generally place the window's lower right hand corner 5 pixels from the -lower right corner of the visible portion of the screen. Not all -applications support window geometries with negative offsets. Some will -place the window's upper right hand corner 5 pixels above and to the left -of the upper left hand corner of the screen; others may do just plain -bizarre things. - - -There are several ways to cause a window to map onto a desktop or page -other than the currently active one. The geometry technique mentioned above -(specifying x,y coordinates larger than the physical screen size), however, -suffers from the limitation of being interpreted relative to the current -viewport: the window will not consistently appear on a specific page, unless -you always invoke the application from the same page. - -A better way to place windows on a different page or desk from the -currently mapped viewport is to use the StartsOnPage style specification -(the successor to the older StartsOnDesk style) in the .fvwmrc configuration -file. The placement is consistent: it does not depend on your current location -on the virtual desktop. - -Some applications that understand standard Xt command line arguments -and X resources, like xterm and xfontsel, allow the user to specify -the start-up desk or page on the command line: -.EX -xterm -xrm "*Desk:1" -.EE -will start an xterm on desk number 1; -.EX -xterm -xrm "*Page:3 2 1" -.EE -will start an xterm two pages to the right and one down from the upper -left hand page of desk number 3. Not all applications understand the use -of these options, however. - -You could achieve the same results with the following lines in your -.Xdefaults file: -.EX -XTerm*Desk: 1 -.EE -or -.EX -XTerm*Page: 3 2 1 -.EE - -.SH INITIALIZATION -During initialization, \fIfvwm\fP will search for a configuration file -which describes key and button bindings, and a few other things. The -format of these files will be described later. First, \fIfvwm\fP will -search for a file named .fvwmrc in the user's home directory, then in -${sysconfdir} (typically __projectroot__/lib/X11/fvwm). -Failing that, it will look for system.fvwmrc in ${sysconfdir} for -system-wide defaults. If that file is not found, \fIfvwm\fP will be -basically useless. - -\fIFvwm\fP will set two environment variables which will be inherited -by its children. These are $DISPLAY which describes the display on -which \fIfvwm\fP is running. $DISPLAY may be unix:0.0 or :0.0, which -doesn't work too well when passed through rsh to another machine, so -$HOSTDISPLAY will also be set and will use a network-ready description -of the display. $HOSTDISPLAY will always use the TCP/IP transport -protocol (even for a local connection) so $DISPLAY should be used for -local connections, as it may use Unix-domain sockets, which are -faster. - -Fvwm has three special functions for initialization: -StartFunction, which is executed on startups and restarts; InitFunction -and RestartFunction, which are executed during Initialization and Restarts -(respectively) just after StartFunction. These may be customized -in a user's rc file via the AddToFunc facility (described later) to start up -modules, xterms, or whatever you'd like to have started by fvwm. - -\fIFvwm\fP also has a special exit function: ExitFunction, executed -when exiting or restarting before actually quitting or anything else. -It could be used to explicitly kill modules, etc. - -.SH COMPILATION OPTIONS -\fIFvwm\fP has a number of compile-time options to reduce memory usage -by limiting the use of certain features. If you -have trouble using a certain command or feature, check to see if -support for it was included at compile time. Optional features are -described in the config.h file. - -.SH ICONS -The basic \fIFvwm\fP configuration uses monochrome bitmap icons, -similar to \fItwm\fP. If XPM extensions are compiled in, then color -icons similar to ctwm, MS-Windows, or the Macintosh icons can be used. -In order to use these options you will need the XPM package, as -described in the INSTALL.fvwm file. - -If both the SHAPE and XPM options are compiled in you will get shaped -color icons, which are very spiffy. - -.SH MODULES -A module is a separate program which runs as a separate Unix process -but transmits commands to \fIfvwm\fP to execute. Users can write -their own modules to do any weird or bizarre manipulations without -bloating or affecting the integrity of \fIfvwm\fP itself. - -Modules MUST be spawned by \fIfvwm\fP so that it can set up two pipes for -\fIfvwm\fP and the module to communicate with. The pipes will already be -open for the module when it starts and the file descriptors for the -pipes are provided as command line arguments. - -Modules can be spawned during \fIfvwm\fP at any time during the X -session by use of the Module built-in command. Modules can exist for -the duration of the X session, or can perform a single task and exit. -If the module is still active when \fIfvwm\fP is told to quit, then -\fIfvwm\fP will close the communication pipes and wait to receive a -SIGCHLD from the module, indicating that it has detected the pipe -closure and has exited. If modules fail to detect the pipe closure -\fIfvwm\fP will exit after approximately 30 seconds anyway. The -number of simultaneously executing modules is limited by the operating -system's maximum number of simultaneously open files, usually between -60 and 256. - -Modules simply transmit text commands to the \fIfvwm\fP built-in -command engine. Text commands are formatted just as in the case of a -mouse binding in the .fvwmrc setup file. Certain auxiliary -information is also transmitted, as in the sample module FvwmButtons. -The FvwmButtons module is documented in its own man page. - -.SH ICCCM COMPLIANCE -\fIFvwm\fP attempts to be ICCCM 1.1 compliant. In addition, ICCCM -states that it should be possible for applications to receive ANY -keystroke, which is not consistent with the keyboard shortcut approach -used in \fIfvwm\fP and most other window managers. In particular you -cannot have the same keyboard shortcuts working with your fvwm2 and -another fvwm2 running within Xnest (a nested X server). The same problem -exists with mouse bindings. - -The ICCCM states that windows possessing the property -.EX -WM_HINTS(WM_HINTS): - Client accepts input or input focus: False -.EE -should not be given the keyboard input focus by the window manager. -These windows can take the input focus by themselves, however. A -number of applications set this property, and yet expect the -window-manager to give them the keyboard focus anyway, so fvwm -provides a window-style, "Lenience", which will allow fvwm to overlook -this ICCCM rule. - - -.SH M4 PREPROCESSING -.PP -M4 pre-processing is handled by a module in fvwm-2.0. To get more -details, try man FvwmM4. In short, if you want fvwm to parse your -files with m4, then replace the word "Read" with "FvwmM4" in -your .fvwmrc file (if it appears at all), and start fvwm with the -command -.EX -fvwm -cmd "FvwmM4 .fvwmrc" -.EE - -.SH CPP PREPROCESSING -.PP -Cpp is the C-language pre-processor. fvwm-2.0 offers cpp processing -which mirrors the m4 pre-processing. To find out about it, re-read -the M4 section above, but replace "m4" with "cpp". - -.SH AUTO-RAISE -.PP -Windows can be automatically raised when it receives focus, or some -number of milliseconds after it receives focus, by using the -auto-raise module, FvwmAuto. - -.SH OPTIONS -These are the command line options that are recognized by \fIfvwm\fP: -.IP "\fB-blackout\fP" -The screen is blacked out during window recaptures and startup. This option -is provided for backwards compatibility only. -.IP "\fB-cmd\fP \fIconfig_command\fP" -Causes \fIfvwm\fP to use \fIconfig_command\fP instead of "Read .fvwmrc" -as its initialization command. -(Note that up to 10 \fB-f\fP and \fB-cmd\fP parameters can be given, -and they are executed in the order specified.) -.IP "\fB-d\fP \fIdisplayname\fP" -Manage the display called "displayname" instead of the name obtained from -the environment variable $DISPLAY. -.IP "\fB-debug\fP" -Puts X transactions in synchronous mode, which dramatically slows things -down, but guarantees that \fIfvwm\fP's internal error messages are correct. -Also causes \fIfvwm\fP to output debug messages while running. -.IP "\fB-f\fP \fIconfig_file\fP" -Causes \fIfvwm\fP to Read \fIconfig_file\fP instead of ".fvwmrc" -as its initialization file. This is equivalent to -\fB-cmd\fP "Read \fIconfig_file\fP". -.IP "\fB-h\fP" -A short usage description is printed. -.IP "\fB-s\fP" -On a multi-screen display, run \fIfvwm\fP only on the screen named in -the $DISPLAY environment variable or provided through the -d -option. Normally, \fIfvwm\fP will attempt to start up on all screens -of a multi-screen display. -.IP "\fB-version\fP" -Print the version of \fIfvwm\fP to stderr. - -.SH CONFIGURATION FILES -The configuration file is used to describe mouse and button bindings, -colors, the virtual display size, and related items. The -initialization configuration file is typically called ".fvwmrc". By -using the "Read" built-in, it is easy to read in new configuration -files as you go. - -Lines beginning with '#' will be ignored by \fIfvwm\fP. Lines -starting with '*' are expected to contain module configuration -commands (rather than configuration commands for \fIfvwm\fP itself). - -Fvwm makes no distinction between configuration commands and built-in -commands, so anything mentioned in the built-in commands section can -be placed on a line by itself for fvwm to execute as it reads the -configuration file, or it can be placed as an executable command in a -menu or bound to a mouse button or a keyboard key. It is left as an -exercise for the user to decide which function make sense for -initialization and which ones make sense for run-time. - -.SH BUILT IN FUNCTIONS -\fIFvwm\fP supports a set of built-in functions which can be bound to -keyboard or mouse buttons. If fvwm expects to find a built-in function -in a command, but fails, it will check to see if the specified command -should have been "Function (rest of command)" or "Module (rest of -command)". This allows complex functions or modules to be invoked in a -manner which is fairly transparent to the configuration file. - -Example: the .fvwmrc file contains the line "HelpMe". Fvwm will look -for a built-in command called "HelpMe", and will fail. Next it will -look for a user-defined complex function called "HelpMe". If no such -user defined function exists, Fvwm will try to execute a module called -"HelpMe". - -In previous versions of fvwm, quoting was critical and irrational in -the .fvwmrc file. As of fvwm-2, most of this has been cleared up. -Quotes are required only when needed to make fvwm consider two or more -words to be a single argument. Unnecessary quoting is allowed. If you -want a quote character in your text, you must escape it by using the -backslash character. For example, if you have a pop-up menu called -Window-Ops, then you don't need quotes: Popup Window-Ops, but if you -replace the dash with a space, then you need quotes: Popup "Window -Ops". - - -.IP "AddButtonStyle \fIbutton\fP [ \fIstate\fP ] [ \fIstyle\fP ] [-- \fI[!]flag ...\fP]" -Adds a button style to \fIbutton\fP. \fIbutton\fP can be a button -number, or one of "All," "Left," or "Right." \fIstate\fP can be -"ActiveUp," "ActiveDown" or "Inactive." If \fIstate\fP is omitted, -then the style is added to every state. If the button style and flags -are enclosed in parentheses, then multiple state definitions can be -placed on a single line. Flags for additional button styles cannot be -changed after definition. - -Buttons are drawn in the order of definition, beginning with the most -recent ButtonStyle, followed by those added with AddButtonStyle. To -clear the button style stack, change style flags, or for descriptions -of available styles and flags, see the ButtonStyle command. Examples: -.EX -ButtonStyle 1 Pixmap led.xpm -- Top Left -ButtonStyle 1 ActiveDown HGradient 8 grey \\ - black -ButtonStyle All -- UseTitleStyle -AddButtonStyle 1 ActiveUp (Pixmap a.xpm) \\ - ActiveDown (Pixmap b.xpm -- Top) -AddButtonStyle 1 Vector 4 50x30@1 70x70@0 \\ - 30x70@0 50x30@1 -.EE -Initially for this example all button states are set to a pixmap. The -second line replaces the ActiveDown state with a gradient (it -overrides the pixmap assigned to it in the line before, which assigned -the same style to every state). Then, the UseTitleStyle flag is set -for all buttons, which causes \fIfvwm\fP to draw any styles set with -TitleStyle before drawing the buttons. Finally, AddButtonStyle is -used to place additional pixmaps for both ActiveUp and ActiveDown -states and a Vector button style is drawn on top of all state. - - -.IP "AddTitleStyle [ \fIstate\fP ] [ \fIstyle\fP ] [ -- \fI[!]flag ...\fP ]" -Adds a title style to the title bar. \fIstate\fP should be one of -"ActiveUp," "ActiveDown," or "Inactive." If \fIstate\fP is omitted, -then the style is added to every state. If the style and flags are -enclosed in parentheses, then multiple state definitions can be placed -on a single line. This command is quite similar to the AddButtonStyle -command (see above). - -Title bars are drawn in the order of definition, beginning with the -most recent TitleStyle, followed by those added with AddTitleStyle. -To clear the title style stack, change style flags, or for the -descriptions of available styles and flags, see the TitleStyle and -ButtonStyle commands. - - -.IP "AddToDecor \fIdecor\fP" -Add or divert commands to the decor named \fIdecor\fP. A decor is a -name given to the set of commands which affect button styles, -title-bar styles, border styles, hilight colors, and window fonts. If -\fIdecor\fP does not exist it is created; otherwise the existing -\fIdecor\fP is modified. - -Created decors start out exactly like the default fvwm decor without -any style definitions. A given decor may be applied to a set of -windows with the UseDecor option of the Style command. Modifying an -existing decor will affect windows which are currently assigned to it. - -AddToDecor is similar in usage to the AddToMenu and AddToFunc -commands, except that menus and functions are replaced by ButtonStyle, -AddButtonStyle, TitleStyle, AddTitleStyle, BorderStyle, HilightColor -and WindowFont commands. Decors created with AddToDecor can be -manipulated with ChangeDecor, DestroyDecor, UpdateDecor, and the -UseDecor Style option. - -The following example creates a decor and style, both named -"flatness." Despite having the same name, they are distinct entities: -.EX -AddToDecor flatness - + ButtonStyle All ActiveUp (-- flat) \\ - Inactive (-- flat) - + TitleStyle -- flat - + BorderStyle -- HiddenHandles NoInset - + HilightColor white navy -Style "flatness" UseDecor flatness, \\ - Color white/grey40,HandleWidth 4 - -Style "xterm" UseStyle flatness -.EE -An existing window's decor may be reassigned with ChangeDecor, or a -Style command followed by a Recapture. The decorations of all windows -or of a specific decor can be updated with UpdateDecor (useful after -decorations are modified; changing Style options requires a Recapture -instead). A decor can be destroyed with DestroyDecor. - - -.IP "AddToFunc [ \fIname\fP [ \fItrigger\fP \fIaction\fP] ]" -Begins or add to a function definition. Here's an example: -.EX -AddToFunc Move-or-Raise "I" Raise - + "M" Move - + "D" Lower -.EE -The function name is Move-or-Raise, and could be invoked from a menu -or a mouse binding or key binding: -.EX -Mouse 1 TS A Move-or-Raise -.EE -The quoted portion of the function tells what kind of action will -trigger the command which follows it. "I" stands for Immediate, and is -executed as soon as the function is invoked. "M" stands for Motion, i.e. -if the user starts moving the mouse. "C" stands for Click, i.e., if the -user presses and releases the mouse in a short period of time -(ClickTime milliseconds). "D" stands for double-click. The action "I" -will cause an action to be performed on the button-press, if the -function is invoked with prior knowledge of which window to act on. - -The special symbols $d, $w and $0 through $9 are available in the -ComplexFunctions or Macros, or whatever you want to call them. Within -a macro, $w is expanded to the window-id (expressed in -hex, i.e. 0x10023c) of the window for which the macro was called -and $d is expanded to the current desk number. $0 -through $9 are the arguments to the macro, so if you call -.EX -Key F10 R A Function MailFunction \\ - xmh "-font fixed" -.EE -and MailFunction is - -.EX -AddToFunc MailFunction - + "I" Next ($0) Iconify -1 - + "I" Next ($0) focus - + "I" None ($0) Exec exec $0 $1 -.EE -Then the last line of the function becomes -.EX - + "I" None (xmh) Exec exec xmh -font fixed -.EE -The expansion is performed as the function is executed, so you can use the -same function with all sorts of different arguments. I could use -.EX -Key F11 R A Function MailFunction \\ - zmail "-bg pink" -.EE -in the same .fvwmrc, if I wanted. An example of using $w is: -.EX -AddToFunc PrintFunction - + "I" Raise - + "I" Exec xdpr -id $w -.EE -Note that $$ is expanded to $. - - -.IP "AddToMenu \fImenu-name\fP [ \fImenu-label\fP \fIaction\fP ]" -Begins or adds to a menu definition. Typically a menu definition looks -like this: -.EX -AddToMenu Utilities "Utilities" Title - + "Xterm" Exec exec xterm -e tcsh - + "Rxvt" Exec exec rxvt - + "Remote Logins" Popup Remote-Logins - + "Top" Exec exec rxvt -T Top -n \\ - Top -e top - + "Calculator" Exec exec xcalc - + "Xmag" Exec exec xmag - + "emacs" Exec exec xemacs - + "Mail" MailFunction \\ - xmh "-font fixed" - + "" Nop - + "Modules" Popup Module-Popup - + "" Nop - + "Exit Fvwm" Popup Quit-Verify -.EE -The menu could be invoked via -.EX -Mouse 1 R A Menu Utilities Nop -.EE -or -.EX -Mouse 1 R A Popup Utilities -.EE -There is no end-of-menu symbol. Menus do not have to be defined in a -contiguous region of the .fvwmrc file. The quoted portion in the -above examples is the menu-label, which will appear in the menu when -the user pops it up. The remaining portion is a built-in command -which should be executed if the user selects that menu item. An empty -menu-label ("") and the Nop function can be used to insert a separator -into the menu. - -Titles can be used within the menu. If you add the option "top" behind -the keyword "Title", the title will be added to the top of the menu. -If there was a title already, it is overwritten. - -.EX -AddToMenu Utilities "Tools" Title top -.EE - -All text up to the first TAB in the menu label is aligned to the -left side of the menu, all text right of the first TAB is aligned -to the right side. All other TABs are replaced by spaces. - -If the menu-label contains an ampersand ('&'), the next character -is taken as a hotkey for the menu item. Hotkeys are underlined in -the label. To get a literal '&', insert '&&'. - -If the menu-label contains a sub-string which is set off by stars, -then the text between the stars is expected to be the name of an -xpm-icon or bitmap-file to insert in the menu. To get a literal '*', -insert '**'.For example -.EX - + "Calculator*xcalc.xpm*" Exec exec xcalc -.EE -inserts a menu item labeled "calculator" with a picture of a -calculator above it. The following: -.EX - + "*xcalc.xpm*" Exec exec xcalc -.EE -Omits the "Calculator" label, but leaves the picture. - -If the menu-label contains a sub-string which is set off by percent signs, -then the text between the percent signs is expected to be the name of an -xpm-icon or bitmap-file to insert to the left of the menu label. -To get a literal '%', insert '%%'. For example -.EX - + "Calculator%xcalc.xpm%" Exec exec xcalc -.EE -inserts a menu item labeled "calculator" with a picture of a -calculator to the left. The following: -.EX - + "%xcalc.xpm%" Exec exec xcalc -.EE -Omits the "Calculator" label, but leaves the picture. The pictures -used with this feature should be small (perhaps 16x16). - -If the menu-name (not the label) contains a sub-string which is set -off by at signs ("@"), then the text between them is expected to be -the name of an xpm or bitmap file to draw along the left side of the -menu (a "side pixmap"). You will probably want to use the SidePic -option of the \fIMenuStyle\fP command instead. To get a literal '@', -insert '@@'. For example -.EX -AddToMenu "StartMenu@linux-menu.xpm@" -.EE -creates a menu with a picture in its bottom left corner. - -If the menu-name contains also a sub-string set of by '^'s, then the -text between '^'s is expected to be the name a of X11 color and the -column containing the side picture will be colorized with that -color. You can set this color for a menu style using the SideColor -option of the \fIMenuStyle\fP command. To get a literal '^', insert -'^^'. Example: -.EX -AddToMenu "StartMenu@linux-menu.xpm@^blue^" -.EE -creates a menu with a picture in its bottom left corner and colorizes -with blue the region of the menu containing the picture. - -In all the above cases, the name of the resulting menu is name specified, -stripped of the substrings between the various delimiters. - - -.IP "AnimatedMove \fIx y\fP [ \fIWarp\fP ]" - -Move a window in an animated way. Similar to Move command, below. -Options are the same, except they are required, since it doesn't make -sense to have a user move the window interactively and animatedly. If -the optional argument \fIWarp\fP is specified the pointer is warped with -the window. - - -.IP "Beep" -As might be expected, this makes the terminal beep. - - -.IP "BorderStyle [ \fIstate\fP ] [ \fIstyle\fP ] [ -- \fI[!]flag ...\fP ]" -Defines a border style for windows. \fIstate\fP can be either -"Active" or "Inactive." If \fIstate\fP is omitted, then the style is -set for both states. If the style and flags are enclosed in -parentheses, then multiple state definitions can be specified per -line. - -\fIstyle\fP is a subset of the available ButtonStyles, and can only be -TiledPixmap (uniform pixmaps which match the bevel colors work best -this way). If an "!" is prefixed to any flag, flag behavior is -negated. If \fIstyle\fP is not specified, then one can change flags -without resetting the style. - -The "HiddenHandles" flag hides the corner handle dividing lines on -windows with handles (this option has no effect for NoHandle windows). -By default, HiddenHandles is disabled. - -The "NoInset" flag supplements HiddenHandles. If given, the inner -bevel around the window frame is not drawn. If HiddenHandles is not -specified, this flag has no effect. - -To decorate the active and inactive window borders with a textured -pixmap, one might specify: -.EX -BorderStyle Active TiledPixmap marble.xpm -BorderStyle Inactive TiledPixmap granite.xpm -BorderStyle Active -- HiddenHandles NoInset -.EE -To clear the style for both states: -.EX -BorderStyle Simple -.EE -To clear for a single state: -.EX -BorderStyle Active Simple -.EE -To unset a flag for a given state: -.EX -BorderStyle Inactive -- !NoInset -.EE -Title-bar buttons can inherit the border style with the UseBorderStyle -flag (see ButtonStyle). - - -.IP "ButtonStyle \fIbutton\fP [ \fIstate\fP ] [ \fIstyle\fP ] [ -- \fI[!]flag ...\fP ]" -Sets the button style for a title-bar button. \fIbutton\fP is the -title-bar button number between 0 and 9, or one of "All," "Left," -"Right," or "Reset." Button numbering is described in the Mouse -section (see below). If the style and flags are enclosed in -parentheses, then multiple state definitions can be specified per -line. - -\fIstate\fP refers to which button state should be set. Button states -are defined as follows: "ActiveUp" and "ActiveDown" refer to the -unpressed and pressed states for buttons on active windows; while the -"Inactive" state denotes buttons on inactive windows. - -If \fIstate\fP is ActiveUp, ActiveDown, or Inactive, that particular -button state is set. If \fIstate\fP is omitted, every state is set. -Specifying a style destroys the current style (use AddButtonStyle to -avoid this). - -If \fIstyle\fP is omitted, then state-dependent flags can be set for -the primary button style without destroying the current style. -Examples (each line should be considered independent): -.EX -ButtonStyle Left -- flat -ButtonStyle All ActiveUp (-- flat) \\ - Inactive (-- flat) -.EE -The first line sets every state of the left buttons to flat, while the -second sets only the ActiveUp and Inactive states of every button to -flat (only flags are changed; the buttons' individual styles are not -changed). - -If you want to reset all buttons to their defaults: -.EX -ButtonStyle Reset -.EE -To reset the ActiveUp button state of button 1 to the default: -.EX -ButtonStyle 1 ActiveUp Default -.EE -To reset all button states of button 1 to the default of -button number 2: -.EX -ButtonStyle 1 Default 2 -.EE - -For any given button, multiple state definitions can be given on one -line by enclosing the style and flags in parentheses. If only one -definition per line is given the parentheses can be omitted. - -\fIflags\fP affect the specified \fIstate\fP. If an "!" is prefixed -to any \fIflag\fP, its behavior is negated. The available -state-dependent flags for all styles are described here (the next -ButtonStyle entry deals with state-independent flags). - -"Raised" causes a raised relief pattern to be drawn. - -"Sunk" causes a sunken relief pattern to be drawn. - -"Flat" inhibits the relief pattern from being drawn. - -"UseTitleStyle" causes the given button state to render the current -title style before rendering the button's own styles. The Raised, -Flat, and Sunk TitleStyle flags are ignored since they are redundant -in this context. - -"UseBorderStyle" causes the button to inherit the decorated -BorderStyle options. - -Raised, Sunk, and Flat are mutually exclusive, and can be specified -for the initial ButtonStyle only. UseTitleStyle and UseBorderStyle -are also mutually exclusive (both can be off however). The default is -Raised with both UseBorderStyle and UseTitleStyle left unset. - -There is an \fBimportant note\fP for the ActiveDown state. When a -button is pressed, the relief is inverted. Because of this, to obtain -a sunken ActiveDown state you must specify the opposite of the desired -relief (i.e. to obtain a pressed-in look which is raised, specify Sunk -for ActiveDown). This behavior is consistent, but may seem confusing -at first. - -Button styles are classified as non-destructive, partially destructive, -or fully destructive. Non-destructive styles do not affect the image. -Partially destructive styles can obscure some or all parts of the -underlying image (i.e. Pixmap). Fully destructive styles obscure the -entire underlying image (i.e. Solid or one of the gradient styles). -Thus, if stacking styles with AddButtonStyle (or AddTitleStyle for -title bars), use care in sequencing styles to minimize redraw. - -The available styles and their arguments now follow (depending on -compilation options, some button styles may be unavailable). - -The "Simple" style does nothing. There are no arguments, and this -style is an example of a non-destructive button style. - -The "Default" style conditionally accepts one argument: a number which -specifies the default button number to load. If the style command -given is ButtonStyle or AddButtonStyle, the argument is optional (if -given, will override the current button). If a command other than -ButtonStyle or AddButtonStyle is used, the number must be specified. - -The "Solid" style fills the button with a solid color. The relief -border color is not affected. The color should be specified as a -single argument. This style is fully destructive. - -The "Vector" style draws a line pattern. Since this is a standard -button style, the keyword "Vector" is optional. The specification is -a little cumbersome: -.EX -ButtonStyle 2 Vector 4 50x30@1 70x70@0 \\ - 30x70@0 50x30@1 -.EE -then the button 2 decoration will use a 4-point pattern consisting of -a line from (x=50,y=30) to (70,70) in the shadow color (@0), and then -to (30,70) in the shadow color, and finally to (50,30) in the -highlight color (@1). Is that too confusing? See the sample .fvwmrc -for a few examples. This style is partially destructive. - -The "VGradient" and "HGradient" styles denote gradient styles. The H -and V prefixes denote both horizontal and vertical directions. - -This style has two forms: - -.in +2 -The first form specifies a linear gradient. Arguments: total number -of colors to allocate (between 2 and 128), the initial color, and the -final color. - -The second form specifies a nonlinear gradient. Arguments: total -number of colors to allocate (between 2 and 128), then the number of -segments. For each segment, specify the starting color, percentage to -increment, then ending color. Each subsequent segment begins with the -color of the last segment. All of the percentages must add up to 100. -.in -2 - -Example: -.EX -TitleStyle VGradient 16 3 Red 20 Blue 30 \\ - Black 50 Grey -.EE -The gradient styles are fully destructive. - -The "Pixmap" style displays a pixmap. A pixmap should be specified as -an argument. For example, the following would give button 2 the same -pixmap for both states, and button 4 different pixmaps for the up, -down and inactive states. -.EX -ButtonStyle 2 Pixmap my_pixmap.xpm -ButtonStyle 4 ActiveUp (Pixmap up.xpm) \\ - ActiveDown (Pixmap down.xpm) -ButtonStyle 4 Inactive Pixmap inactive.xpm -.EE -The pixmap specification can be given as an absolute or relative -pathname (see PixmapPath). If the pixmap cannot be found, the button -style reverts to Simple. Flags specific to the Pixmap style are -"Left," "Right," "Top," and "Bottom." These can be used to justify -the pixmap (default is centered for both directions). Pixmap -transparency is used for the color "None." This style is partially -destructive. - -The "MiniIcon" style draws the window's miniature icon in the button, -which is specified with the MiniIcon option of the Style command. This -button style accepts no arguments. Example: -.EX -Style "*" MiniIcon mini-bx2.xpm -Style "xterm" MiniIcon mini-term.xpm -Style "Emacs" MiniIcon mini-doc.xpm - -ButtonStyle 1 MiniIcon -.EE - -The "TiledPixmap" style accepts a pixmap to be tiled as the button -background. One pixmap is specified as an argument. Pixmap -transparency is not used. This style is fully destructive. - - -.IP "ButtonStyle \fIbutton\fP - \fI[!]flag ...\fP" -Sets state-independent flags for the specified \fIbutton\fP. -State-independent flags affect button behavior. Each flag is -separated by a space. If an "!" is prefixed to the flag then the flag -behavior is negated. The special flag "Clear" clears any existing -flags. - -The following flags are usually used to tell fvwm which buttons should -be affected by MWM function hints. This is not done automatically -since you might have buttons bound to complex functions, for instance. - -"MWMDecorMenu" should be assigned to title bar buttons which display a -menu. The default assignment is the leftmost button. When a window -with the MWMFunctions Style option requests not to show this button, -it will be hidden. - -"MWMDecorMin" should be assigned to title bar buttons which minimize -or iconify the window. The default assignment is the second button -over from the rightmost button. When a window with the MWMFunctions -Style option requests not to show this button, it will be hidden. - -"MWMDecorMax" should be assigned to title bar buttons which maximize -the window. The default assignment is the rightmost button. When a -window with the MWMFunctions Style option requests not to show this -button, it will be hidden. - - -.IP "ChangeDecor \fIdecor\fP" -Changes the decor of a window to \fIdecor\fP. \fIdecor\fP is -"Default," or the name of a decor defined with AddToDecor. If -\fIdecor\fP is invalid, nothing occurs. If called from somewhere in a -window or its border, then that window is affected. If called from -the root window the user will be allowed to select the target window. -ChangeDecor only affects attributes which can be set using the -AddToDecor command. -.EX -ChangeDecor "CustomDecor1" -.EE - -.IP "ChangeMenuStyle \fImenustyle menu ...\fP" -Changes the menu style of "menu" to "menustyle", you may specified more -than one menu in each \fIChangeMenuStyle\fP. -.EX -ChangeMenuStyle pixmap1 Screensavers ScreenLock -.EE - -.IP "ClickTime [ \fIdelay\fP ]" -Specifies the maximum delay (in milliseconds) between a button press -and a button release for the Function built-in to consider the action -a mouse click. The default delay is 150 milliseconds. Omitting the -delay value resets the ClickTime to the default. - - -.IP "Close" -If the window accepts the delete window protocol a message is sent to -the window asking it to gracefully remove itself. If the window does -not understand the delete window protocol then the window is -destroyed. - - -.IP "ColorLimit \fIlimit\fP" -Specifies a limit on the colors used in pixmaps used by fvwm. Zero -(the default) sets no limit. Fvwm uses pixmaps for icons, -mini-icons, and pixmap borders and titles. This command limits pixmap -colors to a set of colors that starts out with common colors. The -current list contains about 60 colors and starts with white, black, -grey, green, blue, red, cyan, yellow, and magenta. The command -"ColorLimit 9" would limit pixmaps to these 9 colors. - -It makes the most sense to put this command at the front of the -.fvwmrc file. This command should be before any menu -definitions that contain mini-icons. - -Solid frame and title colors (including shadows and gradients) are not -controlled by this command. - - -.IP "ColormapFocus \fIFollowsMouse\fP|\fIFollowsFocus\fP" -By default, fvwm installs the colormap of the window that the cursor -is in. If you use ColormapFocus FollowsFocus, then the installed -colormap will be the one for the window that currently has the -keyboard focus. - - -.IP "Current (\fIconditions\fP) \fIcommand\fP" -Performs \fIcommand\fP on the current window if it satisfies all -\fIconditions\fP. Conditions include "Iconic", "!Iconic", "Visible", -"!Visible", "Sticky", "!Sticky", "Maximized", "!Maximized", -"Transient", "!Transient", "Raised", "!Raised", "CurrentDesk", -"CurrentPage", and "CurrentPageAnyDesk". In addition, the condition -may include a window name to match to. The window name may include -the wildcards * and ?. The window name, icon name, class, and -resource will be considered when attempting to find a match. The -window name can begin with ! which will prevent \fIcommand\fP if any -of the window name, icon name, class or resource match. - -Note that earlier versions of fvwm2 required the conditions to be -enclosed in brackets instead of parentheses (this is still supported -for backwards compatibility). - - -.IP "CursorMove \fIhorizontal vertical\fP" -Moves the mouse pointer by \fIhorizontal\fP pages in the X direction -and \fIvertical\fP pages in the Y direction. Either or both entries -may be negative. Both horizontal and vertical values are expressed in -percent of pages, so "CursorMove 100 100" means to move down and right -by one full page. "CursorMove 50 25" means to move right half a page -and down a quarter of a page. Alternatively, the distance can be -specified in pixels by appending a 'p' to the horizontal and/or vertical -specification. For example "CursorMove -10p -10p" means move ten -pixels up and ten pixels left. The CursorMove function should not be -called from pop-up menus. - -.IP "CursorStyle \fIcontext cursornum\fP" -Defines a new cursor for the specified context. The various contexts -are: - -.in +.5i -POSITION (XC_top_left_corner) -.in +.3i -used when initially placing windows -.in -.3i - -TITLE (XC_top_left_arrow) -.in +.3i -used in a window title-bar -.in -.3i - -DEFAULT (XC_top_left_arrow) -.in +.3i -used in windows that don't set their cursor -.in -.3i - -SYS (XC_hand2) -.in +.3i -used in one of the title-bar buttons -.in -.3i - -MOVE (XC_fleur) -.in +.3i -used when moving or resizing windows -.in -.3i - -WAIT (XC_watch) -.in +.3i -used during an EXEC builtin command -.in -.3i - -MENU (XC_sb_left_arrow) -.in +.3i -used in menus -.in -.3i - -SELECT (XC_dot) -.in +.3i -used for various builtin commands such as iconify -.in -.3i - -DESTROY (XC_pirate) -.in +.3i -used for DESTROY, CLOSE, and DELETE built-ins -.in -.3i - -TOP (XC_top_side) -.in +.3i -used in the top side-bar of a window -.in -.3i - -RIGHT (XC_right_side) -.in +.3i -used in the right side-bar of a window -.in -.3i - -BOTTOM (XC_bottom_side) -.in +.3i -used in the bottom side-bar of a window -.in -.3i - -LEFT (XC_left_side) -.in +.3i -used in the left side-bar of a window -.in -.3i - -TOP_LEFT (XC_top_left_corner) -.in +.3i -used in the top left corner of a window -.in -.3i - -TOP_RIGHT (XC_top_right_corner) -.in +.3i -used in the top right corner of a window -.in -.3i - -BOTTOM_LEFT (XC_bottom_left_corner) -.in +.3i -used in the bottom left corner of a window -.in -.3i - -BOTTOM_RIGHT (XC_bottom_right_corner) -.in +.3i -used in the bottom right corner of a window -.in -.3i -.in -.5i - -And the cursornum is the numeric value of the cursor as defined in the -include file X11/cursorfont.h. An example: -.EX -\&# make the kill cursor be XC_gumby: -CursorStyle DESTROY 56 -.EE -The defaults are shown in parenthesis above. - - -.IP "DefaultColors [ \fI foreground background\fP ]" -\fIDefaultColors\fP sets the default forground and background -colors used in miscellaneous windows created by fvwm, for example -in the geometry feedback windows during a move or resize operation. -If you don't want to change one color or the other, use - as its -color name. To revert to the builtin default colors omit both -color names. Note that the default colors are not used in menus, -window titles or icon titles. - - -.IP "DefaultFont [ \fIfontname\fP ]" -\fIDefaultFont\fP sets the default font to font \fIfontname\fP. -The default font is used by fvwm2 whenever no other font has been -specified. To reset the default font to the built in default, omit -the argument. The default font is used for menus, window titles, -icon titles as well as the geometry feedback windows during a move -or resize operation. To override the default font in a specific -context, use the \fIWindowFont\fP, \fIIconFont\fP or \fIMenuStyle\fP -commands. - - -.IP "Delete" -Sends a message to a window asking that it remove itself, frequently -causing the application to exit. - - -.IP "Desk \fIarg1\fP [ \fIarg2\fP ] [ \fImin max\fP ]" -Switches the current viewport to another desktop (workspace, room). - -The command takes 1, 2, 3, or 4 arguments. A single argument is -interpreted as a relative desk number. Two arguments are understood -as a relative and an absolute desk number. Three arguments specify -a relative desk and the minimum and maximum of the allowable range. -Four arguments specify the relative, absolute, minimum and maximum -values. (Desktop numbers can be negative.) - -If \fIarg1\fP is non zero then the next desktop number will be the -current desktop number plus \fIarg1\fP. - -If \fIarg1\fP is zero then the new desktop number will be \fIarg2\fP. -(If \fIarg2\fP is not present, then the command has no effect.) - -If \fImin\fP and \fImax\fP are given, the new desktop number will -be no smaller than min and no bigger than max. Values out of this -range are truncated (if you gave an absolute desk number) or wrapped -around (if you gave a relative desk number). - -The syntax is the same as for \fIMoveToDesk\fP, which moves a window -to a different desktop. - -The number of active desktops is determined dynamically. Only -desktops which contain windows or are currently being displayed are -active. Desktop numbers must be between 2147483647 and -2147483648 -(is that enough?). - - -.IP "DeskTopSize \fIHorizontal\fPx\fIVertical\fP" -Defines the virtual desktop size in units of the physical screen size. - - -.IP "Destroy" -Destroys an application window, which usually causes the application -to crash and burn. - - -.IP "DestroyDecor \fIdecor\fP" -Deletes the \fIdecor\fP defined with AddToDecor, so that subsequent -references to it are no longer valid. Windows using this \fIdecor\fP -revert to the default fvwm decor. The decor named "Default" cannot be -destroyed. -.EX -DestroyDecor "CustomDecor1" -.EE - - -.IP "DestroyFunc" -Deletes a function, so that subsequent references to it are no longer -valid. You can use this to change the contents of a function during an -fvwm session. The function can be rebuilt using AddToFunc. -.EX -DestroyFunc "PrintFunction" -.EE - - -.IP "DestroyMenu" -Deletes a menu, so that subsequent references to it are no longer -valid. You can use this to change the contents of a menu during an -fvwm session. The menu can be rebuilt using AddToMenu. -.EX -DestroyMenu "Utilities" -.EE - -.IP "DestroyMenuStyle \fImenustyle\fP" -Deletes the menu style named "menustyle" and changes all menus using -this style to the default style, you cannot destroy the default menu. -.EX -DestroyMenuStyle pixamp1 -.EE - -.IP "DestroyModuleConfig" -Deletes module configuration entries, so that new configuration lines -may be entered instead. You can use this to change the the way a -module runs during an fvwm session without restarting. Wildcards can -be used for portions of the name as well. -.EX -DestroyModuleConfig FvwmFormFore -DestroyModuleConfig FvwmButtons* -.EE - - -.IP "Direction \fIdirection\fP (\fIconditions\fP) \fIcommand\fP" -Performs \fIcommand\fP (typically Focus) on a window in the given -direction which satisfies all \fIconditions\fP. Conditions are the same -as for \fICurrent\fP. The \fIdirection\fP may be one of North, Northeast, -East, Southeast, South, Southwest, West and Northwest. Which window -Direction selects depends on angle and distance between the centerpoints -of the windows. Closer windows are considered a better match than -those farther away. - - -.IP "Echo \fIstring\fP" -Prints a message to stderr. Potentially useful for debugging things -in your .fvwmrc. -.EX -Echo Beginning style defs... -.EE - - -.IP "EdgeResistance \fIscrolling moving\fP" -Tells how hard it should be to change the desktop viewport by moving -the mouse over the edge of the screen and how hard it should be to -move a window over the edge of the screen. - -The first parameter tells how milliseconds the pointer must spend on -the screen edge before \fIfvwm\fP will move the viewport. This is -intended for people who use "EdgeScroll 100 100" but find themselves -accidentally flipping pages when they don't want to. - -The second parameter tells how many pixels over the edge of the screen -a window's edge must move before it actually moves partially off the -screen. By default the viewport is moved a full page in the requested -direction, but if you used \fIEdgeScroll\fP and set any values other -than zero they will be used instead. - -Note that, with "EdgeScroll 0 0", it is still possible to move or -resize windows across the edge of the current screen. By making the -first parameter to EdgeResistance 10000 this type of motion is -impossible. With EdgeResistance less than 10000 but greater than 0 -moving over pages becomes difficult but not impossible. -See also, EdgeThickness. - -.IP "EdgeScroll \fIhorizontal vertical\fP" -Specifies the percentage of a page to scroll when the cursor hits the -edge of a page. A trailing "p" changes the interpretation to mean "pixels". -If you don't want any paging or scrolling when you hit the edge of a -page include "EdgeScroll 0 0" in your .fvwmrc file, -or possibly better, set the EdgeThickness to zero. -See the EdgeThickness command. If you want whole -pages, use "EdgeScroll 100 100". Both horizontal and vertical should -be positive numbers. - -If the horizontal and vertical percentages are multiplied by 1000 then -scrolling will wrap around at the edge of the desktop. If "EdgeScroll -100000 100000" is used \fIfvwm\fP will scroll by whole pages, wrapping -around at the edge of the desktop. - -.IP "EdgeThickness \fI0\fP|\fI1\fP|\fI2\fP" -This is the width or height of the invisible window that fvwm2 creates -on the edges of the screen that are used for the edgescrolling feature. - -A value of zero completely disables mouse edge scrolling, even while -dragging a window. - -1 gives the smallest pan frames, which seem to work best except on -some servers. - -2 is the default. - -Pan frames of 1 or 2 pixels can sometimes be confusing, for example, -if you drag a window over the edge of the screen, so that it stradles -aa pan frame, clicks on the window, near the edge of the screen are -treated as clicks on the root window. - - -.IP "Emulate \fIfvwm\fP|\fImwm\fP|\fIwin\fP" -This command affects how miscellaneous things are done by fvwm. -For example where the move/resize feedback window appears depends -on this command. To have more MWM- or WIN-like behavior you can call -Emulate with "MWM" or "WIN" as its argument. - - -.IP "Exec \fIcommand\fP" -Executes \fIcommand\fP. You should not use an ampersand ``&'' at the -end of the command. You probably want to use an additional ``exec'' at -the beginning of \fIcommand\fP. Without that, the shell that fvwm -invokes to run your command will stay until the command exits. In -effect, you'll have twice as many processes running as you need. -Note that some shells are smart enough to avoid this, but it never hurts -to include the ``exec'' anyway. - -The following example binds function key F1 in the root window, with -no modifiers, to the exec function. The program rxvt will be started -with an assortment of options. -.EX -Key F1 R N Exec exec rxvt -fg yellow -bg blue \\ - -e /bin/tcsh -.EE - -Note that this function doesn't wait for \fIcommand\fP to complete, so -things like: -.EX -Exec "echo AddToMenu ... > /tmp/file" -Read /tmp/file -.EE -won't work reliably. - -.IP "ExecUseShell [ \fIshell\fP ]" -Makes the Exec command use the specified shell, or the value of the -$SHELL environment variable if no shell is specified, instead of the -default Bourne shell (/bin/sh). -.EX -ExecUseShell -ExecUseShell /usr/local/bin/tcsh -.EE - - -.IP "FlipFocus" -Executes a \fIFocus\fP command as if the user had used the pointer to -select the window. This command alters the order of the windowlist in -the same way as clicking in a window to focus, i.e. the target window is -removed from the windowlist and placed at the start. This command is -recommended for use with the \fIDirection\fP command and in the function -invoked from \fIWindowList\fP. - - -.IP "Focus" -Moves the viewport or window as needed to make the selected window -visible. Sets the keyboard focus to the selected window. Does not -automatically raise the window. Does not warp the pointer into -the selected window (see WarpToWindow function). Does not de-iconify. -This command does not alter the order of the windowlist, it rotates the -windowlist around so that the target window is at the start. - -To raise and warp a pointer together with Focus or FlipFocus, use a function: -.EX -AddToFunc SelectWindow -+ I Focus -+ I Raise -+ I WarpToWindow 50 8p -.EE - - -.IP "Function \fI\FunctionName\\fP" -Used to bind a previously defined function to a key or mouse button. - -The following example binds mouse button 1 to a function called -"Move-or-Raise", whose definition was provided as an example earlier -in this man page. After performing this binding \fIfvwm\fP will -execute to move-or-raise function whenever button 1 is pressed in a -window title-bar. -.EX -Mouse 1 T A Function Move-or-Raise -.EE -The keyword "Function" may be omitted if "FunctionName" does not -coincide with an fvwm built-in function name - - -.IP "GlobalOpts [ \fIoptions\fP ]" -This is a TEMPORARY command used to set some global options which will -later be handled as Style parms (or options to Style parms). It -currently handles the following: -SmartPlacementIsReallySmart/SmartPlacementIsNormal, -ClickToFocusDoesntPassClick/ClickToFocusPassesClick, -ClickToFocusDoesntRaise/ClickToFocusRaises, -MouseFocusClickDoesntRaise/MouseFocusClickRaises, -CaptureHonorsStartsOnPage/CaptureIgnoresStartsOnPage, -RecaptureHonorsStartsOnPage/RecaptureIgnoresStartsOnPage, -ActivePlacementHonorsStartsOnPage/ActivePlacementIgnoresStartsOnPage, -NoStipledTitles/StipledTitles - -Example: -.EX -GlobalOpts ClickToFocusDoesntPassClick, \\ - ClickToFocusDoesntRaise -.EE - -RecaptureHonorsStartsOnPage causes a window to be placed according to, or -revert to, the StartsOnPage desk and page specification on Restart or -Recapture. RecaptureIgnoresStartsOnPage causes fvwm to respect the current -window position on Restart or Recapture. The default is -RecaptureIgnoresStartsOnPage. - -CaptureHonorsStartsOnPage causes the initial capture (of an already -existing window) at startup to place the window according to the -StartsOnPage desk and page specification. CaptureIgnoresStartsOnPage -causes fvwm to ignore these settings (including StartsOnDesk) on -initial capture. The default is CaptureHonorsStartsOnPage. - -ActivePlacementIgnoresStartsOnPage suppresses StartsOnPage or StartsOnDesk -placement in the event that both ActivePlacement and SkipMapping are in -effect when a window is created. This prevents you from interactively -placing a window and then wondering where it disappeared to, because it got -placed on a different desk or page. ActivePlacementHonorsStartsOnPage -allows this to happen anyway. The option has no effect if SkipMapping is -not in effect, because fvwm will switch to the proper desk/page to perform -interactive placement. The default is ActivePlacementHonorsStartsOnPage, -which matches the way StartsOnDesk handled the situation. - -.IP "GotoPage x y" -Moves the desktop viewport to page (x,y). The upper left page is -(0,0), the upper right is (M,0), where M is one less than the current -number of horizontal pages specified in the DeskTopSize command. The -lower left page is (0,N), and the lower right page is (M,N), where N -is the desktop's vertical size as specified in the DeskTopSize -command. The GotoPage function should not be used in a pop-up menu. - - -.IP "HilightColor \fItextcolor backgroundcolor\fP" -Specifies the text and background colors for the decorations on the -window which currently has the keyboard focus. - - -.IP "IconFont [ \fIfontname\fP ]" -Makes \fIfvwm\fP use font \fIfontname\fP for icon labels. To reset -this font to the default font (see \fIDefaultFont\fP) you may omit -\fIfontname\fP. - - -.IP "Iconify [ \fIvalue\fP ]" -Iconifies a window if it is not already iconified or de-iconifies it -if it is already iconified. If the optional argument \fIvalue\fP is -positive only iconification will be allowed. If the optional -argument is negative only de-iconification will be allowed. - - -.IP "IconPath \fIpath\fP" -Specifies a colon separated list of full path names of directories -where bitmap (monochrome) icons can be found. Each path should start -with a slash. Environment variables can be used here as well (i.e. -$HOME or ${HOME}). - -Note: if the FvwmM4 is used to parse your rc files, then \fIm4\fP may -want to mangle the word "include" which will frequently show up in the -IconPath or PixmapPath command. To fix this add undefine(`include') -prior to the IconPath command, or better use the '-m4-prefix' option -to force all m4 directives to have a prefix of "m4_" (see the -\fIFvwmM4\fP man page). - - -.IP "ImagePath \fIpath\fP" -Specifies a colon separated list of directories in which to search -for images (both monochrome and pixmap). - -\fINOTE\fP: ImagePath makes obsolete IconPath and PixmapPath commands in the -next fvwm versions. In this version all of the three commands are allowed. - -The ImagePath may contain environment variables such as $HOME (or -${HOME}). Further, a '+' in the path is expanded to the previous -value of the path, allowing easy appending or prepending to the path. - -For example: -.EX -ImagePath $HOME/icons:+:__projectroot__/include/bitmaps -.EE - - -.IP "Key \fIkeyname Context Modifiers Function\fP" -Binds a keyboard key to a specified \fIfvwm\fP built-in function, or -removes the binding if \fIFunction\fP is '-'. Definition is the same -as for a mouse binding except that the mouse button number is replaced -with a key name. The \fIkeyname\fP is one of the entries from -__projectroot__/include/X11/keysymdef.h, with the leading XK_ omitted. The -\fIContext\fP and \fIModifiers\fP fields are defined as in the Mouse -binding. However, when you press a key the context window is the -window that has the keyboard focus. That is not necessarily the -same as the window the pointer is over (with SloppyFocus or -ClickToFocus). - -The following example binds the built in window list to pop up when -Alt-Ctrl-Shift-F11 is hit, no matter where the mouse pointer is: -.EX -Key F11 A SCM WindowList -.EE - -Binding a key to a title-bar button will not cause that button to -appear unless a mouse binding also exists. - - -.IP "KillModule \fIname\fP" -Causes the module which was invoked with name \fIname\fP to be killed. -\fIname\fP may include wild-cards. - - -.IP "Lower" -Allows the user to lower a window. - - -.IP "Maximize [ \fI horizontal vertical\fP ]" -Without its optional arguments Maximize causes the window to -alternately switch from a full-screen size to its normal size. - -With the optional arguments horizontal and vertical, which are -expressed as percentage of a full screen, the user can control the new -size of the window. If horizontal is greater than 0 then the -horizontal dimension of the window will be set to -horizontal*screen_width/100. The vertical resizing is similar. For -example, the following will add a title-bar button to switch a window -to the full vertical size of the screen: -.EX -Mouse 0 4 A Maximize 0 100 -.EE -The following causes windows to be stretched to the full width: -.EX -Mouse 0 4 A Maximize 100 0 -.EE -This makes a window that is half the screen size in each direction: -.EX -Mouse 0 4 A Maximize 50 50 -.EE -Values larger than 100 can be used with caution. - -If the letter "p" is appended to each coordinate (horizontal and/or -vertical), then the scroll amount will be measured in pixels. - - -.IP "Menu \fImenu-name\fP [ \fIposition\fP ] [ \fIdouble-click-action\fP ]" -Causes a previously defined menu to be popped up in a "sticky" manner. -That is, if the user invokes the menu with a click action instead of a -drag action, the menu will stay up. The command -\fIdouble-click-action\fP will be invoked if the user double-clicks -(or hits the key rapidly twice if the menu is bound to a key) when -bringing the menu up. - -Several other commands affect menu operation. See \fIMenuStyle\fP -and \fISetAnimation\fP. When in a menu, keyboard -shortcuts work as expected. Cursor keystrokes are also allowed. -Specifically, Cursor-Down, Ctrl-N, and Ctrl-J all move to the next -item; Cursor-Up, Ctrl-P, and Ctrl-K all move to the prior item; -Cursor-Left and Ctrl-B return to the prior menu; Cursor-Right and -Ctrl-F popup the next menu; Ctrl-Cursor-Up and Ctrl-Cursor-Down move -up and down five items, respectively; Shift-Cursor-Up and -Shift-Cursor-Down move to the first and last items, respectively; Enter -executes the current item; Escape exits the current sequence of menus. - -The pointer will be warped to where it was when the menu was invoked if -it was both invoked and terminated with a keystroke. - -The \fIposition\fP arguments allow to place the menu somewhere on the -screen, for example centered on the visible screen or above a title -bar. Basically it works like this: you specify a \fIcontext-rectangle\fP -and an offset to this rectangle by which the upper left corner of the menu -is moved from the upper left corner of the rectangle. The \fIposition\fP -arguments consist of several parts: -.EX -[ [context-rectangle] x y ] [ special-options ] -.EE -The \fIcontext-rectangle\fP can be one of: - -.in +.5i -Root -.in +.3i -the root window. -.in -.3i -Mouse -.in +.3i -a 1x1 rectangle at the mouse position. -.in -.3i -Window -.in +.3i -the window with the focus. -.in -.3i -Interior -.in +.3i -the inside of the focused window. -.in -.3i -Title -.in +.3i -the title of the focused window or icon. -.in -.3i -Button -.in +.3i -button #n of the focused window. -.in -.3i -Icon -.in +.3i -the focused icon. -.in -.3i -Menu -.in +.3i -the current menu. -.in -.3i -Item -.in +.3i -the current menu item. -.in -.3i -Context -.in +.3i -the current window, menu or icon. -.in -.3i -This -.in +.3i -whatever widget the pointer is on (e.g. a corner of a window or the root window). -.in -.3i -Rectangle -.in +.3i -the rectangle defined by <\fIgeometry\fP> in X geometry format. Width and height default to 1 if omitted. -.in -.3i -.in -.5i - -If the context-rectangle is omitted "Mouse" is the default. -Note that not all of these make sense under all circumstances -(e.g. "Icon" if the pointer is on a menu). - -The offset values \fIx\fP and \fIy\fP specify how far the menu is -moved from it's default position. By default, the numeric value given -is interpreted as a percentage of the context rectangle's width (height), -but with a trailing "m" the menu's width (height) is used instead. -Furthermore a trailing "p" changes the interpretation to mean "pixels". - -Instead of a single value you can use a list of values. All additional -numbers after the first one are separated from threir predecessor but -their sign. Do not use any other separators. - -If x or y are prefixed with 'o' where is an integer, the -menu and the rectangle will be moved to overlap at the specified position -before any other offsets are applied. The menu and the rectangle will be -placed so that the pixel at percent of the rectangle's width/height -is right over the pixel at percent of the menu's width/height. -So 'o0' means that the top/left borders of the menu and the rectangle -overlap, with 'o100' it's the bottom/right borders and if you use 'o50' -they are centered upon each other (try it and you will see it is much -simpler than this description). The default is 'o0'. The prefix -'o' is an abbreviation for '+-m'. - -A prefix of 'c' is equivalent of 'o50'. Examples: - -.EX -\&# window list in the middle of the screen -WindowList Root c c - -\&# menu to the left of a window -Menu name window -100m c+0 - -\&# popup menu 8 pixels above the mouse pointer -Popup name mouse c -100m-8p - -\&# somewhere on the screen -Menu name rectangle 512x384+1+1 +0 +0 - -\&# centered vertially around a menu item -AddToMenu foobar-menu - + "first item" Nop - + "special item" Popup "another menu" item \\ - +100 c - + "last item" Nop - -\&# above the first menu item -AddToMenu foobar-menu - + "first item" Popup "another menu" item +0 -100m -.EE -Note that you can put a submenu far off the current menu so you could -not reach it with the mouse without leaving the menu. If the pointer -leaves the current menu in the general direction of the submenu the -menu will stay up. - -The \fIspecial-options\fP: - -.in +.5i -The "animated" and "mwm" or "win" meny styles may move a menu somewhere -else on the screen. If you do not want this you can add \fIFixed\fP -as an option. This might happen for example if you want the menu always -in the top right corner of the screen. - -Where do you want a submenu to appear when you click on it's menu item? -The default is to place the title under the cursor, but if you want it -where the position arguments say, use the \fISelectInPlace\fP option. -If you want the pointer on the title of the menu, use \fISelectWarp\fP -too. - -The pointer is warped to the title of a submenu whenever the pointer -would be on an item when the submenu is popped up ("fvwm" menu style) or -never warped to thetitle at all ("mwm" or "win" menu styles). You can -force (forbid) warping whenever the submenu is opened with the -\fIWarpTitle\fP (\fINoWarp\fP) option. - -Note that the \fIspecial-options\fP do work with a normal menu that has -no other position arguments. -.in -.5i - -.IP "MenuStyle \fIstylename options\fP" -Sets a new menu style or changes a previously defined style. -The \fIstylename\fP is the style name; if it contains spaces or tabs it -has to be quoted. The name "*" is reserved for the default menu style. -The default menu style is used for every menu-like object (e.g. the -window created by the \fIWindowList\fP command) that had not be assigned -a style using the \fIChangeMenuStyle\fP. See also \fIDestroyMenuStyle\fP. -When using monochrome color options are ignored. - -\fIoptions\fP is a comma separated list containing some of the -keywords FVWM/MWM/WIN, -Foreground, -Background, -Greyed, -HilightBack/HilightBackOff, -ActiveFore/ActiveForeOff, -Hilight3DThick/Hilight3DThin/Hilight3DOff, -Animation/AnimationOff, -Font, -MenuFace, -PopupDelay, -PopupOffset, -TitleWarp/TitleWarpOff, -TitleUnderlines0/TitleUnderlines1/TitleUnderlines2, -SeparatorsLong/SeparatorsShort, -TrianglesSolid/TrianglesRelief, -PopupImmediately/PopupDelayed, -DoubleClickTime, -SidePic, -SideColor. - -In the above list some options are listed as option pairs or triples -with a / in between. These options exclude each other. - -\fIFVWM\fP, \fIMWM\fP, \fIWIN\fP reset all options to the style with -the same name in former versions of fvwm2. The default for new menu -styles is FVWM style. These options override all others except -Foreground, Background, Greyed, HilightBack, HilightFore and -PopupDelay, so they should be used only as the first option -specified for a menu style or to reset the style to defined bahavior. -The same effect can be created by setting all the other options one -by one. - -\fIMWM\fP and \fIWIN\fP style menus popup sub-menus automatically. -WIN menus indicate the current menu item by changing the -background to dark. \fIFVWM\fP sub-menus overlap the parent menu, -MWM and WIN style menus never overlap the parent menu. - -\fIFVWM\fP style is equivalent to HilightBackOff, Hilight3DThin, -ActiveForeOff, AnimationOff, Font, MenuFace, PopupOffset 0 67, TitleWarp, -TitleUnderlines1, SeparatorsShort, TriangleRelief, PopupDelayed. - -\fIMWM\fP style is equivalent to HilightBackOff, Hilight3DThick, -ActiveForeOff, AnimationOff, Font, MenuFace, PopupOffset -3 100, -TitleWarpOff, TitleUnderlines2, SeparatorsLong, TriangleRelief, -PopupImmediately. - -\fIWIN\fP style is equivalent to HilightBack, Hilight3DOff, -ActiveForeOff, AnimationOff, Font, MenuFace, PopupOffset -5 100, -TitleWarpOff, TitleUnderlines1, SeparatorsShort, TriangleSolid, -PopupImmediately. - -\fIForeground\fP and \fIBackground\fP may have a color name as an -argument. This color is used for menu text or the menu's background. -You can omit the color name to reset these colors to the built in default. - -\fIGreyed\fP may have a color name as an argument. This color is the -one used to draw a menu-selection which is prohibited (or not -recommended) by the mwm-hints which an application has specified. -If the color is omitted the color of "greyed" menu entries is based -on the background color of the menu. - -\fIHilightBack\fP and \fIHilightBackOff\fP switch hilighting the background -of the selected menu item on and off. A specific background color -may be used by providing the color name as an argument to -\fIHilightBack\fP. If you use this option without an argument the -color is based on the menu's background color. - -\fIActiveFore\fP and \fIActiveForeOff\fP switch hilighting the foreground -of the selected menu item on and off. A specific foreground color -may be used by providing the color name as an argument to -ActiveFore. Omitting the color name has the same effet as -using ActiveForeOff. - -\fIHilight3DThick\fP, \fIHilight3DThin\fP and \fIHilight3DOff\fP -determine if the selected menu item is hilighted with a 3D relief. -Thick reliefs are two pixels wide, thin reliefs are one pixel wide. - -\fIAnimation\fP and \fIAnimationOff\fP turn menu animation on or off. -When animation is on, sub-menus that don't fit on the screen cause -the parent menu to be shifted to the left so the sub-menu can be seen. - -\fIFont\fP takes a font name as an argument. If a font by this name -exists it is used for the text of all menu items. If it does not -exist or if the name is left blank the built in default is used. - -\fIMenuFace\fP enforces a fancy background upon the menus. You can -use the same options for MenuFace as for ButtonStyle plus DGradient, -(top-left to down-right) and BGradient (down-left to top-right). See -\fIButtonStyle\fP for more info. If you use MenuFace without arguments -the style is reverted back to normal. - -Some examples of MenuFaces are: - -.EX -MenuFace DGradient 128 2 lightgrey 50 blue 50 white -MenuFace TiledPixmap texture10.xpm -MenuFace HGradient 128 2 Red 40 Maroon 60 White -MenuFace Solid Maroon -.EE - -If you encounter performance problems with gradient backgrounds -you can try one or all of the following: - -Turn Hilighting of the active menu item other than forground color -off: - -.EX -MenuStyle Hilight3DOff, HilightBackOff -MenuStyle ActiveFore -.EE - -Make sure submenus do not overlap the parent menu. This can prevent -menus being redrawn every time a submenu pops up or down. - -.EX -MenuStyle PopupOffset 1 100 -.EE - -Run you X server with backing storage. If your Xserver is started -with the -bs option, turn it off. If not try the -wm option. - -.EX -startx -- -wm -.EE - -You may have to adapt this example to your system (e.g. if you -use xinit to start X). - -\fIPopupDelay\fP requires one numeric argument. This value is the -delay in milliseconds before a sub-menu is popped up when the -pointer moves over a menu item that has a sub-menu. If the value -is zero no automatical pop up is done. If the argument is omitted -the built in default is used. Note that the popup delay has no -effect if the \fIPopupImmediately\fP option is used since sub-menus pop -up immediately then. The PopupDelay option should only be applied to the -default style ('*') since it is a global setting and affects all -menus. - -\fIPopupImmediately\fP makes menu items with sub menus pop up it up as -soon as the pointer enters the item. The PopupDelay is ignored then. -If \fIPopupDelayed\fP is used fvwm2 looks at the \fIPopupDelay\fP option -if or when this automatic popup happens. - -\fIPopupOffset\fP requires two integer arguments. Both values affect -where sub-menus are placed relative to the parent menu. If both -values are zero, the left edge of the sub-menu overlaps the left edge -of the parent menu. If the first value is non-zero the sub-menu is -shifted that many pixels to the right (or left if negative). If the -second value is non-zero the menu is moved by that many percent of -the parent menu's width to the right or left. - -\fITitleWarp\fP and \fITitleWarpOff\fP affect if the pointer warps to -the menu title when a sub-menu is opened or not. Not that regardless of -this setting the pointer will not be warped if the menu does not pop up -under the pointer. - -\fITitleUnderlines0\fP, \fITitleUnderlines1\fP and \fITitleUnderlines2\fP -specify how many lines are drawn below a menu title. - -\fISeparatorsLong\fP and \fISeparatorsShort\fP set the length of -menu separators. Long separators run from the left edge all the -way to the right edge. Short separators leave a few pixels to -the edges of the menu. - -\fITrianglesSolid\fP and \fITrianglesRelief\fP affect how the -small triangles for sub-menus is drawn. Solid triangles are -filled with a color while relief triangles are hollow. - -\fIDoubleClickTime\fP requires one numeric argument. This value is the -time in milliseconds between two mouse clicks in a menu to be -considered as a double click. The default is 450 milliseconds. -If the argument is omitted the doucle click time is reset to this -default. The DoubleClickTime option should only be applied to the -default style ('*') since it is a global setting and affects all -menus. - -\fISidePic\fP takes the name of an xpm or bitmap file as an argument. -The picture is drawn along the left side of the menu. The SidePic -option can be overridden by a menu specific side pixmap (see -\fIAddToMenu\fP). If the file name is omitted an existing side -pixmap is remove from the menu style. - -\fISideColor\fP takes the name of an X11 color as an argument. This -color is used to colorize the column containing the side picture -(see above). The SideColor option can be overridden by a menu -specific side color (see \fIAddToMenu\fP). If the color name is -omitted the side color option is switched off. - -Examples: - -.EX -MenuStyle * mwm -MenuStyle * Foreground Black, Background gray40 -MenuStyle * Greyed gray70, ActiveFore White -MenuStyle * HilightBackOff, Hilight3DOff -MenuStyle * Font lucidasanstypewriter-14 -MenuStyle * MenuFace DGradient 64 darkgray MidnightBlue - -MenuStyle gred mwm -MenuStyle gred Foreground Yellow, Background Maroon -MenuStyle gred Greyed Red, ActiveFore Red -MenuStyle gred HilightBackOff, Hilight3DOff -MenuStyle gred Font lucidasanstypewriter-12 -MenuStyle gred MenuFace DGradient 64 Red Black -.EE - -Note that all style options could be placed on a single line for each -style name. - - -.IP "MenuStyle \fIforecolor backcolor shadecolor font style\fP [ \fIanim\fP ]" -This is the old syntax of the MenuStyle command. It is obsolete and -may be removed in the future. Please use the new syntax as described -above. - -Sets the menu style. When using monochrome the colors are ignored. -The shade-color is the one used to draw a menu-selection which is -prohibited (or not recommended) by the mwm-hints which an application -has specified. The style option is either "fvwm" "mwm" or "win", -which changes the appearance and operation of the menus -and where the feedback window appears during resizes and moves. - -"mwm" and "win" style menus popup sub-menus automatically. -"win" menus indicate the current menu item by changing the -background to black. -"fvwm" sub-menus overlap the parent menu, "mwm" and "win" style menus -never overlap the parent menu. -"mwm" resize and move feedback windows are in the center of the -screen, instead of the upper left corner. - -The "anim" option is either "anim" or blank. When this option -is "anim", sub-menus that don't fit on the screen cause the parent menu -to be shifted to the left so the sub-menu can be seen. - -See also \fISetAnimation\fP command. - -.IP "Module \fIModuleName\fP" -Specifies a module which should be spawned during initialization. At -the current time the available modules (included with fvwm) are -FvwmAnimate (fancy animation of (de)iconification) FvwmAudio (makes -sounds to go with window manager actions), FvwmAuto -(an auto raise module), FvwmBacker (to change the background when you -change desktops), FvwmBanner (to display a spiffy XPM), FvwmButtons -(brings up a customizable tool bar), FvwmCpp (to preprocess your .fvwmrc -with cpp), FvwmEvent (trigger various actions by events), FvwmForm -(to bring up dialogs), FvwmIconBox (like the mwm IconBox), FvwmIconMan -(like the twm icon manager), FvwmIdent (to get window info), FvwmM4 -(to preprocess your .fvwmrc with m4), FvwmPager (a mini version of -the desktop), FvwmSave (saves the desktop state in .xinitrc style), -FvwmSaveDesk (saves the desktop state in fvwm commands), FvwmScroll -(puts scrollbars on any window), FvwmTalk (to interactively run fvwm -commands), and FvwmWinList (a window list), FvwmAnimate (produces -animation effects when a window is iconified or deiconifed). -.\" Note: The "Optional Module Name" description is missing. -These modules have their own man pages. There are other modules out -on there as well. - -Modules can be short lived transient programs or, like FvwmButtons, -can remain for the duration of the X session. Modules will be -terminated by the window manager prior to restarts and quits, if -possible. See the introductory section on modules. The keyword -"module" may be omitted if \fIModuleName\fP is distinct from all -built-in and function names. - - -.IP "ModulePath" -Specifies a colon separated list of paths for \fIfvwm\fP to search -when looking for a module to load. Individual directories do not need -trailing slashes. Environment variables can be used here as well (i.e. -$HOME or ${HOME}). The builtin module path is available via the -environment variable $FVWM_MODULEDIR. - - -.IP "Mouse \fIButton Context Modifiers Function\fP" -Defines a mouse binding, or removes the binding if \fIFunction\fP is -'-'. \fIButton\fP is the mouse button number. If \fIButton\fP is -zero then any button will perform the specified function. -\fIContext\fP describes where the binding applies. Valid contexts are -R for the root window, W for an application window, T for a window -title bar, S for a window side, top, or bottom bar, F for a window -frame (the corners), I for an Icon window, or 0 through 9 for -title-bar buttons, or any combination of these letters. A is for any -context except for title-bar buttons. For instance, a context of FST -will apply when the mouse is anywhere in a window's border except the -title-bar buttons. - -\fIModifiers\fP is any combination of N for no modifiers, C for -control, S for shift, M for Meta, or A for any modifier. For example, -a modifier of SM will apply when both the Meta and Shift keys are -down. X11 modifiers mod1 through mod5 are represented as the digits -1 through 5. - -\fIFunction\fP is one of \fIfvwm\fP's built-in functions. - -The title bar buttons are numbered with odd numbered buttons on the -left side of the title bar and even numbers on the right. -Smaller-numbered buttons are displayed toward the outside of the -window while larger-numbered buttons appear toward the middle of the -window (0 is short for 10). In summary, the buttons are numbered: -.EX -1 3 5 7 9 0 8 6 4 2 -.EE -The highest odd numbered button which has an action bound to it -determines the number of buttons drawn on the left side of the title -bar. The highest even number determines the number or right side -buttons which are drawn. Actions can be bound to either mouse buttons -or keyboard keys. - - -.IP "Move [ \fIx y\fP [ \fIWarp\fP ] ]" -Allows the user to move a window. If called from somewhere in a -window or its border, then that window will be moved. If called from -the root window then the user will be allowed to select the target -window. If the optional argument \fIWarp\fP is specified the pointer is warped -with the window. - -The operation can be aborted with Escape or by pressing any mouse button -(except button 1 which confirms the move). - -If the optional arguments x and y are provided, then the window will -be moved immediately without user interaction. Each argument can -specify an absolute or relative position from either the left (top) or -right (bottom) of the screen. By default, the numeric value given is -interpreted as a percentage of the screen width (height), but a trailing -"p" changes the interpretation to mean "pixels". - -Simple Examples: -.EX -\&# Interactive move -Mouse 1 T A Move -\&# Move window so top left is at (10%,10%) -Mouse 2 T A Move 10 10 -\&# Move top left to (10pixels,10pixels) -Mouse 3 T A Move 10p 10p -.EE - -More complex examples (these can be bound as actions to keystrokes, -etc.; only the command is shown, though): -.EX -\&# Move window so bottom right is at bottom -\&# right of screen -Move -0 -0 - -\&# Move window 5% to the right, and to the -\&# middle vertically -Move w+5 50 - -\&# Move window up 10 pixels, and so left edge -\&# is at x=40 pixels -Move 40p w-10p -.EE - -See also the "AnimatedMove" command, above. - - -.IP "MoveToDesk \fIarg1\fP [ \fIarg2\fP ] [ \fImin max\fP ]" -Moves the selected window to another desktop (workspace, room). - -The arguments are the same as for the \fIDesk\fP command. MoveToDesk -is a replacement for the old WindowsDesk command, which can no longer -be used. - - -.IP "MoveToPage [ \fIx y\fP ]" -Moves the selected window to another page (x,y). The upper left page is -(0,0), the upper right is (M,0), where M is one less than the current -number of horizontal pages specified in the DeskTopSize command. The -lower left page is (0,N), and the lower right page is (M,N), where N -is the desktop's vertical size as specified in the DeskTopSize -command. If \fIx\fP and \fIy\fP are not given, the window is moved to -the current page (a window that has the focus but is off-screen can -be retrieved with this). - - -.IP "Next (\fIconditions\fP) \fIcommand\fP" -Performs \fIcommand\fP (typically Focus) on the next window which -satisfies all \fIconditions\fP. Conditions are the same as for \fICurrent\fP -with the addition of CirculateHit which overrides the CirculateSkip style -attribute and CirculateHitIcon which overrides the CirculateSkipIcon style -attribute for iconified windows. - - -.IP "None (\fIconditions\fP) \fIcommand\fP" -Performs \fIcommand\fP if no window which satisfies all -\fIconditions\fP exists. Conditions are the same as for \fINext\fP. - - -.IP "Nop" -Does nothing. This is used to insert a blank line or separator in a -menu. If the menu item specification is Nop " ", then a blank line is -inserted. If it looks like Nop "", then a separator line is inserted. -Can also be used as the double-click action for Menu. - - -.IP "OpaqueMoveSize \fIpercentage\fP" -Tells \fIfvwm\fP the maximum size window with which opaque window -movement should be used. The percentage is percent of the total -screen area. With "OpaqueMoveSize 0" all windows will be moved using the -traditional rubber-band outline. With "OpaqueMoveSize 100" all windows -will be move as solid windows. The default is "OpaqueMoveSize 5", which -allows small windows to be moved in an opaque manner but large windows -are moved as rubber-bands. - - -.IP "PipeRead \fIcmd option\fP" -Causes fvwm to read commands output from the program named -\fIcmd\fP. Useful for building up dynamic menu entries based on a -directories contents, for example. - - -.IP "PixmapPath \fIpath\fP" -Specifies a colon separated list of full path names of directories -where pixmap (color) icons can be found. Each path should start with -a slash. Environment variables can be used here as well (i.e. $HOME -or ${HOME}). - - -.IP "Popup \fIPopupName\fP [ \fIposition\fP ] [ \fIdefault-action\fP ]" -This built-in has two purposes: to bind a menu to a key or mouse -button, and to bind a sub-menu into a menu. The formats for the two -purposes differ slightly. The \fIposition\fP arguments are the same -as for \fIMenu\fP. The command \fIdefault-action\fP will be invoked -if the user clicks a button to invoke the menu and releases it -immediately again (or hits the key rapidly twice if the menu is bound -to a key). - -To bind a previously defined pop-up menu to a key or mouse button: -.sp -.in +.25i -The following example binds mouse buttons 2 and 3 to a pop-up called -"Window Ops". The menu will pop up if the buttons 2 or 3 are pressed -in the window frame, side-bar, or title-bar, with no modifiers (none -of shift, control, or meta). -.EX -Mouse 2 FST N Popup "Window Ops" -Mouse 3 FST N Popup "Window Ops" -.EE -Pop-ups can be bound to keys through the use of the Key built in. -Pop-ups can be operated without using the mouse by binding to keys and -operating via the up arrow, down arrow, and enter keys. -.in -.25i -.sp -To bind a previously defined pop-up menu to another menu, for use as a -sub-menu: -.sp -.in +.25i -The following example defines a sub menu, "Quit-Verify" and binds it into a -main menu, called "RootMenu": -.EX -AddToMenu Quit-Verify - + "Really Quit Fvwm?" Title - + "Yes, Really Quit" Quit - + "Restart Fvwm2" Restart fvwm2 - + "Restart Fvwm 1.xx" Restart fvwm - + "" Nop - + "No, Don't Quit" Nop - -AddToMenu RootMenu "Root Menu" Title - + "Open XTerm Window" Popup NewWindowMenu - + "Login as Root" Exec exec xterm \\ - -fg green -T Root \\ - -n Root -e su - - + "Login as Anyone" Popup AnyoneMenu - + "Remote Hosts" Popup HostMenu - + "" Nop - + "X utilities" Popup Xutils - + "" Nop - + "Fvwm Modules" Popup Module-Popup - + "Fvwm Window Ops" Popup Window-Ops - + "" Nop - + "Previous Focus" Prev (*) Focus - + "Next Focus" Next (*) Focus - + "" Nop - + "Refresh screen" Refresh - + "Recapture screen" Recapture - + "" Nop - + "Reset X defaults" Exec xrdb -load \\ - $HOME/.Xdefaults - + "" Nop - + "" Nop - + "Quit" Popup Quit-Verify -.EE -.in -.25i -.sp -Popup differs from Menu in that pop-ups do not stay up if the user -simply clicks. These are Twm style popup-menus, which are a little -hard on the wrist. Menu provides Motif or Microsoft-Windows style -menus which will stay up on a click action. See menu for an explanation -of the interactive behaviour of menus. - - -.IP "Prev (\fIconditions\fP) \fIcommand\fP" -Performs \fIcommand\fP (typically Focus) on the previous window which -satisfies all \fIconditions\fP. Conditions are the same as for \fINext\fP. - - -.IP "Quit" -Exits fvwm, generally causing X to exit too. - - -.IP "QuitScreen" -Causes fvwm to stop managing the screen on which the command was issued. - - -.IP "Raise" -Allows the user to raise a window. - - -.IP "RaiseLower" -Alternately raises and lowers a window. - - -.IP "Read \fIfilename\fP [ \fIoption\fP ]" -Causes fvwm to read commands from the file named \fIfilename\fP. -If the option following the filename is "Quiet", no message is -produced if the file is not found. - - -.IP "Recapture" -Causes fvwm to recapture all of its windows. This ensures that the -latest style parameters will be used. The recapture operation is -visually disturbing. - - -.IP "Refresh" -Causes all windows on the screen to redraw themselves. - - -.IP "RefreshWindow" -Causes current (or chosen) window to redraw itself. - - -.IP "Resize [ \fIx y\fP ]" -Allows the user to resize a window. If called from somewhere in a -window or its border, then that window will be resized. If called from -the root window then the user will be allowed to select the target -window. - -The operation can be aborted with Escape or by pressing any mouse button -(except button 1 which confirms the resize). - -If the optional arguments x and y are provided, then the window will -be resized so that its dimensions are \fIx\fP by \fIy\fP). The units -of x and y are percent-of-screen, unless a letter "p" is appended to -each coordinate, in which case the location is specified in pixels. - - -.IP "Restart \fIWindowManagerName\fP " -Causes \fIfvwm\fP to restart itself if WindowManagerName is "fvwm2", -or to switch to an alternate window manager if WindowManagerName is -other than "fvwm2". If the window manager is not in your default -search path, then you should use the full path name for -\fIWindowManagerName\fP. - -This command should not have a trailing ampersand or any command line -arguments and should not make use of any environmental variables. Of -the following examples, the first two are sure losers, but the third -is OK: -.EX -Key F1 R N Restart fvwm & -Key F1 R N Restart $(HOME)/bin/fvwm -Key F1 R N Restart /home/nation/bin/fvwm -.EE - -.IP "Scroll \fIhorizonal vertical\fP" -Scrolls the virtual desktop's viewport by \fIhorizontal\fP pages in -the x-direction and \fIvertical\fP pages in the y-direction. Either -or both entries may be negative. Both horizontal and vertical values -are expressed in percent of pages, so "Scroll 100 100" means to scroll -down and left by one full page. "Scroll 50 25" means to scroll left -half a page and down a quarter of a page. The scroll function should -not be called from pop-up menus. Normally, scrolling stops at the edge -of the desktop. - -If the horizontal and vertical percentages are multiplied by 1000 then -scrolling will wrap around at the edge of the desktop. If "Scroll -100000 0" is executed over and over \fIfvwm\fP will move to the next -desktop page on each execution and will wrap around at the edge of the -desktop, so that every page is hit in turn. - -If the letter "p" is appended to each coordinate (horizontal and/or -vertical), then the scroll amount will be measured in pixels. - -.IP "SendToModule \fImodulename string\fP" -Sends an arbitrary string (no quotes required) to all modules matching -\fImodulename\fP, which may contain wildcards. This only makes sense -if the module is set up to understand and deal with these strings -though... Can be used for module to module communication, or -implementation of more complex commands in modules. - -.IP "SetAnimation \fImilliseconds-delay\fP [ \fifractions-to-move-list\fP ]" -Sets the time between frames and the list of fractional offsets to -customize the animated moves of the \fIAnimatedMove\fP command and -the animation of menus (if the menu style is set to animated). If -the \fIfractions-to-move-list\fP is omitted, only the time between frames -is altered. The fractions-to-move-list specifies how far the window -should be offset at each successive frame as a fraction of the difference -between the starting location and the ending location. e.g.: -.EX -SetAnimation 10 -.01 0 .01 .03 .08 .18 .3 \\ - .45 .6 .75 .85 .90 .94 .97 .99 1.0 -.EE - -Sets the delay between frames to 10ms, and sets the positions of the 16 -frames of the animation motion. Notice that negative values are allowed, -and in particular can be used to make the motion appear more cartoonish, by -briefly moving slightly in the opposite direction of the main motion. The -above settings are the default. - -.IP "SetEnv \fIvarname stringvalue\fP" -Set an environment variable to a new value, similar to shell's export -or setenv command. The variable and its value are inherited by processes -started directly by fvwm2. This can be especially useful in conjunction -with the FvwmM4 module; e.g. "SetEnv height HEIGHT" will make the FvwmM4-set -variable "HEIGHT" usable by processes started by fvwm2 as the environment -variable "$height". If \fIstringvalue\fP includes whitespace, you should -enclose it in quotes. - - -.IP "SnapAttraction \fIproximity\fP [ \fIbehavior\fP ]" -If during an interactive move the window (or icon) comes within \fIproximity\fP -pixels of another the window (or icon) will be moved to make the borders -adjoin. The default of -1 means that no snapping will happen. A setting of -0 does indeed snap when the distance is zero pixels. This is relevant when -the \fISnapGrid\fP command is used. - -The \fIbehavior\fP argument is optional and may be set to one of the four -following values: - -With \fIAll\fP both icons and windows snap to other windows and other -icons. - -\fISameType\fP lets snap windows only to other windows and icons -only to other icons. - -With \fIWindows\fP windows snap only to other windows. Icons do not -snap. - -Similarly with \fIIcons\fP icons snap to only other icons and -windows do not snap. - -The default SnapAttraction setting for behavior is "All". - -.IP "SnapGrid \fIx-grid-size y-grid-size\fP" -During an interactive move a window (or icon) will be positioned such that -its location (top left corner) will be coincindent with the nearest grid point. -The default \fIx-grid-size\fP and \fIy-grid-size\fP setting are both 1, which -is effectively no grid all. An interactive move with both \fISnapGrid\fP -and \fISnapAttraction\fP in effect will result in the window being moved to be -adjacent to the nearest window border (if within snap proximity) or grid -position. In other words, the window will move the shortest distance possible -to satisfy both \fISnapGrid\fP and \fISnapAttraction\fP. Note that the X and -Y coordinates are not coupled. For example, a window may snap to another window -on the X axis while snapping to a grid point on the Y axis. - -.IP "Stick" -Makes a window sticky if it is not already sticky, or non-sticky if it -is already sticky. - -.IP "Style \fIwindowname options\fP" -This command is intended to replace the old fvwm 1.xx global commands -NoBorder, NoTitle, StartsOnDesk, Sticky, StaysOnTop, Icon, -WindowListSkip, CirculateSkip, SuppressIcons, BoundaryWidth, -NoBoundaryWidth, StdForeColor, and StdBackColor with a single flexible -and comprehensive window(s) specific command. This command is used to -set attributes of a window to values other than the default or to set -the window manager default styles. - -\fIwindowname\fP can be a window's name, class, or resource string. -It can contain the wildcards * and/or ?, which are matched in the -usual Unix filename manner. They are searched in the reverse order -stated, so that Style commands based on the name override or augment -those based on the class, which override or augment those based on the -resource string. - -Note - windows that have no name (WM_NAME) are given a name of -"Untitled", and windows that don't have a class (WM_CLASS, res_class) -are given Class = "NoClass" and those that don't have a resource -(WM_CLASS, res_name) are given Resource = "NoResource". - -\fIoptions\fP is a comma separated list containing some or all of the -keywords BorderWidth, HandleWidth, NoIcon/Icon, MiniIcon, IconBox, -IconGrid, IconFill, -NoTitle/Title, NoHandles/Handles, WindowListSkip/WindowListHit, -CirculateSkip/CirculateHit, StaysOnTop/StaysPut, Sticky/Slippery, -StartIconic/StartNormal, Color, ForeColor, BackColor, -StartsOnDesk/StartsOnPage/StartsAnyWhere, IconTitle/NoIconTitle, -MWMButtons/FvwmButtons, MWMBorder/FvwmBorder, MWMDecor/NoDecorHint, -MWMFunctions/NoFuncHint, HintOverride/NoOverride, NoButton/Button, -OLDecor/NoOLDecor, StickyIcon/SlipperyIcon, -SmartPlacement/DumbPlacement, RandomPlacement/ActivePlacement, -DecorateTransient/NakedTransient, SkipMapping/ShowMapping, UseDecor, -UseStyle, NoPPosition/UsePPosition, Lenience/NoLenience, -ClickToFocus/SloppyFocus/MouseFocus|FocusFollowsMouse. - -In the above list some options are listed as -style-option/opposite-style-option. The opposite-style-option for -entries that have them describes the \fIfvwm\fP default behavior and -can be used if you want to change the \fIfvwm\fP default behavior. - -\fIDecorateTransient\fP causes transient windows, which are normally -left undecorated, to be given the usual \fIfvwm\fP decorations (title -bar, buttons, etc.). Note that some pop-up windows, such as the xterm -menus, are not managed by the window manager and still do not receive -decorations. \fINakedTransient\fP (the default) causes transient windows -not to be given the standard decorations. - -\fIIcon\fP takes an (optional) unquoted string argument which is the icon -bitmap or pixmap to use. - -\fIIconBox\fP takes four numeric arguments or an X11 geometry string: -.EX -IconBox l t r b -.EE -or -.EX -IconBox geometry -.EE - -Where l is the left coordinate, t is the top, r is right and b is -bottom. Negative coordinates indicate distance from the right or -bottom of the screen. -Perhaps easier to use is an X11 Geometry string: -.EX -IconBox -80x200-1-1 -.EE -Which would place an 80 by 240 pixel iconbox in the lower right hand -corner of the screen. -The iconbox is a region of the screen where fvwm -attempts to put icons for any matching window, as long as they do not -overlap other icons. -Multiple icon boxes can be defined as overflow areas. When the first -icon box is filled, the second one is filled. All the icon boxes for -one style must be defined in one command. For example: -.EX -Style "*" IconBox -80x200-1-1, \\ - IconBox 1000x70-1-1 -.EE - -\fIIconGrid\fP takes 2 numeric arguments greater than zero. -.EX -IconGrid x y -.EE -Icons are placed in an icon box by stepping thru the icon box using -the x and y values for the icon grid, looking for a free space. -The default grid is 3 by 3 pixels which gives a tightly packed appearance. -To get a more regular appearance use a grid larger than your largest icon. -Currently there is no way to clip an icon to a maximum size. -An IconGrid definition must follow the IconBox definition that it -applies to: -.EX -Style "*" IconBox -80x240-1-1, IconGrid 90 90 -.EE - -\fIIconFill\fP takes 2 arguments. -.EX -IconFill Bottom Right -.EE -Icons are placed in an icon box by stepping thru the icon box using -these arguments to control the direction the box is filled in. -By default the direction is left to right, then top to bottom. -This would be expressed as: -.EX -IconFill left bottom -.EE -To fill an icon box in columns instead of rows, specify the -vertical direction (top or bottom) first. -The directions can be abbreviated or spelled out as follows: "t", "top", -"b", "bot", "bottom", "l", "lft", "left", "r", "rgt", "right". -An IconFill definition must follow the IconBox definition that it -applies to: -.EX -Style "*" IconBox -80x240-1-1, IconFill b r -.EE - -\fIMiniIcon\fP specifies a pixmap to use as the miniature icon for the -window. This miniature icon can be drawn in a title-bar button (see -ButtonStyle), and can be used by various fvwm modules (FvwmWinList, -FvwmIconMan, and FvwmTaskBar). It takes the name of a pixmap as an -argument. - -\fIStartsOnDesk\fP takes a numeric argument which is the desktop number on -which the window should be initially placed. Note that standard Xt -programs can also specify this via a resource (e.g. "-xrm '*Desk: 1'"). - -\fIStartsOnPage\fP takes 1, 2, or 3 numeric arguments. If one or three -arguments are givem, the first (or only) argument is the desktop number. If -three arguments are given, the 2nd and 3rd arguments identify the x,y page -position on the virtual window. If two arguments are given, they specify the -page position, and indicate no desk preference. If only one argument is given, -StartsOnPage functions exactly like StartsOnDesk. For those standard Xt -programs which understand this usage, the starting desk/page can also be -specified via a resource (e.g., "-xrm 'Fvwm.Page: 1 0 2'"). - -StartsOnPage in conjunction with SkipMapping is a useful technique when you -want to start an app on some other page and continue with what you were -doing, rather than waiting for it to appear. - -\fIStaysOnTop\fP makes the window always try to stay on top of the other -windows. This might be handy for clocks or mailboxes that you would -always like to be visible. If the window is explicitly lowered it -will not try to force its way back to the top until it is explicitly -raised. StaysPut (the default) allows the window to be obscured and -stay that way. - -\fIBorderWidth\fP takes a numeric argument which is the width of the border -to place the window if it does not have resize-handles. - -\fIHandleWidth\fP takes a numeric argument which is the width of the border -to place the window if it does have resize-handles. - -\fIButton\fP and \fINoButton\fP take a numeric argument which is the -number of the title-bar button which is to be included/omitted. - -\fIStickyIcon\fP makes the window sticky when its iconified. It will -deiconify on top the active desktop. - -\fIMWMButtons\fP makes the Maximize button look pressed-in when the window -is maximized. See the MWMButton flag in ButtonStyle for more -information. - -\fIMWMBorder\fP makes the 3-D bevel more closely match mwm's. - -\fIMWMDecor\fP makes fvwm attempt to recognize and respect the mwm -decoration hints that applications occasionally use. - -\fIMWMFunctions\fP makes fvwm attempt to recognize and respect the mwm -prohibited operations hints that applications occasionally use. -HintOverride makes fvwm shade out operations that mwm would prohibit, -but it lets you perform the operation anyway. - -\fIOLDecor\fP makes fvwm attempt to recognize and respect the olwm and olvwm -hints that many older XView and OLIT applications use. - -\fIColor\fP takes two arguments. The first is the window-label text color -and the second is the window decoration's normal background color. -The two colors are separated with a slash. If the use of a slash -causes problems then the separate ForeColor and BackColor options can -be used. - -\fIUseDecor\fP accepts one argument: the name of a decor created with -AddToDecor. If UseDecor is not specified, the "Default" decor is -used. Windows do not actually contain decors, but are always assigned -to one. If the decor is later modified with AddToDecor, the changes -will be visible for all windows which are assigned to it. The decor -for a window can be reassigned with ChangeDecor. - -\fIUseStyle\fP takes one arg, which is the name of another style. That way -you can have unrelated window names easily inherit similar traits -without retyping. For example: 'Style "rxvt" UseStyle "XTerm"'. - -\fISkipMapping\fP tells fvwm not to switch to the desk the window is on when -it gets mapped initially (useful with StartsOnDesk or StartsOnPage). - -\fILenience\fP instructs fvwm to ignore the convention in the ICCCM which -states that if an application sets the input field of the wm_hints -structure to False, then it never wants the window manager to give it -the input focus. The only application that I know of which needs this -is sxpm, and that is a silly bug with a trivial fix and has no overall -effect on the program anyway. Rumor is that some older applications -have problems too. - -\fIClickToFocus\fP instructs fvwm to give the focus to the window when it is -clicked in. The default \fIMouseFocus\fP (or its alias -\fIFocusFollowsMouse\fP) tells fvwm to give the window the focus as soon as -the pointer enters the window, and take it away when the pointer leaves the -window. \fISloppyFocus\fP is similar, but doesn't give up the focus if the -pointer leaves the window to pass over the root window or a ClickToFocus -window (unless you click on it, that is), which makes it possible to -move the mouse out of the way without losing focus. - -\fINoPPosition\fP instructs fvwm to ignore the PPosition field when adding -new windows. Adherence to the PPosition field is required for some -applications, but if you don't have one of those its a real headache. - -\fIRandomPlacement\fP causes windows which would normally require user -placement to be automatically placed in ever-so-slightly random -locations. For the best of all possible worlds use both -RandomPlacement and SmartPlacement. - -\fISmartPlacement\fP causes windows which would normally require user -placement to be automatically placed in a smart location - a location -in which they do not overlap any other windows on the screen. If no -such position can be found user placement or random placement (if -specified) will be used as a fall-back method. For the best of all -possible worlds use both RandomPlacement and SmartPlacement. - -An example: -.EX -\&# Change default fvwm behavior to no title- -\&# bars on windows! Also define a default icon. -Style "*" NoTitle, \\ - Icon unknown1.xpm, \\ - BorderWidth 4, \\ - HandleWidth 5 - -\&# now, window specific changes: -Style "Fvwm*" NoHandles, Sticky, \\ - WindowListSkip, \\ - BorderWidth 0 -Style "Fvwm Pager" StaysOnTop, BorderWidth 0 -Style "*lock" NoHandles, Sticky, \\ - StaysOnTop, WindowListSkip -Style "xbiff" Sticky, WindowListSkip -Style "FvwmButtons" NoHandles, Sticky, \\ - WindowListSkip -Style "sxpm" NoHandles -Style "makerkit" - -\&# Put title-bars back on xterms only! -Style "xterm" Title, Color black/grey - -Style "rxvt" Icon term.xpm -Style "xterm" Icon rterm.xpm -Style "xcalc" Icon xcalc.xpm -Style "xbiff" Icon mail1.xpm -Style "xmh" Icon mail1.xpm, \\ - StartsOnDesk 2 -Style "matlab" Icon math4.xpm, \\ - StartsOnDesk 3 -Style "xmag" Icon magnifying_glass2.xpm -Style "xgraph" Icon graphs.xpm -Style "FvwmButtons" Icon toolbox.xpm -Style "Maker" StartsOnDesk 1 -Style "signal" StartsOnDesk 3 - -\&# Fire up Netscape on the second desk, in the -\&# middle of my 3x3 virtual desktop, and don't -\&# bother me with it... -Style "Netscape*" SkipMapping, \\ - StartsOnPage 1 1 1 -.EE -Note that all properties for a window will be OR'ed together. In the -above example "FvwmPager" gets the property StaysOnTop via an exact -window name match but also gets NoHandles, Sticky, and WindowListSkip -by a match to "Fvwm*". It will get NoTitle by virtue of a match to -"*". If conflicting styles are specified for a window, then the last -style specified will be used. - -If the NoIcon attribute is set then the specified window will simply -disappear when it is iconified. The window can be recovered through -the window-list. If Icon is set without an argument then the NoIcon -attribute is cleared but no icon is specified. An example which -allows only the FvwmPager module icon to exist: -.EX -Style "*" NoIcon -Style "Fvwm Pager" Icon -.EE - - -.IP "Title" -Does nothing. This is used to insert a title line in a popup or menu. - - -.IP "TitleStyle [ \fIjustification\fP ] [ \fIheight num\fP ]" -Sets attributes for the title bar. Justifications can be "Centered", -"RightJustified," or "LeftJustified." \fIheight\fP sets the title -bar's height to an amount in pixels. Defaults are Centered and -WindowFont height. The \fIheight\fP parameter must be set after a -WindowFont command since WindowFont resets the height to the default -for the specified font. Example: -.EX -TitleStyle LeftJustified Height 24 -.EE - - -.IP "TitleStyle [ \fIstate\fP ] [ \fIstyle\fP ] [ -- \fI[!]flag ...\fP ]" -Sets the style for the title bar. \fIstate\fP can be one of -"ActiveUp," "ActiveDown," or "Inactive." If \fIstate\fP is omitted, -then the style is added to every state. If parentheses are placed -around the style and flags, then multiple state definitions can be -given per line. \fIstyle\fP can be omitted so that flags can be set -while not destroying the current style. - -If an "!" is prefixed to any \fIflag\fP, its behavior is negated. -Valid flags for each state include "Raised," "Flat," and "Sunk" (these -are mutually exclusive). The default is Raised. See the note in -ButtonStyle regarding the ActiveDown state. Examples: -.EX -TitleStyle ActiveUp HGradient 16 navy black -TitleStyle ActiveDown (Solid red -- flat) \\ - Inactive (TiledPixmap wood.xpm) -TitleStyle ActiveUp (-- Flat) ActiveDown \\ - (-- Raised) Inactive (-- Flat) -.EE -This sets the ActiveUp state to a horizontal gradient, the ActiveDown -state to solid red, and the Inactive state to a tiled wood pixmap. -Finally, ActiveUp is set to look flat, while ActiveDown set to be sunk -(the Raised flag for the ActiveDown state causes it to appear Sunk due -to relief inversion), and Inactive is set to flat as well. An example -which sets flags for all states: -.EX -TitleStyle -- flat -.EE -For a flattened look: -.EX -TitleStyle -- flat -ButtonStyle All ActiveUp (-- flat) Inactive \\ - (-- flat) -.EE - - -.IP "UpdateDecor [ \fIdecor\fP ]" -Updates window decorations. \fIdecor\fP is an optional argument which -specifies the \fIdecor\fP to update. If given, only windows which are -assigned to that particular \fIdecor\fP will be updated. This command -is useful, for instance, after a ButtonStyle, TitleStyle or -BorderStyle (possibly used in conjunction with AddToDecor). -Specifying an invalid decor results in all windows being updated. -This command is less disturbing than Recapture, but does not affect -window style options as Recapture does. - - -.IP "Wait \fIname\fP" -This built-in is intended to be used in \fIfvwm\fP functions only. It -causes execution of a function to pause until a new window name -\fIname\fP appears. \fIFvwm\fP remains fully functional during a wait. -This is particularly useful in the InitFunction if you are trying to -start windows on specific desktops: -.EX -AddToFunc InitFunction - + "I" exec xterm -geometry 80x64+0+0 - + "I" Wait xterm - + "I" Desk 0 2 - + "I" Exec exec xmh -font fixed -geometry \\ - 507x750+0+0 - + "I" Wait xmh - + "I" Desk 0 0 -.EE -The above function starts an xterm on the current desk, waits for it -to map itself, then switches to desk 2 and starts an xmh. After the -xmh window appears control moves to desk 0. - - -.IP "WarpToWindow \fIx y\fP" -Warps the cursor to the associated window. The parameters x and y -default to percentage of window down and in from the upper left hand -corner (or number of pixels down and in if 'p' is appended to the -numbers). - - -.IP "WindowFont [ \fIfontname\fP ]" -Makes \fIfvwm\fP use font \fIfontname\fP instead of "fixed" for window -title-bars. To reset this font to the default font (see \fIDefaultFont\fP) -you may omit \fIfontname\fP. - - -.IP "WindowId \fIid func\fP" -The WindowId function is similar to the Next and Prev funcs, except -that it looks for a specific window \fIid\fP and runs the specified -\fIfunc\fP on it. -.EX -WindowId 0x34567890 Raise -WindowId 0x34567890 WarpToWindow 50 50 -.EE -Mostly this is useful for functions used with the WindowList builtin. - - -.IP "WindowList [ \fIposition\fP ] [ \fIoptions\fP ] [ \fIdouble-click-action\fP ]" -Generates a pop-up menu (and pops it up) in which the title and -geometry of each of the windows currently on the desk top are shown. -The geometry of iconified windows is shown in parenthesis. Selecting -an item from the window list pop-up menu will by default cause the -interpreted function WindowListFunc to be run with the window id of -that window passed in as $0. By default the WindowListFunc looks like -this: -.EX -AddToFunc WindowListFunc - + "I" WindowId $0 Iconify -1 - + "I" WindowId $0 FlipFocus - + "I" WindowId $0 Raise - + "I" WindowId $0 WarpToWindow 5p 5p -.EE -You can Destroy the builtin WindowListFunc and create your own if -these defaults do not suit you. - -The \fIposition\fP arguments are the same as for \fIMenu\fP. The -command \fIdouble-click-action\fP will be invoked if the user -double-clicks (or hits the key rapidly twice if the menu is bound -to a key) when bringing the window list. The double-click-action -must be quoted if it consists of more than one word. - -The double-click-action is useful to define a default window if you -have bound the window list to a key (or button) like this: -.EX -Key Tab A M WindowList "Prev FlipFocus" -.EE -Hitting Alt-Tab once it brings up the window list, if you hit it -twice the focus is flipped between the current and the last focused -window. - -The \fIoptions\fP passed to WindowList can be "NoGeometry", "Function -", "Desk ", "CurrentDesk", "NoIcons", "Icons", -"OnlyIcons", "NoNormal", "Normal", "OnlyNormal", "NoSticky", "Sticky", -"OnlySticky", "NoOnTop", "OnTop", "OnlyOnTop", "NoDeskSort", "UseIconName", -"Alphabetic", "NotAlphabetic". - -(Note - normal means not iconic, sticky, or ontop) - -If you pass in a function via "Function ", $0 is the window -id: -.EX -AddToFunc IFunc "I" WindowId $0 Iconify -WindowList Function IFunc, NoSticky, \\ - CurrentDesk, NoIcons -.EE - -If you wanted to use the WindowList as an icon manager, you could invoke -the following: -.EX -WindowList OnlyIcons, Sticky, OnTop, Geometry -.EE -(Note - the "Only" options essentially wipe out all other ones...) - - -.IP "WindowsDesk \fIarg1\fP [ \fIarg2\fP ]" -Moves the selected window to another desktop (workspace, room). - -This command has been removed and must be replaced by \fIMoveToDesk\fP, -the arguments for which are the same as for the \fIDesk\fP command. -\fINote:\fP You cannot simply change the name of the command: the -syntax has changed. If you used "WindowsDesk n" to move a window to -desk n, you will have to change it to "MoveToDesk 0 n". - - -.IP "WindowShade [ \fIopt\fP ]" -Toggles the window shade feature for titled windows. Windows in the -shaded state only display a title bar. If \fIopt\fP is not given, the -window shade state is toggled. If \fIopt\fP is 1, the window is -forced to the shaded state. If \fIopt\fP is 2, then the window is -forced to the non-shaded state. Maximized windows and windows without -titles cannot be shaded. - - -.IP "XORvalue \fInumber\fP" -Changes the value with which bits are XOR'ed when doing rubber-band -window moving or resizing. Setting this value is a trial-and-error +.Dd $Mdocdate$ +.Dt FVWM2 1 +.Os OpenBSD +.Sh NAME +.Nm fvwm2 +.Nd F Virtual Window Manager for X11 +.Sh SYNOPSIS +.Nm fvwm2 +.Op Fl s +.Op Fl f Ar config-file +.Op Fl cmd Ar config-command +.Op Fl display Ar display +.Op Fl debug +.Sh DESCRIPTION +.Nm +is the F Virtual Window Manager, a highly configurable ICCCM-compliant +window manager for the X Window System. +.Pp +.Nm +provides virtual desktops, complex function definitions, extensive +styling capabilities, and a modular architecture. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl s +Single-screen mode. +Do not manage multiple screens on a multi-headed display. +Each screen must then be managed by a separate +.Nm process. - - -.IP "+" -Used to continue adding to the last specified decor, function or menu. -See the discussion for AddToDecor, AddToFunc, and AddToMenu. - - - -.SH KEYBOARD SHORTCUTS -All (I think) window manager operations can be performed from the -keyboard so mouseless operation should be possible. In addition to -scrolling around the virtual desktop by binding the Scroll built-in to -appropriate keys, pop-ups, move, resize, and most other built-ins can -be bound to keys. Once a built-in function is started the pointer is -moved by using the up, down, left, and right arrows, and the action is -terminated by pressing return. Holding down the shift key will cause -the pointer movement to go in larger steps and holding down the -control key will cause the cursor movement to go in smaller steps. -Standard emacs and vi cursor movement controls (^n, ^p, ^f, ^b, and -^j, ^k, ^h, ^l) can be used instead of the arrow keys. - - -.SH SUPPLIED CONFIGURATION -A sample configuration file, .fvwmrc, is supplied with the \fIfvwm\fP -distribution. It is well commented and can be used as a source of -examples for \fIfvwm\fP configuration. - - -.SH USE ON MULTI-SCREEN DISPLAYS -If the -s command line argument is not given, \fIfvwm\fP will -automatically start up on every screen on the specified display. -After \fIfvwm\fP starts each screen is treated independently. -Restarts of \fIfvwm\fP need to be performed separately on each screen. -The use of EdgeScroll 0 0 is strongly recommended for multi-screen -displays. - -You may need to quit on each screen to quit from the X session -completely. - - -.SH ENVIRONMENT -.TP -DISPLAY -Fvwm starts on this display unless the -.I -display -option is given. -.TP -FVWM_MODULEDIR -Set by \fIfvwm\fP to the directory containing the standard \fIfvwm\fP -modules. - - -.SH BUGS -As of fvwm 2.2 there were exactly 46.144 unidentified bugs. -Identified bugs have mostly been fixed, though. Since then 12.25 bugs -have been fixed. Assuming that there are at least 10 unidentified -bugs for every identified one, that leaves us with 46.144 - 12.25 + 10 -* 12.25 = 156.395 unidentified bugs. If we follow this to its logical -conclusion we will have an infinite number of unidentified bugs before -the number of bugs can start to diminish, at which point the program -will be bug-free. Since this is a computer program infinity = -3.4028e+38 if you don't insist on double-precision. At the current -rate of bug discovery we should expect to achieve this point in -4.27e+27 years. I guess I better plan on passing this thing on to my -children.... - -Known bugs can be found in the BUGS file in the distribution, in -the fvwm bug tracking system (accessible from the fvwm home page) and -in the TO-DO list. - -Bug reports can be sent to the FVWM workers' mailing list (see the FAQ). - -.SH AUTHOR -Robert Nation with help from many people, based on \fItwm\fP code, -which was written by Tom LaStrange. After Robert Nation came Charles Hines, -followed by Brady Montz. Currently fvwm is maintained by a number of people -on the fvwm-workers mailing list (Dan Espen, Steve Robbins, Paul Smith, -Jason Tibbitts, Dominik Vogt, Bob Woodside and others). - -The official FVWM homepage is http://www.fvwm.org/. +.It Fl f Ar config-file +Read +.Ar config-file +instead of the default +.Pa ~/.fvwmrc +or the system-wide +.Pa /etc/X11/fvwm/system.fvwm2rc . +.It Fl cmd Ar config-command +Execute +.Ar config-command +after reading the configuration file. +.It Fl display Ar display +Connect to the X display +.Ar display . +.It Fl debug +Enable synchronous X11 protocol debugging. +.El +.Sh CONFIGURATION +.Nm +reads configuration from +.Pa ~/.fvwmrc +by default. +If that file does not exist, the system configuration at +.Pa /etc/X11/fvwm/system.fvwm2rc +is used. +.Pp +The configuration language supports: +.Bl -dash +.It +Style rules for window appearance and behavior. +.It +Key and mouse bindings for interactive control. +.It +Complex functions with conditional logic. +.It +Menu definitions. +.It +Module invocations. +.It +Environment variable expansion. +.It +File inclusion with +.Ic Read +and +.Ic PipeRead . +.El +.Sh COMMANDS +The following built-in commands are available in configuration +files and from modules: +.Pp +.Bl -tag -width "ButtonStyle" -compact +.It Ic AddToFunc +Define or extend a complex function. +.It Ic AddToMenu +Define or extend a menu. +.It Ic ButtonStyle +Set button decoration style. +.It Ic ChangeDecor +Change window decoration at runtime. +.It Ic ClickTime +Set double-click timeout. +.It Ic CursorMove +Move the cursor relative to its current position. +.It Ic Desk +Switch to a different desktop. +.It Ic DestroyDecor +Destroy a named decoration set. +.It Ic DestroyMenu +Destroy a menu definition. +.It Ic DestroyMenuStyle +Destroy a menu style. +.It Ic EdgeResistance +Set resistance to moving windows past screen edges. +.It Ic EdgeScroll +Set edge-triggered viewport scrolling. +.It Ic Exec +Execute an external command. +.It Ic Function +Execute a named complex function. +.It Ic GlobalOpts +Set global window manager options. +.It Ic GotoPage +Move the viewport to a specific page. +.It Ic HilightColor +Set the highlight color for the focus window. +.It Ic IconFont +Set the font for icon labels. +.It Ic IconPath +Set the icon search path. +.It Ic Key +Define a keyboard binding. +.It Ic Lower +Lower a window. +.It Ic Maximize +Maximize or restore a window. +.It Ic MenuStyle +Set menu appearance and behavior. +.It Ic Module +Launch a module. +.It Ic ModulePath +Set the module search path. +.It Ic Mouse +Define a mouse binding. +.It Ic Move +Move a window. +.It Ic Next +Focus the next window. +.It Ic NoBoundaryWidth +Remove window boundary width. +.It Ic OpaqueMove +Set opaque window moving. +.It Ic OpaqueResize +Set opaque window resizing. +.It Ic PipeRead +Read configuration from a pipe. +.It Ic PixmapPath +Set the pixmap search path. +.It Ic Popup +Display a popup menu. +.It Ic Prev +Focus the previous window. +.It Ic Quit +Exit +.Nm . +.It Ic Raise +Raise a window. +.It Ic RaiseLower +Toggle raise/lower state. +.It Ic Read +Read configuration from a file. +.It Ic Recapture +Re-capture all windows on the display. +.It Ic Refresh +Refresh all window decorations. +.It Ic Resize +Resize a window. +.It Ic Restart +Restart +.Nm . +.It Ic Scroll +Scroll the viewport. +.It Ic SetEnv +Set an environment variable. +.It Ic Style +Set window style options. +.It Ic TitleStyle +Set title bar decoration style. +.It Ic UseDecor +Apply a named decoration set to a window. +.It Ic Wait +Wait for a named window. +.It Ic WindowFont +Set the font for window titles. +.It Ic WindowList +Invoke the built-in window list. +.It Ic WindowShade +Shade or unshade a window. +.It Ic XORvalue +Set XOR drawing value. +.El +.Sh MODULES +.Nm +supports loadable modules that communicate with the window manager +via a binary packet protocol over Unix pipes. +Modules typically provide additional functionality such as: +.Bl -dash +.It +Desktop pagers +.Pq Xr FvwmPager 1 . +.It +Button bars and docks +.Pq Xr FvwmButtons 1 . +.It +Window lists +.Pq Xr FvwmWinList 1 . +.It +Icon management +.Pq Xr FvwmIconBox 1 , Xr FvwmIconMan 1 . +.It +Desktop background management +.Pq Xr FvwmBacker 1 . +.It +Session state saving +.Pq Xr FvwmSave 1 , Xr FvwmSaveDesk 1 . +.It +Configuration preprocessors +.Pq Xr FvwmCpp 1 , Xr FvwmM4 1 . +.El +.Sh ENVIRONMENT +.Bl -tag -width "FVWM_MODULEDIR" -compact +.It Ev DISPLAY +X11 display to connect to. +.It Ev HOME +User home directory, used for configuration file location. +.It Ev FVWM_MODULEDIR +Override the module installation directory. +.It Ev FVWM_EXEC_FD +Internal: file descriptor for the execution helper IPC (not user-settable). +.El +.Sh FILES +.Bl -tag -width "~/.fvwm2rc" -compact +.It Pa ~/.fvwmrc +Per-user configuration file. +.It Pa ~/.fvwm2rc +Alternative per-user configuration file. +.It Pa /etc/X11/fvwm/system.fvwm2rc +System-wide configuration file. +.It Pa /usr/X11R6/lib/X11/fvwm/ +System module and resource directory. +.El +.Sh SECURITY CONSIDERATIONS +.Nm +runs with privilege separation: +.Bl -dash +.It +The main window manager process owns the X11 connection and +manages windows. +.It +The +.Nm fvwm_exec +helper process executes external commands without access +to the X11 connection. +.It +After initialization, the main process drops privileges via +.Xr pledge 2 +and +.Xr unveil 2 . +.El +.Pp +The main +.Nm +process runs with the following +.Xr pledge 2 +promises after startup: +.Bl -dash -compact +.It +.Va stdio +(memory allocation, logging) +.It +.Va rpath +(read configuration and resources) +.It +.Va proc +(fork for module launching) +.It +.Va exec +(launch the execution helper) +.El +.Pp +The execution helper runs with the following +.Xr pledge 2 +promises: +.Bl -dash -compact +.It +.Va stdio +.It +.Va proc +.It +.Va exec +.El +.Pp +.Nm +uses +.Xr unveil 2 +to restrict filesystem access to: +.Bl -dash -compact +.It +.Pa /usr/X11R6/lib/X11/fvwm/ +(read + execute) +.It +.Pa /etc/X11/fvwm/ +(read) +.It +.Pa /tmp/ +(read, write, create) +.El +.Pp +.Nm +modules are separate processes. +Each module opens its own X11 connection and communicates +with the main +.Nm +process via Unix pipes. +Module binaries are executed by the helper process, preventing +the main window manager from directly executing user commands. +.Sh SEE ALSO +.Xr fvwm_exec 1 , +.Xr FvwmAuto 1 , +.Xr FvwmBacker 1 , +.Xr FvwmBanner 1 , +.Xr FvwmButtons 1 , +.Xr FvwmCpp 1 , +.Xr FvwmForm 1 , +.Xr FvwmIconBox 1 , +.Xr FvwmIconMan 1 , +.Xr FvwmIdent 1 , +.Xr FvwmM4 1 , +.Xr FvwmPager 1 , +.Xr FvwmRearrange 1 , +.Xr FvwmSave 1 , +.Xr FvwmSaveDesk 1 , +.Xr FvwmScroll 1 , +.Xr FvwmTalk 1 , +.Xr FvwmWinList 1 , +.Xr xpmroot 1 , +.Xr pledge 2 , +.Xr unveil 2 +.Sh COMPATIBILITY +.Nm +is compatible with FVWM 2.2.5 configuration syntax. +Existing +.Pa .fvwm2rc +files should work without modification. +.Pp +Module IPC protocol semantics are preserved from FVWM 2.2.5. +The binary packet format and message type numbering are unchanged. +Module descriptor conventions are unchanged. +.Sh HISTORY +.Nm +was originally written by Robert Nation in 1993. +This is the OpenBSD fork of FVWM 2.2.5. +.Sh AUTHORS +.An Robert Nation +and many contributors. +.Ox +fork maintained by the +.Ox +project. +.Sh CAVEATS +Privilege separation, +.Xr pledge 2 , +and +.Xr unveil 2 +policies in this version have not been verified through runtime testing. +.Pp +The execution helper and imsg IPC have not been tested against real +X11 workloads. +Module protocol compatibility has been preserved through static +inspection of message layouts but has not been empirically verified. Index: fvwm/libs/ColorUtils.c =================================================================== RCS file: /cvs/src/xenocara/app/fvwm/libs/ColorUtils.c,v retrieving revision 1.1 diff -u -r1.1 fvwm/libs/ColorUtils.c --- fvwm/libs/ColorUtils.c +++ fvwm/libs/ColorUtils.c @@ -1,261 +1,133 @@ /* - * The following GPL code from scwm implements a good, fast 3D-shadowing - * algorithm. It converts the color from RGB to HLS space, then - * multiplies both the luminosity and the saturation by a specified - * factor (clipping at the extremes). Then it converts back to RGB and - * creates a color. The guts of it, i.e. the `color_mult' routine, looks - * a bit longish, but this is only because there are 6-way conditionals - * at the begining and end; it actually runs quite fast. The algorithm is - * the same as Gtk's, but the implemenation is independent and more - * streamlined. + * Copyright (c) 2025-2026 David Uhden Collado * - * Calling `adjust_pixel_brightness' with a `factor' of 1.3 for hilights - * and 0.7 for shadows exactly emulates Gtk's shadowing, which is, IMO - * the most visually pleasing shadowing of any widget set; using 1.2 and - * 0.5 respectively gives something closer to the "classic" fvwm effect - * with deeper shadows and more subtle hilights, but still (IMO) smoother - * and more attractive than fvwm. - * - * The only color these routines do not usefully handle is black; black - * will be returned even for a factor greater than 1.0, when optimally - * one would like to see a very dark gray. This could possibly be - * addressed by adding a small additive factor when brightening - * colors. If anyone adds that feature, please feed it upstream to me. - * - * Feel free to use this code in fvwm2, of course. - * - * - Maciej Stachowiak - * - * And, of course, history shows, we took him up on the offer. - * Integrated into fvwm2 by Dan Espen, 11/13/98. - */ - - -/* - * Copyright (C) 1997, 1998, Maciej Stachowiak and Greg J. Badros - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING.GPL. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "config.h" /* must be first */ - +#include #include -#include /* for X functions in general */ -#include "fvwmlib.h" /* prototype GetShadow GetHilit */ - -#define SCALE 65535.0 -#define HALF_SCALE (SCALE / 2) -typedef enum { - R_MAX_G_MIN, R_MAX_B_MIN, - G_MAX_B_MIN, G_MAX_R_MIN, - B_MAX_R_MIN, B_MAX_G_MIN -} MinMaxState; +#include "config.h" +#include "fvwmlib.h" -/* Multiply the HLS-space lightness and saturation of the color by the - given multiple, k - based on the way gtk does shading, but independently - coded. Should give better relief colors for many cases than the old - fvwm algorithm. */ +#define SCALE 65535.0 +#define HALF_SCALE (SCALE * 0.5) -/* FIXMS: This can probably be optimized more, examine later. */ +enum ColorChannel { CHANNEL_RED = 0, CHANNEL_GREEN = 1, CHANNEL_BLUE = 2 }; -static void -color_mult (unsigned short *red, - unsigned short *green, - unsigned short *blue, double k) +static void +color_mult(unsigned short *red, unsigned short *green, unsigned short *blue, + double factor) { - if (*red == *green && *red == *blue) { - double temp; - /* A shade of gray */ - temp = k * (double) (*red); - if (temp > SCALE) { - temp = SCALE; - } - *red = (unsigned short)(temp); - *green = *red; - *blue = *red; - } else { - /* Non-zero saturation */ - double r, g, b; - double min, max; - double a, l, s; - double delta; - double middle; - MinMaxState min_max_state; + double components[3]; + components[CHANNEL_RED] = (double)*red; + components[CHANNEL_GREEN] = (double)*green; + components[CHANNEL_BLUE] = (double)*blue; + + if (components[CHANNEL_RED] == components[CHANNEL_GREEN] && + components[CHANNEL_RED] == components[CHANNEL_BLUE]) { + double level = components[CHANNEL_RED] * factor; + if (level > SCALE) { + level = SCALE; + } + *red = (unsigned short)level; + *green = *red; + *blue = *red; + return; + } - r = (double) *red; - g = (double) *green; - b = (double) *blue; + int max_index = CHANNEL_RED; + int min_index = CHANNEL_RED; + for (int idx = CHANNEL_GREEN; idx <= CHANNEL_BLUE; ++idx) { + if (components[idx] > components[max_index]) { + max_index = idx; + } + if (components[idx] < components[min_index]) { + min_index = idx; + } + } - if (r > g) { - if (r > b) { - max = r; - if (g < b) { - min = g; - min_max_state = R_MAX_G_MIN; - a = b - g; - } else { - min = b; - min_max_state = R_MAX_B_MIN; - a = g - b; + int mid_index = + CHANNEL_RED + CHANNEL_GREEN + CHANNEL_BLUE - max_index - min_index; + double max_value = components[max_index]; + double min_value = components[min_index]; + double span = max_value - min_value; + double ratio = (components[mid_index] - min_value) / span; + + double lightness = 0.5 * (max_value + min_value); + double extrema_sum = max_value + min_value; + double saturation_denominator = (lightness <= HALF_SCALE) ? + extrema_sum : + (2.0 * SCALE - extrema_sum); + double saturation = span / saturation_denominator; + + lightness *= factor; + if (lightness > SCALE) { + lightness = SCALE; } - } else { - max = b; - min = g; - min_max_state = B_MAX_G_MIN; - a = r - g; - } - } else { - if (g > b) { - max = g; - if (b < r) { - min = b; - min_max_state = G_MAX_B_MIN; - a = r - b; - } else { - min = r; - min_max_state = G_MAX_R_MIN; - a = b - r; + saturation *= factor; + if (saturation > 1.0) { + saturation = 1.0; } - } else { - max = b; - min = r; - min_max_state = B_MAX_R_MIN; - a = g - r; - } - } - - delta = max - min; - a = a / delta; - - l = (max + min) / 2; - if (l <= HALF_SCALE) { - s = max + min; - } else { - s = 2.0 * SCALE - (max + min); - } - s = delta/s; - - l *= k; - if (l > SCALE) { - l = SCALE; - } - s *= k; - if (s > 1.0) { - s = 1.0; - } - if (l <= HALF_SCALE) { - max = l * (1 + s); - } else { - max = s * SCALE + l - s * l; - } + double new_max; + if (lightness <= HALF_SCALE) { + new_max = lightness * (1.0 + saturation); + } else { + new_max = + saturation * SCALE + lightness - saturation * lightness; + } - min = 2 * l - max; - delta = max - min; - middle = min + delta * a; + double new_min = 2.0 * lightness - new_max; + double new_span = new_max - new_min; + double new_mid = new_min + new_span * ratio; - switch (min_max_state) { - case R_MAX_G_MIN: - r = max; - g = min; - b = middle; - break; - case R_MAX_B_MIN: - r = max; - g = middle; - b = min; - break; - case G_MAX_B_MIN: - r = middle; - g = max; - b = min; - break; - case G_MAX_R_MIN: - r = min; - g = max; - b = middle; - break; - case B_MAX_G_MIN: - r = middle; - g = min; - b = max; - break; - case B_MAX_R_MIN: - r = min; - g = middle; - b = max; - break; - } + double updated[3]; + updated[max_index] = new_max; + updated[min_index] = new_min; + updated[mid_index] = new_mid; - *red = (unsigned short) r; - *green = (unsigned short) g; - *blue = (unsigned short) b; - } + *red = (unsigned short)updated[CHANNEL_RED]; + *green = (unsigned short)updated[CHANNEL_GREEN]; + *blue = (unsigned short)updated[CHANNEL_BLUE]; } -/* - * This routine uses PictureSaveDisplay and PictureCMap which must be - * created by InitPictureCMAP in Picture.c. - * - * If you attempt to use GetShadow and GetHilit, make sure your module - * calls InitPictureCMAP first. - */ static Pixel adjust_pixel_brightness(Pixel pixel, double factor) { - extern Colormap PictureCMap; - extern Display *PictureSaveDisplay; - XColor c; - c.pixel = pixel; - XQueryColor (PictureSaveDisplay, PictureCMap, &c); - color_mult(&c.red, &c.green, &c.blue, factor); - XAllocColor (PictureSaveDisplay, PictureCMap, &c); + extern Colormap PictureCMap; + extern Display *PictureSaveDisplay; + XColor color_spec; + + color_spec.pixel = pixel; + XQueryColor(PictureSaveDisplay, PictureCMap, &color_spec); + color_mult( + &color_spec.red, &color_spec.green, &color_spec.blue, factor); + XAllocColor(PictureSaveDisplay, PictureCMap, &color_spec); - return c.pixel; + return color_spec.pixel; } -/* - * These are the original fvwm2 APIs, one for highlights and one for - * shadows. Together, if used in a frame around a rectangle, they - * produce a 3d appearance. - * - * The input pixel, is normally the background color used in the - * rectangle. One would hope, when the user selects to color something - * with a multi-color pixmap, they will have the insight to also assign a - * background color to the pixmaped area that approximates the average - * color of the pixmap. - * - * Currently callers handle monochrome before calling this routine. The - * next logical enhancement is for that logic to be moved here. Probably - * a new API that deals with foreground/background/hilite/shadow - * allocation all in 1 call is the next logical extenstion. - * - * Color allocation is also a good candidate for becoming a library - * routine. The color allocation logic in FvwmButtons using the XPM - * library closeness stuff may be the ideal model. - * (dje 11/15/98) - */ #define DARKNESS_FACTOR 0.5 -Pixel GetShadow(Pixel background) { - return adjust_pixel_brightness(background, DARKNESS_FACTOR); +Pixel +GetShadow(Pixel background) +{ + return adjust_pixel_brightness(background, DARKNESS_FACTOR); } #define BRIGHTNESS_FACTOR 1.4 -Pixel GetHilite(Pixel background) { - return adjust_pixel_brightness(background, BRIGHTNESS_FACTOR); +Pixel +GetHilite(Pixel background) +{ + return adjust_pixel_brightness(background, BRIGHTNESS_FACTOR); } Index: fvwm/modules/FvwmBacker/root_bits.c =================================================================== RCS file: /cvs/src/xenocara/app/fvwm/modules/FvwmBacker/root_bits.c,v retrieving revision 1.1 diff -u -r1.1 fvwm/modules/FvwmBacker/root_bits.c --- fvwm/modules/FvwmBacker/root_bits.c +++ fvwm/modules/FvwmBacker/root_bits.c @@ -1,19 +1,17 @@ -/* Rewrite of this file by Dominik Vogt on Nov-1-1998 to remove the - * Xconsortium copyright. +/* + * Copyright (c) 2025-2026 David Uhden Collado * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include @@ -24,22 +22,22 @@ extern Display *dpy; extern int screen; extern char *Module; -unsigned long GetColor(char *name) +unsigned long +GetColor(char *name) { - XColor color; + Colormap cmap = DefaultColormap(dpy, screen); + XColor spec = {0}; + + if (!XParseColor(dpy, cmap, name, &spec)) { + fprintf(stderr, "%s: unknown color \"%s\"\n", Module, name); + exit(1); + } - color.pixel = 0; - if (!XParseColor (dpy, DefaultColormap(dpy,screen), name, &color)) - { - fprintf(stderr,"%s: unknown color \"%s\"\n",Module,name); - exit(1); - } - else if(!XAllocColor (dpy, DefaultColormap(dpy,screen), &color)) - { - fprintf(stderr, "%s: unable to allocate color for \"%s\"\n", - Module, name); - exit(1); - } + if (!XAllocColor(dpy, cmap, &spec)) { + fprintf(stderr, "%s: unable to allocate color for \"%s\"\n", + Module, name); + exit(1); + } - return color.pixel; + return spec.pixel; } Index: fvwm/modules/FvwmRearrange/FvwmRearrange.1 =================================================================== RCS file: /cvs/src/xenocara/app/fvwm/modules/FvwmRearrange/FvwmRearrange.1,v retrieving revision 1.1 diff -u -r1.1 fvwm/modules/FvwmRearrange/FvwmRearrange.1 --- fvwm/modules/FvwmRearrange/FvwmRearrange.1 +++ fvwm/modules/FvwmRearrange/FvwmRearrange.1 @@ -1,7 +1,8 @@ -.\" $OpenBSD: FvwmRearrange.1,v 1.1.1.1 2006/11/26 10:53:53 matthieu Exp $ +.\" $OpenBSD: FvwmRearrange.1,v 2.0 2025/10/18 10:00:00 random Exp $ .\" t -.\" @(#)FvwmRearrange.1 11/9/98 -.de EX \"Begin example +.\" @(#)FvwmRearrange.1 18/10/25 +.de EX +.\" Begin example macro .ne 5 .if n .sp 1 .if t .sp .5 @@ -9,133 +10,123 @@ .in +.5i .. .de EE +.\" End example macro .fi .in -.5i .if n .sp 1 .if t .sp .5 .. -.TH FvwmRearrange 1 "November 9, 1998" "FvwmRearrange 1.0" "FvwmRearrange 1.0" +.TH FVWMREARRANGE 1 "October 18, 2025" "2.0" "FVWM Modules" .UC .SH NAME -FvwmRearrange \- rearrange FVWM windows +FvwmRearrange \- reorganise FVWM clients .SH SYNOPSIS -FvwmRearrange is spawned by fvwm, so no command line invocation will work. - +FvwmRearrange is launched internally by fvwm; invoking it directly from a shell +is not supported. .SH DESCRIPTION -This module can be called to tile or cascade windows. - -When tiling the module attempts to tile windows on the current screen -subject to certain constraints. Horizontal or vertical tiling is performed -so that each window does not overlap another, and by default each window -is resized to its nearest resize increment (note sometimes some space -might appear between tiled windows -- this is why). - -When cascading the module attempts to cascade windows on the current screen -subject to certain constraints. Layering is performed so consecutive -windows will have their window titles visible underneath the previous. - +FvwmRearrange arranges windows either in a tiled grid or in a cascading stack. +Tiling fills the current screen with non-overlapping frames. Rows or columns +may be generated automatically so every client finds a slot. When tiling is in +effect, windows are resized to match their assigned cell unless stretching has +been disabled, which can leave gaps between tiles. +.PP +In cascade mode the module positions successive windows so that the title of +each client remains visible beneath the one before it. Windows can optionally +be constrained to a maximum width and height while still honouring the resize +increment rules. .SH INVOCATION -FvwmRearrange is best invoked from a menu, popup or button. There are a -number of command line options which can be used to constrain the -layering, these are described below. As an example case, one could -call FvwmRearrange with the following arguments: +FvwmRearrange is normally bound to menus, buttons, or key bindings. The module +accepts a variety of switches that tailor how windows are selected and laid +out. The following samples show typical usage: .EX FvwmRearrange -tile -h 10 10 90 90 .EE -or .EX -FvwmRearrange -cascade \-resize 10 2 80 70 +FvwmRearrange -cascade -resize 10 2 80 70 .EE - -The first invocation will horizontally tile windows with a bounding box -which starts at 10 by 10 percent into and down the screen and ends at -90 by 90 percent into and down the screen. - -The second invocation will cascade windows starting 10 by 2 percent into and -down the screen. Windows will be constrained to 80 by 70 percent of -the screen dimensions. Since the \fIresize\fP is also specified, -windows will be resized to the given constrained width and height. - -FvwmRearrange can be called as FvwmTile or FvwmCascade. This is equivalent -to providing the -tile or -cascade option. This form is obsolete and -supplied for backwards compatibility only. - -Command-line arguments passed to FvwmRearrange are described here. +.PP +The first command tiles across the screen horizontally, beginning 10 percent +from the left and top edges and finishing at the point 90 percent across and +down. The second command cascades windows starting 10 percent across and +2 percent down, resizing each client to 80 by 70 percent of the screen when +possible. +.PP +For backward compatibility the module can also be invoked as FvwmTile or +FvwmCascade, which internally pass \-tile or \-cascade. +.SH OPTIONS +The options recognised by FvwmRearrange are described below. .IP \-a -Causes \fIall\fP window styles to be affected, even ones with the -WindowListSkip style. +Process every window, including those marked with the WindowListSkip style. As +part of this shortcut, untitled, transient, and maximised clients are also +selected. .IP \-cascade -Cascade windows. This argument must be the first on the command line. -This is the default. +Choose cascade mode. If neither \-cascade nor \-tile is supplied, cascade is +the default behaviour. .IP \-desk -Causes all windows on the desk to be cascaded/tiled instead of the -current screen only. +Operate on all windows on the current desk rather than limiting the action to +those that intersect the visible screen. .IP \-flatx -Inhibits border width increment. Only used when cascading. +When cascading, suppress the automatic horizontal offset that would normally be +added for each step. .IP \-flaty -Inhibits border height increment. Only used when cascading. +When cascading, suppress the automatic vertical offset that would normally be +added for each step. .IP \-h -Tiles horizontally (default is to tile vertically). Used for tiling only. -.IP "\-incx \fIarg\fP" -Specifies a horizontal increment which is successively added to -cascaded windows. \fIarg\fP is a percentage of screen width, or pixel -value if a \fIp\fP is suffixed. Default is zero. Used only for cascading. -.IP "\-incy \fIarg\fP" -Specifies a vertical increment which is successively added to cascaded -windows. \fIarg\fP is a percentage of screen height, or pixel value -if a \fIp\fP is suffixed. Default is zero. Used only for cascading. - +Tile across the screen first, and then downward. Without this option the module +tiles vertically. +.IP "\-incx \fIvalue\fP" +Add \fIvalue\fP to the horizontal offset between cascaded windows. The value +is taken as a percentage of the screen width unless suffixed with \fIp\fP, in +which case it is a pixel amount. +.IP "\-incy \fIvalue\fP" +Add \fIvalue\fP to the vertical offset between cascaded windows. Percentages +are relative to the screen height; appending \fIp\fP forces interpretation as +pixels. .IP \-m -Causes maximized windows to also be affected (implied by \-all). -.IP "\-mn \fIarg\fP" -Tiles up to \fIarg\fP windows in tile direction. If more windows -exist, a new direction row or column is created (in effect, a matrix -is created). Used only when tiling windows. +Include maximised windows in the operation (this is implied by \-a). +.IP "\-mn \fIcount\fP" +Limit each tile row or column to \fIcount\fP windows before starting another +row or column. Only meaningful when tiling. .IP \-noraise -Inhibits window raising, leaving the depth ordering intact. +Do not alter the stacking order of affected clients. .IP \-noresize -Inhibits window resizing, leaving window sizes intact. This is the default -when cascading windows. +Preserve existing window sizes. This is the implicit default when cascading. .IP \-nostretch -If tiling: inhibits window growth to fit tile. Windows are shrunk to fit the -tile but not expanded. - -If cascading: inhibits window expansion when using the \-resize option. Windows -will only shrink to fit the maximal width and height (if given). +While tiling, only shrink windows to fit their cells; never enlarge them. While +cascading, do not expand windows beyond the specified maximum size when +\-resize is active. .IP \-r -Reverses the window sequence. +Reverse the sequence in which windows are processed. .IP \-resize -Forces all windows to resize to the constrained width and height (if -given). This is the default when tiling windows. +Force clients to adopt the requested tiling or cascade dimensions. This is the +default when tiling. .IP \-s -Causes sticky windows to also be affected (implied by \-all). +Consider sticky windows along with normal clients (also implied by \-a). .IP \-t -Causes transient windows to also be affected (implied by \-all). +Include transient windows (implied by \-a). .IP \-tile -Tile windows. This argument must be the first on the command line. +Tile windows. If supplied it must appear before other options. .IP \-u -Causes untitled windows to also be affected (implied by \-all). - -Up to four numbers can be placed on the command line that are not -switches. The first pair specify an x and y offset to start the first -window (default is 0, 0). -The meaning of the second pair depends on operation mode: - -When tiling windows it specifies an absolute coordinate reference -denoting the lower right bounding box for tiling. - -When cascading it specifies a maximal width and height for the layered -windows. If an affected window exceeds either this width or height, it -is resized to the maximal width or height. - -If any number is suffixed with the letter p, then it is taken to be a -pixel value, otherwise it is interpreted as a screen percentage. -Specifying zero for any parameter is equivalent to not specifying it. - -.SH BUGS -It is probably not a good idea to delete windows while windows are -being rearranged. - +Include untitled windows (implied by \-a). +.PP +You may supply up to four additional numeric arguments. The first two numbers +specify the initial X and Y offsets, in percentages of the screen size unless +they end with \fIp\fP to denote pixels. The interpretation of the third and +fourth numbers varies with the chosen mode: +.RS +.TP +Tiling +The third and fourth parameters represent the lower-right corner of the tiling +bounding box. +.TP +Cascading +The third value caps the window width and the fourth value caps the height. A +window that exceeds either limit is resized down to the limit. +.RE +.PP +Supplying zero for any numeric parameter leaves the corresponding default in +place. .SH AUTHORS Andrew Veliath (original FvwmTile and FvwmCascade modules) -Dominik Vogt (merged FvwmTile and FvwmCascade to FvwmRearrange) +Dominik Vogt (merged FvwmTile and FvwmCascade into FvwmRearrange) +David Uhden Collado (Complete rewrite and modernization) Index: fvwm/modules/FvwmRearrange/FvwmRearrange.c =================================================================== RCS file: /cvs/src/xenocara/app/fvwm/modules/FvwmRearrange/FvwmRearrange.c,v retrieving revision 1.1 diff -u -r1.1 fvwm/modules/FvwmRearrange/FvwmRearrange.c --- fvwm/modules/FvwmRearrange/FvwmRearrange.c +++ fvwm/modules/FvwmRearrange/FvwmRearrange.c @@ -1,40 +1,34 @@ /* - * FvwmRearrange.c -- fvwm module to arrange windows + * FvwmRearrange: fvwm module to tile or cascade windows in a region. * - * Copyright (C) 1996, 1997, 1998, 1999 Andrew T. Veliath + * Copyright (c) 2025-2026 David Uhden Collado * - * Version 1.0 + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Combined FvwmTile and FvwmCascade to FvwmRearrange module. - * 9-Nov-1998 Dominik Vogt + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "config.h" +#include +#include + +#include +#include #include #include -#include #include -#include -#include #include -#include -#ifdef HAVE_SYS_BSDTYPES_H -#include +#include "config.h" +#include "../../fvwm/fvwm_sandbox.h" + #endif #if HAVE_SYS_SELECT_H @@ -43,587 +37,832 @@ #include -#include "fvwmlib.h" -#include "../../fvwm/module.h" #include "../../fvwm/fvwm.h" +#include "../../fvwm/module.h" +#include "fvwmlib.h" -typedef struct window_item { - Window frame; - int th, bw; - unsigned long width, height; - struct window_item *prev, *next; -} window_item, *window_list; - -/* vars */ -Display *dpy; -int dwidth, dheight; -char *argv0; -int fd[2], fd_width; -window_list wins = NULL, wins_tail = NULL; -int wins_count = 0; -FILE *console; - -/* switches */ -int ofsx = 0, ofsy = 0; -int maxw = 0, maxh = 0; -int maxx, maxy; -int untitled = 0, transients = 0; -int maximized = 0; -int all = 0; -int desk = 0; -int reversed = 0, raise_window = 1; -int resize = 0; -int nostretch = 0; -int sticky = 0; -int flatx = 0, flaty = 0; -int incx = 0, incy = 0; -int horizontal = 0; -int maxnum = 0; - -char FvwmTile; -char FvwmCascade; - -void insert_window_list(window_list *wl, window_item *i) +void DeadPipe(int sig); + +typedef struct ClientNode { + Window frame; + int title_height; + int border_width; + unsigned long width; + unsigned long height; + struct ClientNode *prev; + struct ClientNode *next; +} ClientNode; + +typedef struct ModuleState { + Display *display; + int screen_width; + int screen_height; + char *program_name; + int pipe_fd[2]; + int fd_width; + ClientNode *head; + ClientNode *tail; + int client_count; + FILE *log; + int offset_x; + int offset_y; + int limit_width; + int limit_height; + int bound_x; + int bound_y; + int include_untitled; + int include_transients; + int include_maximized; + int include_sticky; + int include_all; + int entire_desk; + int reverse_order; + int raise_clients; + int resize_clients; + int avoid_stretch; + int flat_x; + int flat_y; + int step_x; + int step_y; + int tile_horizontal; + int tile_limit; + char run_tile; + char run_cascade; +} ModuleState; + +static ModuleState g_state = {.raise_clients = 1}; + +static void +prepend_client(ModuleState *state, ClientNode *node) { - if (*wl) { - if ((i->prev = (*wl)->prev)) - i->prev->next = i; - i->next = *wl; - (*wl)->prev = i; - } else - i->next = i->prev = NULL; - *wl = i; + node->prev = NULL; + node->next = state->head; + if (state->head) { + state->head->prev = node; + } else { + state->tail = node; + } + state->head = node; + ++state->client_count; } -void free_window_list(window_list *wl) +static void +release_clients(ModuleState *state) { - window_item *q; - while (*wl) { - q = *wl; - *wl = (*wl)->next; - free(q); - } + ClientNode *cursor = state->head; + while (cursor) { + ClientNode *next = cursor->next; + free(cursor); + cursor = next; + } + state->head = NULL; + state->tail = NULL; + state->client_count = 0; } -int is_suitable_window(unsigned long *body) +static ClientNode * +find_client(ModuleState *state, Window frame) { - XWindowAttributes xwa; - unsigned long flags = body[8]; - - if ((flags&WINDOWLISTSKIP) && !all) - return 0; - - if ((flags&MAXIMIZED) && !maximized) - return 0; - - if ((flags&STICKY) && !sticky) - return 0; - - if (!XGetWindowAttributes(dpy, (Window)body[1], &xwa)) - return 0; - - if (xwa.map_state != IsViewable) - return 0; + for (ClientNode *cursor = state->head; cursor; cursor = cursor->next) { + if (cursor->frame == frame) { + return cursor; + } + } + return NULL; +} - if (!(flags&MAPPED)) - return 0; +static void +detach_client(ModuleState *state, ClientNode *node) +{ + if (!node) { + return; + } + if (node->prev) { + node->prev->next = node->next; + } else { + state->head = node->next; + } + if (node->next) { + node->next->prev = node->prev; + } else { + state->tail = node->prev; + } + free(node); + --state->client_count; +} - if (flags&ICONIFIED) - return 0; +static int +window_matches(ModuleState *state, unsigned long *body) +{ + unsigned long flags = body[8]; + XWindowAttributes xwa; - if (!desk) { - int x = (int)body[3], y = (int)body[4]; - int w = (int)body[5], h = (int)body[6]; - if (!((x < dwidth) && (y < dheight) - && (x + w > 0) && (y + h > 0))) - return 0; - } - - if (!(flags&TITLE) && !untitled) - return 0; + if ((flags & WINDOWLISTSKIP) && !state->include_all) { + return 0; + } + if ((flags & MAXIMIZED) && !state->include_maximized) { + return 0; + } + if ((flags & STICKY) && !state->include_sticky) { + return 0; + } + if (!XGetWindowAttributes(state->display, (Window)body[1], &xwa)) { + return 0; + } + if (xwa.map_state != IsViewable) { + return 0; + } + if (!(flags & MAPPED)) { + return 0; + } + if (flags & ICONIFIED) { + return 0; + } + if (!state->entire_desk) { + int x = (int)body[3]; + int y = (int)body[4]; + int w = (int)body[5]; + int h = (int)body[6]; + if (!((x < state->screen_width) && (y < state->screen_height) && + (x + w > 0) && (y + h > 0))) { + return 0; + } + } + if (!(flags & TITLE) && !state->include_untitled) { + return 0; + } + if ((flags & TRANSIENT) && !state->include_transients) { + return 0; + } + return 1; +} - if ((flags&TRANSIENT) && !transients) - return 0; +static int +collect_client(ModuleState *state) +{ + unsigned long header[HEADER_SIZE]; + unsigned long *body; + fd_set infds; + int keep_running = 1; + + FD_ZERO(&infds); + FD_SET(state->pipe_fd[1], &infds); + select(state->fd_width, &infds, NULL, NULL, NULL); + + if (ReadFvwmPacket(state->pipe_fd[1], header, &body) > 0) { + switch (header[1]) { + case M_CONFIGURE_WINDOW: + if (window_matches(state, body)) { + ClientNode *node = (ClientNode *)xmalloc( + sizeof(ClientNode)); + node->frame = (Window)body[1]; + node->title_height = (int)body[9]; + node->border_width = (int)body[10]; + node->width = body[5]; + node->height = body[6]; + prepend_client(state, node); + } + break; + case M_DESTROY_WINDOW: + if (body) { + ClientNode *node = + find_client(state, (Window)body[1]); + if (node) { + detach_client(state, node); + } + } + break; + case M_END_WINDOWLIST: + keep_running = 0; + break; + default: + fprintf(state->log, + "%s: internal inconsistency: unknown message\n", + state->program_name); + break; + } + free(body); + } else { + keep_running = 0; + } - return 1; + return keep_running; } -int get_window(void) +static int +await_configure(ModuleState *state, ClientNode *node) { - unsigned long header[HEADER_SIZE], *body; - int count, last = 0; - fd_set infds; - FD_ZERO(&infds); - FD_SET(fd[1], &infds); - select(fd_width,&infds, 0, 0, NULL); - if ((count = ReadFvwmPacket(fd[1],header,&body)) > 0) { - switch (header[1]) - { - case M_CONFIGURE_WINDOW: - if (is_suitable_window(body)) { - window_item *wi = - (window_item*)safemalloc(sizeof( window_item )); - wi->frame = (Window)body[1]; - wi->th = (int)body[9]; - wi->bw = (int)body[10]; - wi->width = body[5]; - wi->height = body[6]; - if (!wins_tail) wins_tail = wi; - insert_window_list(&wins, wi); - ++wins_count; - } - last = 1; - break; - - case M_END_WINDOWLIST: - break; - - default: - fprintf(console, - "%s: internal inconsistency: unknown message\n", - argv0); - break; - } - free(body); - } - return last; + for (;;) { + unsigned long header[HEADER_SIZE]; + unsigned long *body; + fd_set infds; + + FD_ZERO(&infds); + FD_SET(state->pipe_fd[1], &infds); + select(state->fd_width, &infds, NULL, NULL, NULL); + + if (ReadFvwmPacket(state->pipe_fd[1], header, &body) > 0) { + switch (header[1]) { + case M_CONFIGURE_WINDOW: + if (body && (Window)body[1] == node->frame) { + free(body); + return 1; + } + break; + case M_DESTROY_WINDOW: + if (body) { + Window frame = (Window)body[1]; + if (frame == node->frame) { + free(body); + return 0; + } + ClientNode *other = + find_client(state, frame); + if (other) { + detach_client(state, other); + } + } + break; + case M_END_WINDOWLIST: + break; + default: + break; + } + free(body); + } else { + return 0; + } + } } -void wait_configure(window_item *wi) +static int +parse_metric(const char *token, unsigned long reference) { - int found = 0; - unsigned long header[HEADER_SIZE], *body; - int count; - fd_set infds; - FD_ZERO(&infds); - FD_SET(fd[1], &infds); - select(fd_width,&infds, 0, 0, NULL); - while (!found) - if ((count = ReadFvwmPacket(fd[1],header,&body)) > 0) { - if ((header[1] == M_CONFIGURE_WINDOW) - && (Window)body[1] == wi->frame) - found = 1; - free(body); + char *endptr; + long value; + + if (!token || !*token) { + return 0; + } + + value = strtol(token, &endptr, 10); + if (endptr && *endptr && isalpha((unsigned char)*endptr)) { + return (int)value; } + return (int)((value * (long)reference) / 100); } -int atopixel(char *s, unsigned long f) +static void +send_resize(ModuleState *state, const ClientNode *node, unsigned long width, + unsigned long height) { - int l = strlen(s); - if (l < 1) return 0; - if (isalpha(s[l - 1])) { - char s2[24]; - strcpy(s2,s); - s2[strlen(s2) - 1] = 0; - return atoi(s2); - } - return (atoi(s) * f) / 100; + char command[128]; + + snprintf(command, sizeof(command), "Resize %lup %lup", width, height); + SendInfo(state->pipe_fd, command, node->frame); } -void tile_windows(void) +static void +send_move(ModuleState *state, const ClientNode *node, int x, int y) { - char msg[128]; - int cur_x = ofsx, cur_y = ofsy; - int wdiv, hdiv, i, j, count = 1; - window_item *w = reversed ? wins_tail : wins; - - if (horizontal) { - if ((maxnum > 0) && (maxnum < wins_count)) { - count = wins_count / maxnum; - if (wins_count % maxnum) ++count; - hdiv = (maxy - ofsy + 1) / maxnum; - } else { - maxnum = wins_count; - hdiv = (maxy - ofsy + 1) / wins_count; - } - wdiv = (maxx - ofsx + 1) / count; - - for (i = 0; w && (i < count); ++i) { - for (j = 0; w && (j < maxnum); ++j) { - int nw = wdiv - w->bw * 2; - int nh = hdiv - w->bw * 2 - w->th; - - if (resize) { - if (nostretch) { - if (nw > w->width) - nw = w->width; - if (nh > w->height) - nh = w->height; - } - sprintf(msg, "Resize %lup %lup", - (nw > 0) ? nw : w->width, - (nh > 0) ? nh : w->height); - SendInfo(fd,msg,w->frame); + char command[128]; + + snprintf(command, sizeof(command), "Move %up %up", x, y); + SendInfo(state->pipe_fd, command, node->frame); +} + +static void +tile_clients(ModuleState *state) +{ + ClientNode *cursor = state->reverse_order ? state->tail : state->head; + int stripes = 1; + int slots_per_stripe; + int wdiv; + int hdiv; + int current_x = state->offset_x; + int current_y = state->offset_y; + int limit = state->tile_limit; + + if (state->tile_horizontal) { + if ((limit > 0) && (limit < state->client_count)) { + stripes = state->client_count / limit; + if (state->client_count % limit) { + ++stripes; + } + hdiv = (state->bound_y - state->offset_y + 1) / limit; + } else { + limit = state->client_count; + state->tile_limit = limit; + hdiv = (state->bound_y - state->offset_y + 1) / + state->client_count; + } + slots_per_stripe = limit; + wdiv = (state->bound_x - state->offset_x + 1) / stripes; + + for (int s = 0; cursor && (s < stripes); ++s) { + for (int slot = 0; cursor && (slot < slots_per_stripe); + ++slot) { + int new_width = wdiv - cursor->border_width * 2; + int new_height = hdiv - + cursor->border_width * 2 - + cursor->title_height; + + if (state->resize_clients) { + if (state->avoid_stretch) { + if (new_width > + (int)cursor->width) { + new_width = + (int)cursor->width; + } + if (new_height > + (int)cursor->height) { + new_height = + (int)cursor->height; + } + } + send_resize(state, cursor, + (new_width > 0) ? + (unsigned long)new_width : + cursor->width, + (new_height > 0) ? + (unsigned long)new_height : + cursor->height); + } + + send_move(state, cursor, current_x, current_y); + if (state->raise_clients) { + SendInfo(state->pipe_fd, "Raise", + cursor->frame); + } + + current_y += hdiv; + { + int alive = + await_configure(state, cursor); + ClientNode *next = state->reverse_order + ? + cursor->prev : cursor->next; + if (!alive) { + detach_client(state, cursor); + } + cursor = next; + } + } + current_x += wdiv; + current_y = state->offset_y; } - sprintf(msg, "Move %up %up", cur_x, cur_y); - SendInfo(fd,msg,w->frame); - if (raise_window) - SendInfo(fd,"Raise",w->frame); - cur_y += hdiv; - wait_configure(w); - w = reversed ? w->prev : w->next; - } - cur_x += wdiv; - cur_y = ofsy; - } - } else { - if ((maxnum > 0) && (maxnum < wins_count)) { - count = wins_count / maxnum; - if (wins_count % maxnum) ++count; - wdiv = (maxx - ofsx + 1) / maxnum; } else { - maxnum = wins_count; - wdiv = (maxx - ofsx + 1) / wins_count; - } - hdiv = (maxy - ofsy + 1) / count; - - for (i = 0; w && (i < count); ++i) { - for (j = 0; w && (j < maxnum); ++j) { - int nw = wdiv - w->bw * 2; - int nh = hdiv - w->bw * 2 - w->th; - - if (resize) { - if (nostretch) { - if (nw > w->width) - nw = w->width; - if (nh > w->height) - nh = w->height; - } - sprintf(msg, "Resize %lup %lup", - (nw > 0) ? nw : w->width, - (nh > 0) ? nh : w->height); - SendInfo(fd,msg,w->frame); + if ((limit > 0) && (limit < state->client_count)) { + stripes = state->client_count / limit; + if (state->client_count % limit) { + ++stripes; + } + wdiv = (state->bound_x - state->offset_x + 1) / limit; + } else { + limit = state->client_count; + state->tile_limit = limit; + wdiv = (state->bound_x - state->offset_x + 1) / + state->client_count; } - sprintf(msg, "Move %up %up", cur_x, cur_y); - SendInfo(fd,msg,w->frame); - if (raise_window) - SendInfo(fd,"Raise",w->frame); - cur_x += wdiv; - wait_configure(w); - w = reversed ? w->prev : w->next; - } - cur_x = ofsx; - cur_y += hdiv; - } - } + slots_per_stripe = limit; + hdiv = (state->bound_y - state->offset_y + 1) / stripes; + + for (int s = 0; cursor && (s < stripes); ++s) { + for (int slot = 0; cursor && (slot < slots_per_stripe); + ++slot) { + int new_width = wdiv - cursor->border_width * 2; + int new_height = hdiv - + cursor->border_width * 2 - + cursor->title_height; + + if (state->resize_clients) { + if (state->avoid_stretch) { + if (new_width > + (int)cursor->width) { + new_width = + (int)cursor->width; + } + if (new_height > + (int)cursor->height) { + new_height = + (int)cursor->height; + } + } + send_resize(state, cursor, + (new_width > 0) ? + (unsigned long)new_width : + cursor->width, + (new_height > 0) ? + (unsigned long)new_height : + cursor->height); + } + + send_move(state, cursor, current_x, current_y); + if (state->raise_clients) { + SendInfo(state->pipe_fd, "Raise", + cursor->frame); + } + + current_x += wdiv; + { + int alive = + await_configure(state, cursor); + ClientNode *next = state->reverse_order + ? + cursor->prev : cursor->next; + if (!alive) { + detach_client(state, cursor); + } + cursor = next; + } + } + current_x = state->offset_x; + current_y += hdiv; + } + } } -void cascade_windows(void) +static void +cascade_clients(ModuleState *state) { - char msg[128]; - int cur_x = ofsx, cur_y = ofsy; - window_item *w = reversed ? wins_tail : wins; - while (w) - { - unsigned long nw = 0, nh = 0; - if (raise_window) - SendInfo(fd,"Raise",w->frame); - sprintf(msg, "Move %up %up", cur_x, cur_y); - SendInfo(fd,msg,w->frame); - if (resize) { - if (nostretch) { - if (maxw - && (w->width > maxw)) - nw = maxw; - if (maxh - && (w->height > maxh)) - nh = maxh; - } else { - nw = maxw; - nh = maxh; - } - if (nw || nh) { - sprintf(msg, "Resize %lup %lup", - nw ? nw : w->width, - nh ? nh : w->height); - SendInfo(fd,msg,w->frame); - } - } - wait_configure(w); - if (!flatx) - cur_x += w->bw; - cur_x += incx; - if (!flaty) - cur_y += w->bw + w->th; - cur_y += incy; - w = reversed ? w->prev : w->next; - } + ClientNode *cursor = state->reverse_order ? state->tail : state->head; + int current_x = state->offset_x; + int current_y = state->offset_y; + + while (cursor) { + unsigned long target_width = 0; + unsigned long target_height = 0; + int advance_x = state->step_x; + int advance_y = state->step_y; + + if (state->raise_clients) { + SendInfo(state->pipe_fd, "Raise", cursor->frame); + } + + send_move(state, cursor, current_x, current_y); + + if (state->resize_clients) { + if (state->avoid_stretch) { + if (state->limit_width && + cursor->width > + (unsigned long)state->limit_width) { + target_width = + (unsigned long)state->limit_width; + } + if (state->limit_height && + cursor->height > + (unsigned long)state->limit_height) { + target_height = + (unsigned long)state->limit_height; + } + } else { + target_width = state->limit_width; + target_height = state->limit_height; + } + + if (target_width || target_height) { + send_resize(state, cursor, + target_width ? target_width : cursor->width, + target_height ? target_height : + cursor->height); + } + } + + if (!state->flat_x) { + advance_x += cursor->border_width; + } + if (!state->flat_y) { + advance_y += + cursor->border_width + cursor->title_height; + } + + { + int alive = await_configure(state, cursor); + ClientNode *next = + state->reverse_order ? cursor->prev : cursor->next; + if (!alive) { + detach_client(state, cursor); + } + cursor = next; + } + + current_x += advance_x; + current_y += advance_y; + } } -void parse_args(char *s, int argc, char *argv[], int argi) +static void +parse_arguments(ModuleState *state, const char *source, int argc, char *argv[], + int start_index) { - int nsargc = 0; - /* parse args */ - for (; argi < argc; ++argi) - { - if (!strcmp(argv[argi],"-tile") || !strcmp(argv[argi],"-cascade")) { - /* ignore */ - } - else if (!strcmp(argv[argi],"-u")) { - untitled = 1; - } - else if (!strcmp(argv[argi],"-t")) { - transients = 1; - } - else if (!strcmp(argv[argi], "-a")) { - all = untitled = transients = maximized = 1; - if (FvwmCascade) - sticky = 1; - } - else if (!strcmp(argv[argi], "-r")) { - reversed = 1; - } - else if (!strcmp(argv[argi], "-noraise")) { - raise_window = 0; - } - else if (!strcmp(argv[argi], "-noresize")) { - resize = 0; - } - else if (!strcmp(argv[argi], "-nostretch")) { - nostretch = 1; - } - else if (!strcmp(argv[argi], "-desk")) { - desk = 1; - } - else if (!strcmp(argv[argi], "-flatx")) { - flatx = 1; - } - else if (!strcmp(argv[argi], "-flaty")) { - flaty = 1; - } - else if (!strcmp(argv[argi], "-r")) { - reversed = 1; - } - else if (!strcmp(argv[argi], "-h")) { - horizontal = 1; - } - else if (!strcmp(argv[argi], "-m")) { - maximized = 1; - } - else if (!strcmp(argv[argi], "-s")) { - sticky = 1; - } - else if (!strcmp(argv[argi], "-mn") && ((argi + 1) < argc)) { - maxnum = atoi(argv[++argi]); - } - else if (!strcmp(argv[argi], "-resize")) { - resize = 1; - } - else if (!strcmp(argv[argi], "-nostretch")) { - nostretch = 1; - } - else if (!strcmp(argv[argi], "-incx") && ((argi + 1) < argc)) { - incx = atopixel(argv[++argi], dwidth); - } - else if (!strcmp(argv[argi], "-incy") && ((argi + 1) < argc)) { - incy = atopixel(argv[++argi], dheight); - } - else { - if (++nsargc > 4) { - fprintf(console, - "%s: %s: ignoring unknown arg %s\n", - argv0, s, argv[argi]); - continue; - } - if (nsargc == 1) { - ofsx = atopixel(argv[argi], dwidth); - } else if (nsargc == 2) { - ofsy = atopixel(argv[argi], dheight); - } else if (nsargc == 3) { - if (FvwmCascade) - maxw = atopixel(argv[argi], dwidth); - else /* FvwmTile */ - maxx = atopixel(argv[argi], dwidth); - } else if (nsargc == 4) { - if (FvwmCascade) - maxh = atopixel(argv[argi], dheight); - else /* FvwmTile */ - maxy = atopixel(argv[argi], dheight); - } - } - } + int positional = 0; + + for (int i = start_index; i < argc; ++i) { + const char *arg = argv[i]; + + if (!strcmp(arg, "-tile") || !strcmp(arg, "-cascade")) { + continue; + } else if (!strcmp(arg, "-u")) { + state->include_untitled = 1; + } else if (!strcmp(arg, "-t")) { + state->include_transients = 1; + } else if (!strcmp(arg, "-a")) { + state->include_all = 1; + state->include_untitled = 1; + state->include_transients = 1; + state->include_maximized = 1; + if (state->run_cascade) { + state->include_sticky = 1; + } + } else if (!strcmp(arg, "-r")) { + state->reverse_order = 1; + } else if (!strcmp(arg, "-noraise")) { + state->raise_clients = 0; + } else if (!strcmp(arg, "-noresize")) { + state->resize_clients = 0; + } else if (!strcmp(arg, "-nostretch")) { + state->avoid_stretch = 1; + } else if (!strcmp(arg, "-desk")) { + state->entire_desk = 1; + } else if (!strcmp(arg, "-flatx")) { + state->flat_x = 1; + } else if (!strcmp(arg, "-flaty")) { + state->flat_y = 1; + } else if (!strcmp(arg, "-h")) { + state->tile_horizontal = 1; + } else if (!strcmp(arg, "-m")) { + state->include_maximized = 1; + } else if (!strcmp(arg, "-s")) { + state->include_sticky = 1; + } else if (!strcmp(arg, "-mn") && ((i + 1) < argc)) { + state->tile_limit = atoi(argv[++i]); + } else if (!strcmp(arg, "-resize")) { + state->resize_clients = 1; + } else if (!strcmp(arg, "-incx") && ((i + 1) < argc)) { + state->step_x = + parse_metric(argv[++i], state->screen_width); + } else if (!strcmp(arg, "-incy") && ((i + 1) < argc)) { + state->step_y = + parse_metric(argv[++i], state->screen_height); + } else { + ++positional; + if (positional > 4) { + fprintf(state->log, + "%s: %s: ignoring unknown arg %s\n", + state->program_name, source, arg); + continue; + } + + if (positional == 1) { + state->offset_x = + parse_metric(arg, state->screen_width); + } else if (positional == 2) { + state->offset_y = + parse_metric(arg, state->screen_height); + } else if (positional == 3) { + if (state->run_cascade) { + state->limit_width = parse_metric( + arg, state->screen_width); + } else { + state->bound_x = parse_metric( + arg, state->screen_width); + } + } else if (positional == 4) { + if (state->run_cascade) { + state->limit_height = parse_metric( + arg, state->screen_height); + } else { + state->bound_y = parse_metric( + arg, state->screen_height); + } + } + } + } } #ifdef USERC -int parse_line(char *s, char ***args) +static int +tokenise_config(char *line, char ***argv_out) { - int count = 0, i = 0; - char *arg_save[48]; - strtok(s, " "); - while ((s = strtok(NULL, " "))) - arg_save[count++] = s; - *args = (char **)safemalloc(sizeof( char * ) * count); - for (; i < count; ++i) - (*args)[i] = arg_save[i]; - return count; + char *tokens[48]; + int count = 0; + char *cursor = strtok(line, " \t"); + + while (cursor && count < 48) { + cursor = strtok(NULL, " \t"); + if (!cursor) { + break; + } + tokens[count++] = cursor; + } + + if (count > 0) { + *argv_out = (char **)xmalloc(sizeof(char *) * count); + for (int i = 0; i < count; ++i) { + (*argv_out)[i] = tokens[i]; + } + } else { + *argv_out = NULL; + } + + return count; } #ifdef FVWM1 -char *GetConfigLine(char *filename, char *match) +static char * +LoadConfigLine(const char *filename, const char *match) { - FILE *f = fopen(filename, "r"); - if (f) { - int l = strlen(match), found = 0; - char line[256], *s = line; - line[0] = 0; - s = fgets(line, 256, f); - while (s && !found) { - if (strncmp(line, match, l) == 0) { - found = 1; - break; - } - s = fgets(line, 256, f); - } - fclose(f); - if (found) { - char *ret; - int l2 = strlen(line); - ret = (char *)safemalloc(sizeof(char) * l2); - strcpy(ret, line); - if (ret[l2 - 1] == '\n') - ret[l2 - 1] = 0; - return ret; - } else - return NULL; - } else + FILE *f = fopen(filename, "r"); + if (f) { + char line[256]; + size_t match_len = strlen(match); + + while (fgets(line, sizeof(line), f)) { + if (strncmp(line, match, match_len) == 0) { + size_t len = strlen(line); + char *copy = (char *)xmalloc(len + 1); + + strcpy(copy, line); + if (len && copy[len - 1] == '\n') { + copy[len - 1] = '\0'; + } + fclose(f); + return copy; + } + } + fclose(f); + } return NULL; } #endif /* FVWM1 */ #endif /* USERC */ -void DeadPipe(int sig) { exit(0); } +static void +handle_sigpipe(int sig) +{ + (void)sig; + exit(0); +} -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { + ModuleState *state = &g_state; + #ifdef USERC - char match[128]; - int config_line_count, len; - char *config_line; + char match[128]; + char *config_line; #endif - console = fopen("/dev/console","w"); - if (!console) console = stderr; + state->log = fopen("/dev/console", "w"); + if (!state->log) { + state->log = stderr; + } - if (!(argv0 = strrchr(argv[0],'/'))) - argv0 = argv[0]; - else - ++argv0; + state->program_name = strrchr(argv[0], '/'); + state->program_name = + state->program_name ? state->program_name + 1 : argv[0]; - if (argc < 6) { - fprintf(stderr, + if (argc < 6) { #ifdef FVWM1 - "%s: module should be executed by fvwm only\n", + fprintf(stderr, "%s: module should be executed by fvwm only\n", + state->program_name); #else - "%s: module should be executed by fvwm2 only\n", + fprintf(stderr, "%s: module should be executed by fvwm2 only\n", + state->program_name); #endif - argv0); - exit(-1); - } - - fd[0] = atoi(argv[1]); - fd[1] = atoi(argv[2]); - - if (!(dpy = XOpenDisplay(NULL))) { - fprintf(console, "%s: couldn't open display %s\n", - argv0, - XDisplayName(NULL)); - exit(-1); - } - signal (SIGPIPE, DeadPipe); - - { - int s = DefaultScreen(dpy); - dwidth = DisplayWidth(dpy, s); - dheight = DisplayHeight(dpy, s); - } - - fd_width = GetFdWidth(); - + exit(1); + } + + state->pipe_fd[0] = atoi(argv[1]); + state->pipe_fd[1] = atoi(argv[2]); + + state->display = XOpenDisplay(NULL); + if (!state->display) { + fprintf(state->log, "%s: couldn't open display %s\n", + state->program_name, XDisplayName(NULL)); + exit(1); + } + + signal(SIGPIPE, handle_sigpipe); + + { + int screen = DefaultScreen(state->display); + state->screen_width = DisplayWidth(state->display, screen); + state->screen_height = DisplayHeight(state->display, screen); + } + + state->fd_width = GetFdWidth(); + #ifdef USERC - strcpy(match, "*"); - strcat(match, argv0); - len = strlen(match); + strlcpy(match, "*", sizeof(match)); + strlcat(match, state->program_name, sizeof(match)); + #ifdef FVWM1 - if ((config_line = GetConfigLine(argv[3], match))) { - char **args = NULL; - config_line_count = parse_line(config_line, &args); - parse_args("config args", - config_line_count, args, 0); - free(config_line); - free(args); - } + config_line = LoadConfigLine(argv[3], match); + if (config_line) { + char **args = NULL; + int arg_count = tokenise_config(config_line, &args); + + parse_arguments(state, "config args", arg_count, args, 0); + free(args); + free(config_line); + } #else - GetConfigLine(fd, &config_line); - while (config_line != NULL) { - if (strncmp(match,config_line,len)==0) { - char **args = NULL; - int cllen = strlen(config_line); - if (config_line[cllen - 1] == '\n') - config_line[cllen - 1] = 0; - config_line_count = parse_line(config_line, &args); - parse_args("config args", - config_line_count, args, 0); - free(args); - } - GetConfigLine(fd, &config_line); - } + GetConfigLine(state->pipe_fd, &config_line); + while (config_line) { + if (strncmp(match, config_line, strlen(match)) == 0) { + char **args = NULL; + int len = strlen(config_line); + if (len && config_line[len - 1] == '\n') { + config_line[len - 1] = '\0'; + } + { + int arg_count = + tokenise_config(config_line, &args); + parse_arguments( + state, "config args", arg_count, args, 0); + free(args); + } + } + GetConfigLine(state->pipe_fd, &config_line); + } #endif /* FVWM1 */ #endif /* USERC */ - if (strcmp(argv0, "FvwmCascade") && (!strcmp(argv0, "FvwmTile") || - (argc >= 7 && !strcmp(argv[6], "-tile")))) - { - FvwmTile = 1; - FvwmCascade = 0; - resize = 1; - } - else - { - FvwmCascade = 1; - FvwmTile = 0; - resize = 0; - } - parse_args("module args", argc, argv, 6); + if (strcmp(state->program_name, "FvwmCascade") && + (!strcmp(state->program_name, "FvwmTile") || + (argc >= 7 && !strcmp(argv[6], "-tile")))) { + state->run_tile = 1; + state->run_cascade = 0; + state->resize_clients = 1; + } else { + state->run_cascade = 1; + state->run_tile = 0; + state->resize_clients = 0; + } + + parse_arguments(state, "module args", argc, argv, 6); #ifdef FVWM1 - { - char msg[256]; - sprintf(msg, "SET_MASK %lu\n",(unsigned long)( - M_CONFIGURE_WINDOW| - M_END_WINDOWLIST - )); - SendInfo(fd,msg,0); - + { + char msg[256]; + snprintf(msg, sizeof(msg), "SET_MASK %lu\n", + (unsigned long)(M_CONFIGURE_WINDOW | M_DESTROY_WINDOW | + M_END_WINDOWLIST)); + SendInfo(state->pipe_fd, msg, 0); + #ifdef FVWM1_MOVENULL - /* avoid interactive placement in fvwm version 1 */ - if (!ofsx) ++ofsx; - if (!ofsy) ++ofsy; + if (!state->offset_x) { + ++state->offset_x; + } + if (!state->offset_y) { + ++state->offset_y; + } #endif - } + } #else - SetMessageMask(fd, - M_CONFIGURE_WINDOW - | M_END_WINDOWLIST - ); + SetMessageMask(state->pipe_fd, + M_CONFIGURE_WINDOW | M_DESTROY_WINDOW | M_END_WINDOWLIST); #endif - if (FvwmTile) - { - if (!maxx) maxx = dwidth; - if (!maxy) maxy = dheight; - } - - SendInfo(fd,"Send_WindowList",0); - while (get_window()); - if (wins_count) - { - if (FvwmCascade) - cascade_windows(); - else /* FvwmTile */ - tile_windows(); - } - free_window_list(&wins); - if (console != stderr) - fclose(console); - return 0; + if (state->run_tile) { + if (!state->bound_x) { + state->bound_x = state->screen_width; + } + if (!state->bound_y) { + state->bound_y = state->screen_height; + } + } + + SendInfo(state->pipe_fd, "Send_WindowList", 0); + + sandbox_x11_config("FvwmRearrange"); + + while (collect_client(state)) { + /* keep reading until the end marker arrives */ + } + + if (state->client_count) { + if (state->run_cascade) { + cascade_clients(state); + } else { + tile_clients(state); + } + } + + release_clients(state); + + if (state->log != stderr) { + fclose(state->log); + } + + return 0; +} + +void +DeadPipe(int sig) +{ + (void)sig; + exit(0); }