Alopex

Changes On Branch master

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch master Excluding Merge-Ins

This is equivalent to a diff from 45f6523171 to 2e35545abe

2014-06-22
22:12
Merge pull request #51 from pfernie/mod_mask_support Support ModX Bind.Mod values besides just Mod4 Leaf check-in: 2e35545abe user: jesse@mccluresk9.com tags: trunk, master
22:08
Merge pull request #50 from pfernie/focus_up Initialize Client *b to NULL check-in: e3c8a65315 user: jesse@mccluresk9.com tags: trunk, master
20:24
Support ModX Bind.Mod values besides just Mod4 Allow user to specify Mod1, Mod2, etc. as Bind.Mod values check-in: 42fdaaf0e5 user: patrick.fernie@gmail.com tags: trunk, master
2013-11-29
03:24
ver 3 coming soon Leaf check-in: 888df91866 user: mcclure_jesse@msn.com tags: trunk, origin/version2
03:15
ver 3 coming soon check-in: 1358d57fac user: mcclure_jesse@msn.com tags: trunk, master
2013-11-22
21:18
added ignore_root_resize check-in: 45f6523171 user: jesse@mccluresk9.com tags: trunk, origin/version2
2013-10-03
17:46
added internationalization to property change notify to handle firefox check-in: 4547f9c17c user: jesse@mccluresk9.com tags: trunk, origin/version2

Deleted COPYING.

     1         -                    GNU GENERAL PUBLIC LICENSE
     2         -                       Version 3, 29 June 2007
     3         -
     4         - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
     5         - Everyone is permitted to copy and distribute verbatim copies
     6         - of this license document, but changing it is not allowed.
     7         -
     8         -                            Preamble
     9         -
    10         -  The GNU General Public License is a free, copyleft license for
    11         -software and other kinds of works.
    12         -
    13         -  The licenses for most software and other practical works are designed
    14         -to take away your freedom to share and change the works.  By contrast,
    15         -the GNU General Public License is intended to guarantee your freedom to
    16         -share and change all versions of a program--to make sure it remains free
    17         -software for all its users.  We, the Free Software Foundation, use the
    18         -GNU General Public License for most of our software; it applies also to
    19         -any other work released this way by its authors.  You can apply it to
    20         -your programs, too.
    21         -
    22         -  When we speak of free software, we are referring to freedom, not
    23         -price.  Our General Public Licenses are designed to make sure that you
    24         -have the freedom to distribute copies of free software (and charge for
    25         -them if you wish), that you receive source code or can get it if you
    26         -want it, that you can change the software or use pieces of it in new
    27         -free programs, and that you know you can do these things.
    28         -
    29         -  To protect your rights, we need to prevent others from denying you
    30         -these rights or asking you to surrender the rights.  Therefore, you have
    31         -certain responsibilities if you distribute copies of the software, or if
    32         -you modify it: responsibilities to respect the freedom of others.
    33         -
    34         -  For example, if you distribute copies of such a program, whether
    35         -gratis or for a fee, you must pass on to the recipients the same
    36         -freedoms that you received.  You must make sure that they, too, receive
    37         -or can get the source code.  And you must show them these terms so they
    38         -know their rights.
    39         -
    40         -  Developers that use the GNU GPL protect your rights with two steps:
    41         -(1) assert copyright on the software, and (2) offer you this License
    42         -giving you legal permission to copy, distribute and/or modify it.
    43         -
    44         -  For the developers' and authors' protection, the GPL clearly explains
    45         -that there is no warranty for this free software.  For both users' and
    46         -authors' sake, the GPL requires that modified versions be marked as
    47         -changed, so that their problems will not be attributed erroneously to
    48         -authors of previous versions.
    49         -
    50         -  Some devices are designed to deny users access to install or run
    51         -modified versions of the software inside them, although the manufacturer
    52         -can do so.  This is fundamentally incompatible with the aim of
    53         -protecting users' freedom to change the software.  The systematic
    54         -pattern of such abuse occurs in the area of products for individuals to
    55         -use, which is precisely where it is most unacceptable.  Therefore, we
    56         -have designed this version of the GPL to prohibit the practice for those
    57         -products.  If such problems arise substantially in other domains, we
    58         -stand ready to extend this provision to those domains in future versions
    59         -of the GPL, as needed to protect the freedom of users.
    60         -
    61         -  Finally, every program is threatened constantly by software patents.
    62         -States should not allow patents to restrict development and use of
    63         -software on general-purpose computers, but in those that do, we wish to
    64         -avoid the special danger that patents applied to a free program could
    65         -make it effectively proprietary.  To prevent this, the GPL assures that
    66         -patents cannot be used to render the program non-free.
    67         -
    68         -  The precise terms and conditions for copying, distribution and
    69         -modification follow.
    70         -
    71         -                       TERMS AND CONDITIONS
    72         -
    73         -  0. Definitions.
    74         -
    75         -  "This License" refers to version 3 of the GNU General Public License.
    76         -
    77         -  "Copyright" also means copyright-like laws that apply to other kinds of
    78         -works, such as semiconductor masks.
    79         -
    80         -  "The Program" refers to any copyrightable work licensed under this
    81         -License.  Each licensee is addressed as "you".  "Licensees" and
    82         -"recipients" may be individuals or organizations.
    83         -
    84         -  To "modify" a work means to copy from or adapt all or part of the work
    85         -in a fashion requiring copyright permission, other than the making of an
    86         -exact copy.  The resulting work is called a "modified version" of the
    87         -earlier work or a work "based on" the earlier work.
    88         -
    89         -  A "covered work" means either the unmodified Program or a work based
    90         -on the Program.
    91         -
    92         -  To "propagate" a work means to do anything with it that, without
    93         -permission, would make you directly or secondarily liable for
    94         -infringement under applicable copyright law, except executing it on a
    95         -computer or modifying a private copy.  Propagation includes copying,
    96         -distribution (with or without modification), making available to the
    97         -public, and in some countries other activities as well.
    98         -
    99         -  To "convey" a work means any kind of propagation that enables other
   100         -parties to make or receive copies.  Mere interaction with a user through
   101         -a computer network, with no transfer of a copy, is not conveying.
   102         -
   103         -  An interactive user interface displays "Appropriate Legal Notices"
   104         -to the extent that it includes a convenient and prominently visible
   105         -feature that (1) displays an appropriate copyright notice, and (2)
   106         -tells the user that there is no warranty for the work (except to the
   107         -extent that warranties are provided), that licensees may convey the
   108         -work under this License, and how to view a copy of this License.  If
   109         -the interface presents a list of user commands or options, such as a
   110         -menu, a prominent item in the list meets this criterion.
   111         -
   112         -  1. Source Code.
   113         -
   114         -  The "source code" for a work means the preferred form of the work
   115         -for making modifications to it.  "Object code" means any non-source
   116         -form of a work.
   117         -
   118         -  A "Standard Interface" means an interface that either is an official
   119         -standard defined by a recognized standards body, or, in the case of
   120         -interfaces specified for a particular programming language, one that
   121         -is widely used among developers working in that language.
   122         -
   123         -  The "System Libraries" of an executable work include anything, other
   124         -than the work as a whole, that (a) is included in the normal form of
   125         -packaging a Major Component, but which is not part of that Major
   126         -Component, and (b) serves only to enable use of the work with that
   127         -Major Component, or to implement a Standard Interface for which an
   128         -implementation is available to the public in source code form.  A
   129         -"Major Component", in this context, means a major essential component
   130         -(kernel, window system, and so on) of the specific operating system
   131         -(if any) on which the executable work runs, or a compiler used to
   132         -produce the work, or an object code interpreter used to run it.
   133         -
   134         -  The "Corresponding Source" for a work in object code form means all
   135         -the source code needed to generate, install, and (for an executable
   136         -work) run the object code and to modify the work, including scripts to
   137         -control those activities.  However, it does not include the work's
   138         -System Libraries, or general-purpose tools or generally available free
   139         -programs which are used unmodified in performing those activities but
   140         -which are not part of the work.  For example, Corresponding Source
   141         -includes interface definition files associated with source files for
   142         -the work, and the source code for shared libraries and dynamically
   143         -linked subprograms that the work is specifically designed to require,
   144         -such as by intimate data communication or control flow between those
   145         -subprograms and other parts of the work.
   146         -
   147         -  The Corresponding Source need not include anything that users
   148         -can regenerate automatically from other parts of the Corresponding
   149         -Source.
   150         -
   151         -  The Corresponding Source for a work in source code form is that
   152         -same work.
   153         -
   154         -  2. Basic Permissions.
   155         -
   156         -  All rights granted under this License are granted for the term of
   157         -copyright on the Program, and are irrevocable provided the stated
   158         -conditions are met.  This License explicitly affirms your unlimited
   159         -permission to run the unmodified Program.  The output from running a
   160         -covered work is covered by this License only if the output, given its
   161         -content, constitutes a covered work.  This License acknowledges your
   162         -rights of fair use or other equivalent, as provided by copyright law.
   163         -
   164         -  You may make, run and propagate covered works that you do not
   165         -convey, without conditions so long as your license otherwise remains
   166         -in force.  You may convey covered works to others for the sole purpose
   167         -of having them make modifications exclusively for you, or provide you
   168         -with facilities for running those works, provided that you comply with
   169         -the terms of this License in conveying all material for which you do
   170         -not control copyright.  Those thus making or running the covered works
   171         -for you must do so exclusively on your behalf, under your direction
   172         -and control, on terms that prohibit them from making any copies of
   173         -your copyrighted material outside their relationship with you.
   174         -
   175         -  Conveying under any other circumstances is permitted solely under
   176         -the conditions stated below.  Sublicensing is not allowed; section 10
   177         -makes it unnecessary.
   178         -
   179         -  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
   180         -
   181         -  No covered work shall be deemed part of an effective technological
   182         -measure under any applicable law fulfilling obligations under article
   183         -11 of the WIPO copyright treaty adopted on 20 December 1996, or
   184         -similar laws prohibiting or restricting circumvention of such
   185         -measures.
   186         -
   187         -  When you convey a covered work, you waive any legal power to forbid
   188         -circumvention of technological measures to the extent such circumvention
   189         -is effected by exercising rights under this License with respect to
   190         -the covered work, and you disclaim any intention to limit operation or
   191         -modification of the work as a means of enforcing, against the work's
   192         -users, your or third parties' legal rights to forbid circumvention of
   193         -technological measures.
   194         -
   195         -  4. Conveying Verbatim Copies.
   196         -
   197         -  You may convey verbatim copies of the Program's source code as you
   198         -receive it, in any medium, provided that you conspicuously and
   199         -appropriately publish on each copy an appropriate copyright notice;
   200         -keep intact all notices stating that this License and any
   201         -non-permissive terms added in accord with section 7 apply to the code;
   202         -keep intact all notices of the absence of any warranty; and give all
   203         -recipients a copy of this License along with the Program.
   204         -
   205         -  You may charge any price or no price for each copy that you convey,
   206         -and you may offer support or warranty protection for a fee.
   207         -
   208         -  5. Conveying Modified Source Versions.
   209         -
   210         -  You may convey a work based on the Program, or the modifications to
   211         -produce it from the Program, in the form of source code under the
   212         -terms of section 4, provided that you also meet all of these conditions:
   213         -
   214         -    a) The work must carry prominent notices stating that you modified
   215         -    it, and giving a relevant date.
   216         -
   217         -    b) The work must carry prominent notices stating that it is
   218         -    released under this License and any conditions added under section
   219         -    7.  This requirement modifies the requirement in section 4 to
   220         -    "keep intact all notices".
   221         -
   222         -    c) You must license the entire work, as a whole, under this
   223         -    License to anyone who comes into possession of a copy.  This
   224         -    License will therefore apply, along with any applicable section 7
   225         -    additional terms, to the whole of the work, and all its parts,
   226         -    regardless of how they are packaged.  This License gives no
   227         -    permission to license the work in any other way, but it does not
   228         -    invalidate such permission if you have separately received it.
   229         -
   230         -    d) If the work has interactive user interfaces, each must display
   231         -    Appropriate Legal Notices; however, if the Program has interactive
   232         -    interfaces that do not display Appropriate Legal Notices, your
   233         -    work need not make them do so.
   234         -
   235         -  A compilation of a covered work with other separate and independent
   236         -works, which are not by their nature extensions of the covered work,
   237         -and which are not combined with it such as to form a larger program,
   238         -in or on a volume of a storage or distribution medium, is called an
   239         -"aggregate" if the compilation and its resulting copyright are not
   240         -used to limit the access or legal rights of the compilation's users
   241         -beyond what the individual works permit.  Inclusion of a covered work
   242         -in an aggregate does not cause this License to apply to the other
   243         -parts of the aggregate.
   244         -
   245         -  6. Conveying Non-Source Forms.
   246         -
   247         -  You may convey a covered work in object code form under the terms
   248         -of sections 4 and 5, provided that you also convey the
   249         -machine-readable Corresponding Source under the terms of this License,
   250         -in one of these ways:
   251         -
   252         -    a) Convey the object code in, or embodied in, a physical product
   253         -    (including a physical distribution medium), accompanied by the
   254         -    Corresponding Source fixed on a durable physical medium
   255         -    customarily used for software interchange.
   256         -
   257         -    b) Convey the object code in, or embodied in, a physical product
   258         -    (including a physical distribution medium), accompanied by a
   259         -    written offer, valid for at least three years and valid for as
   260         -    long as you offer spare parts or customer support for that product
   261         -    model, to give anyone who possesses the object code either (1) a
   262         -    copy of the Corresponding Source for all the software in the
   263         -    product that is covered by this License, on a durable physical
   264         -    medium customarily used for software interchange, for a price no
   265         -    more than your reasonable cost of physically performing this
   266         -    conveying of source, or (2) access to copy the
   267         -    Corresponding Source from a network server at no charge.
   268         -
   269         -    c) Convey individual copies of the object code with a copy of the
   270         -    written offer to provide the Corresponding Source.  This
   271         -    alternative is allowed only occasionally and noncommercially, and
   272         -    only if you received the object code with such an offer, in accord
   273         -    with subsection 6b.
   274         -
   275         -    d) Convey the object code by offering access from a designated
   276         -    place (gratis or for a charge), and offer equivalent access to the
   277         -    Corresponding Source in the same way through the same place at no
   278         -    further charge.  You need not require recipients to copy the
   279         -    Corresponding Source along with the object code.  If the place to
   280         -    copy the object code is a network server, the Corresponding Source
   281         -    may be on a different server (operated by you or a third party)
   282         -    that supports equivalent copying facilities, provided you maintain
   283         -    clear directions next to the object code saying where to find the
   284         -    Corresponding Source.  Regardless of what server hosts the
   285         -    Corresponding Source, you remain obligated to ensure that it is
   286         -    available for as long as needed to satisfy these requirements.
   287         -
   288         -    e) Convey the object code using peer-to-peer transmission, provided
   289         -    you inform other peers where the object code and Corresponding
   290         -    Source of the work are being offered to the general public at no
   291         -    charge under subsection 6d.
   292         -
   293         -  A separable portion of the object code, whose source code is excluded
   294         -from the Corresponding Source as a System Library, need not be
   295         -included in conveying the object code work.
   296         -
   297         -  A "User Product" is either (1) a "consumer product", which means any
   298         -tangible personal property which is normally used for personal, family,
   299         -or household purposes, or (2) anything designed or sold for incorporation
   300         -into a dwelling.  In determining whether a product is a consumer product,
   301         -doubtful cases shall be resolved in favor of coverage.  For a particular
   302         -product received by a particular user, "normally used" refers to a
   303         -typical or common use of that class of product, regardless of the status
   304         -of the particular user or of the way in which the particular user
   305         -actually uses, or expects or is expected to use, the product.  A product
   306         -is a consumer product regardless of whether the product has substantial
   307         -commercial, industrial or non-consumer uses, unless such uses represent
   308         -the only significant mode of use of the product.
   309         -
   310         -  "Installation Information" for a User Product means any methods,
   311         -procedures, authorization keys, or other information required to install
   312         -and execute modified versions of a covered work in that User Product from
   313         -a modified version of its Corresponding Source.  The information must
   314         -suffice to ensure that the continued functioning of the modified object
   315         -code is in no case prevented or interfered with solely because
   316         -modification has been made.
   317         -
   318         -  If you convey an object code work under this section in, or with, or
   319         -specifically for use in, a User Product, and the conveying occurs as
   320         -part of a transaction in which the right of possession and use of the
   321         -User Product is transferred to the recipient in perpetuity or for a
   322         -fixed term (regardless of how the transaction is characterized), the
   323         -Corresponding Source conveyed under this section must be accompanied
   324         -by the Installation Information.  But this requirement does not apply
   325         -if neither you nor any third party retains the ability to install
   326         -modified object code on the User Product (for example, the work has
   327         -been installed in ROM).
   328         -
   329         -  The requirement to provide Installation Information does not include a
   330         -requirement to continue to provide support service, warranty, or updates
   331         -for a work that has been modified or installed by the recipient, or for
   332         -the User Product in which it has been modified or installed.  Access to a
   333         -network may be denied when the modification itself materially and
   334         -adversely affects the operation of the network or violates the rules and
   335         -protocols for communication across the network.
   336         -
   337         -  Corresponding Source conveyed, and Installation Information provided,
   338         -in accord with this section must be in a format that is publicly
   339         -documented (and with an implementation available to the public in
   340         -source code form), and must require no special password or key for
   341         -unpacking, reading or copying.
   342         -
   343         -  7. Additional Terms.
   344         -
   345         -  "Additional permissions" are terms that supplement the terms of this
   346         -License by making exceptions from one or more of its conditions.
   347         -Additional permissions that are applicable to the entire Program shall
   348         -be treated as though they were included in this License, to the extent
   349         -that they are valid under applicable law.  If additional permissions
   350         -apply only to part of the Program, that part may be used separately
   351         -under those permissions, but the entire Program remains governed by
   352         -this License without regard to the additional permissions.
   353         -
   354         -  When you convey a copy of a covered work, you may at your option
   355         -remove any additional permissions from that copy, or from any part of
   356         -it.  (Additional permissions may be written to require their own
   357         -removal in certain cases when you modify the work.)  You may place
   358         -additional permissions on material, added by you to a covered work,
   359         -for which you have or can give appropriate copyright permission.
   360         -
   361         -  Notwithstanding any other provision of this License, for material you
   362         -add to a covered work, you may (if authorized by the copyright holders of
   363         -that material) supplement the terms of this License with terms:
   364         -
   365         -    a) Disclaiming warranty or limiting liability differently from the
   366         -    terms of sections 15 and 16 of this License; or
   367         -
   368         -    b) Requiring preservation of specified reasonable legal notices or
   369         -    author attributions in that material or in the Appropriate Legal
   370         -    Notices displayed by works containing it; or
   371         -
   372         -    c) Prohibiting misrepresentation of the origin of that material, or
   373         -    requiring that modified versions of such material be marked in
   374         -    reasonable ways as different from the original version; or
   375         -
   376         -    d) Limiting the use for publicity purposes of names of licensors or
   377         -    authors of the material; or
   378         -
   379         -    e) Declining to grant rights under trademark law for use of some
   380         -    trade names, trademarks, or service marks; or
   381         -
   382         -    f) Requiring indemnification of licensors and authors of that
   383         -    material by anyone who conveys the material (or modified versions of
   384         -    it) with contractual assumptions of liability to the recipient, for
   385         -    any liability that these contractual assumptions directly impose on
   386         -    those licensors and authors.
   387         -
   388         -  All other non-permissive additional terms are considered "further
   389         -restrictions" within the meaning of section 10.  If the Program as you
   390         -received it, or any part of it, contains a notice stating that it is
   391         -governed by this License along with a term that is a further
   392         -restriction, you may remove that term.  If a license document contains
   393         -a further restriction but permits relicensing or conveying under this
   394         -License, you may add to a covered work material governed by the terms
   395         -of that license document, provided that the further restriction does
   396         -not survive such relicensing or conveying.
   397         -
   398         -  If you add terms to a covered work in accord with this section, you
   399         -must place, in the relevant source files, a statement of the
   400         -additional terms that apply to those files, or a notice indicating
   401         -where to find the applicable terms.
   402         -
   403         -  Additional terms, permissive or non-permissive, may be stated in the
   404         -form of a separately written license, or stated as exceptions;
   405         -the above requirements apply either way.
   406         -
   407         -  8. Termination.
   408         -
   409         -  You may not propagate or modify a covered work except as expressly
   410         -provided under this License.  Any attempt otherwise to propagate or
   411         -modify it is void, and will automatically terminate your rights under
   412         -this License (including any patent licenses granted under the third
   413         -paragraph of section 11).
   414         -
   415         -  However, if you cease all violation of this License, then your
   416         -license from a particular copyright holder is reinstated (a)
   417         -provisionally, unless and until the copyright holder explicitly and
   418         -finally terminates your license, and (b) permanently, if the copyright
   419         -holder fails to notify you of the violation by some reasonable means
   420         -prior to 60 days after the cessation.
   421         -
   422         -  Moreover, your license from a particular copyright holder is
   423         -reinstated permanently if the copyright holder notifies you of the
   424         -violation by some reasonable means, this is the first time you have
   425         -received notice of violation of this License (for any work) from that
   426         -copyright holder, and you cure the violation prior to 30 days after
   427         -your receipt of the notice.
   428         -
   429         -  Termination of your rights under this section does not terminate the
   430         -licenses of parties who have received copies or rights from you under
   431         -this License.  If your rights have been terminated and not permanently
   432         -reinstated, you do not qualify to receive new licenses for the same
   433         -material under section 10.
   434         -
   435         -  9. Acceptance Not Required for Having Copies.
   436         -
   437         -  You are not required to accept this License in order to receive or
   438         -run a copy of the Program.  Ancillary propagation of a covered work
   439         -occurring solely as a consequence of using peer-to-peer transmission
   440         -to receive a copy likewise does not require acceptance.  However,
   441         -nothing other than this License grants you permission to propagate or
   442         -modify any covered work.  These actions infringe copyright if you do
   443         -not accept this License.  Therefore, by modifying or propagating a
   444         -covered work, you indicate your acceptance of this License to do so.
   445         -
   446         -  10. Automatic Licensing of Downstream Recipients.
   447         -
   448         -  Each time you convey a covered work, the recipient automatically
   449         -receives a license from the original licensors, to run, modify and
   450         -propagate that work, subject to this License.  You are not responsible
   451         -for enforcing compliance by third parties with this License.
   452         -
   453         -  An "entity transaction" is a transaction transferring control of an
   454         -organization, or substantially all assets of one, or subdividing an
   455         -organization, or merging organizations.  If propagation of a covered
   456         -work results from an entity transaction, each party to that
   457         -transaction who receives a copy of the work also receives whatever
   458         -licenses to the work the party's predecessor in interest had or could
   459         -give under the previous paragraph, plus a right to possession of the
   460         -Corresponding Source of the work from the predecessor in interest, if
   461         -the predecessor has it or can get it with reasonable efforts.
   462         -
   463         -  You may not impose any further restrictions on the exercise of the
   464         -rights granted or affirmed under this License.  For example, you may
   465         -not impose a license fee, royalty, or other charge for exercise of
   466         -rights granted under this License, and you may not initiate litigation
   467         -(including a cross-claim or counterclaim in a lawsuit) alleging that
   468         -any patent claim is infringed by making, using, selling, offering for
   469         -sale, or importing the Program or any portion of it.
   470         -
   471         -  11. Patents.
   472         -
   473         -  A "contributor" is a copyright holder who authorizes use under this
   474         -License of the Program or a work on which the Program is based.  The
   475         -work thus licensed is called the contributor's "contributor version".
   476         -
   477         -  A contributor's "essential patent claims" are all patent claims
   478         -owned or controlled by the contributor, whether already acquired or
   479         -hereafter acquired, that would be infringed by some manner, permitted
   480         -by this License, of making, using, or selling its contributor version,
   481         -but do not include claims that would be infringed only as a
   482         -consequence of further modification of the contributor version.  For
   483         -purposes of this definition, "control" includes the right to grant
   484         -patent sublicenses in a manner consistent with the requirements of
   485         -this License.
   486         -
   487         -  Each contributor grants you a non-exclusive, worldwide, royalty-free
   488         -patent license under the contributor's essential patent claims, to
   489         -make, use, sell, offer for sale, import and otherwise run, modify and
   490         -propagate the contents of its contributor version.
   491         -
   492         -  In the following three paragraphs, a "patent license" is any express
   493         -agreement or commitment, however denominated, not to enforce a patent
   494         -(such as an express permission to practice a patent or covenant not to
   495         -sue for patent infringement).  To "grant" such a patent license to a
   496         -party means to make such an agreement or commitment not to enforce a
   497         -patent against the party.
   498         -
   499         -  If you convey a covered work, knowingly relying on a patent license,
   500         -and the Corresponding Source of the work is not available for anyone
   501         -to copy, free of charge and under the terms of this License, through a
   502         -publicly available network server or other readily accessible means,
   503         -then you must either (1) cause the Corresponding Source to be so
   504         -available, or (2) arrange to deprive yourself of the benefit of the
   505         -patent license for this particular work, or (3) arrange, in a manner
   506         -consistent with the requirements of this License, to extend the patent
   507         -license to downstream recipients.  "Knowingly relying" means you have
   508         -actual knowledge that, but for the patent license, your conveying the
   509         -covered work in a country, or your recipient's use of the covered work
   510         -in a country, would infringe one or more identifiable patents in that
   511         -country that you have reason to believe are valid.
   512         -
   513         -  If, pursuant to or in connection with a single transaction or
   514         -arrangement, you convey, or propagate by procuring conveyance of, a
   515         -covered work, and grant a patent license to some of the parties
   516         -receiving the covered work authorizing them to use, propagate, modify
   517         -or convey a specific copy of the covered work, then the patent license
   518         -you grant is automatically extended to all recipients of the covered
   519         -work and works based on it.
   520         -
   521         -  A patent license is "discriminatory" if it does not include within
   522         -the scope of its coverage, prohibits the exercise of, or is
   523         -conditioned on the non-exercise of one or more of the rights that are
   524         -specifically granted under this License.  You may not convey a covered
   525         -work if you are a party to an arrangement with a third party that is
   526         -in the business of distributing software, under which you make payment
   527         -to the third party based on the extent of your activity of conveying
   528         -the work, and under which the third party grants, to any of the
   529         -parties who would receive the covered work from you, a discriminatory
   530         -patent license (a) in connection with copies of the covered work
   531         -conveyed by you (or copies made from those copies), or (b) primarily
   532         -for and in connection with specific products or compilations that
   533         -contain the covered work, unless you entered into that arrangement,
   534         -or that patent license was granted, prior to 28 March 2007.
   535         -
   536         -  Nothing in this License shall be construed as excluding or limiting
   537         -any implied license or other defenses to infringement that may
   538         -otherwise be available to you under applicable patent law.
   539         -
   540         -  12. No Surrender of Others' Freedom.
   541         -
   542         -  If conditions are imposed on you (whether by court order, agreement or
   543         -otherwise) that contradict the conditions of this License, they do not
   544         -excuse you from the conditions of this License.  If you cannot convey a
   545         -covered work so as to satisfy simultaneously your obligations under this
   546         -License and any other pertinent obligations, then as a consequence you may
   547         -not convey it at all.  For example, if you agree to terms that obligate you
   548         -to collect a royalty for further conveying from those to whom you convey
   549         -the Program, the only way you could satisfy both those terms and this
   550         -License would be to refrain entirely from conveying the Program.
   551         -
   552         -  13. Use with the GNU Affero General Public License.
   553         -
   554         -  Notwithstanding any other provision of this License, you have
   555         -permission to link or combine any covered work with a work licensed
   556         -under version 3 of the GNU Affero General Public License into a single
   557         -combined work, and to convey the resulting work.  The terms of this
   558         -License will continue to apply to the part which is the covered work,
   559         -but the special requirements of the GNU Affero General Public License,
   560         -section 13, concerning interaction through a network will apply to the
   561         -combination as such.
   562         -
   563         -  14. Revised Versions of this License.
   564         -
   565         -  The Free Software Foundation may publish revised and/or new versions of
   566         -the GNU General Public License from time to time.  Such new versions will
   567         -be similar in spirit to the present version, but may differ in detail to
   568         -address new problems or concerns.
   569         -
   570         -  Each version is given a distinguishing version number.  If the
   571         -Program specifies that a certain numbered version of the GNU General
   572         -Public License "or any later version" applies to it, you have the
   573         -option of following the terms and conditions either of that numbered
   574         -version or of any later version published by the Free Software
   575         -Foundation.  If the Program does not specify a version number of the
   576         -GNU General Public License, you may choose any version ever published
   577         -by the Free Software Foundation.
   578         -
   579         -  If the Program specifies that a proxy can decide which future
   580         -versions of the GNU General Public License can be used, that proxy's
   581         -public statement of acceptance of a version permanently authorizes you
   582         -to choose that version for the Program.
   583         -
   584         -  Later license versions may give you additional or different
   585         -permissions.  However, no additional obligations are imposed on any
   586         -author or copyright holder as a result of your choosing to follow a
   587         -later version.
   588         -
   589         -  15. Disclaimer of Warranty.
   590         -
   591         -  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
   592         -APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
   593         -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
   594         -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
   595         -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   596         -PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
   597         -IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
   598         -ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
   599         -
   600         -  16. Limitation of Liability.
   601         -
   602         -  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
   603         -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
   604         -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
   605         -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
   606         -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
   607         -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
   608         -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
   609         -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
   610         -SUCH DAMAGES.
   611         -
   612         -  17. Interpretation of Sections 15 and 16.
   613         -
   614         -  If the disclaimer of warranty and limitation of liability provided
   615         -above cannot be given local legal effect according to their terms,
   616         -reviewing courts shall apply local law that most closely approximates
   617         -an absolute waiver of all civil liability in connection with the
   618         -Program, unless a warranty or assumption of liability accompanies a
   619         -copy of the Program in return for a fee.
   620         -
   621         -                     END OF TERMS AND CONDITIONS
   622         -
   623         -            How to Apply These Terms to Your New Programs
   624         -
   625         -  If you develop a new program, and you want it to be of the greatest
   626         -possible use to the public, the best way to achieve this is to make it
   627         -free software which everyone can redistribute and change under these terms.
   628         -
   629         -  To do so, attach the following notices to the program.  It is safest
   630         -to attach them to the start of each source file to most effectively
   631         -state the exclusion of warranty; and each file should have at least
   632         -the "copyright" line and a pointer to where the full notice is found.
   633         -
   634         -    <one line to give the program's name and a brief idea of what it does.>
   635         -    Copyright (C) <year>  <name of author>
   636         -
   637         -    This program is free software: you can redistribute it and/or modify
   638         -    it under the terms of the GNU General Public License as published by
   639         -    the Free Software Foundation, either version 3 of the License, or
   640         -    (at your option) any later version.
   641         -
   642         -    This program is distributed in the hope that it will be useful,
   643         -    but WITHOUT ANY WARRANTY; without even the implied warranty of
   644         -    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   645         -    GNU General Public License for more details.
   646         -
   647         -    You should have received a copy of the GNU General Public License
   648         -    along with this program.  If not, see <http://www.gnu.org/licenses/>.
   649         -
   650         -Also add information on how to contact you by electronic and paper mail.
   651         -
   652         -  If the program does terminal interaction, make it output a short
   653         -notice like this when it starts in an interactive mode:
   654         -
   655         -    <program>  Copyright (C) <year>  <name of author>
   656         -    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
   657         -    This is free software, and you are welcome to redistribute it
   658         -    under certain conditions; type `show c' for details.
   659         -
   660         -The hypothetical commands `show w' and `show c' should show the appropriate
   661         -parts of the General Public License.  Of course, your program's commands
   662         -might be different; for a GUI interface, you would use an "about box".
   663         -
   664         -  You should also get your employer (if you work as a programmer) or school,
   665         -if any, to sign a "copyright disclaimer" for the program, if necessary.
   666         -For more information on this, and how to apply and follow the GNU GPL, see
   667         -<http://www.gnu.org/licenses/>.
   668         -
   669         -  The GNU General Public License does not permit incorporating your program
   670         -into proprietary programs.  If your program is a subroutine library, you
   671         -may consider it more useful to permit linking proprietary applications with
   672         -the library.  If this is what you want to do, use the GNU Lesser General
   673         -Public License instead of this License.  But first, please read
   674         -<http://www.gnu.org/philosophy/why-not-lgpl.html>.

Changes to Makefile.

     1         -PROG	=	alopex
     2         -LIBS	=	-lX11 -lXrandr
     3         -PREFIX	?=	/usr
     4         -MANDIR	?=	/usr/share/man
     5         -VER		=	2.0
     6         -HEADERS	=	config.h icons.h theme.h
     7         -MOLT	?=	WinterCoat
            1  +
            2  +PROG     =  alopex
            3  +VER      =  4.0a
            4  +CC       ?= gcc
            5  +CFLAGS   += $(shell pkg-config --cflags x11 cairo freetype2 xinerama)
            6  +LDLIBS   += $(shell pkg-config --libs x11 cairo freetype2 xinerama)
            7  +PREFIX   ?= /usr
            8  +MODULES  =  actions alopex atoms config draw tile xlib
            9  +HEADERS  =  alopex.h actions.h
           10  +MANPAGES =  alopex.1
           11  +VPATH    =  src:doc
     8     12   
     9         -${PROG}: ${PROG}.c ${HEADERS}
    10         -	@${CC} -D${MOLT} ${CFLAGS} ${LIBS} -o ${PROG} ${PROG}.c
    11         -	@strip ${PROG}
           13  +${PROG}: ${MODULES:%=%.o}
    12     14   
    13         -clean:
    14         -	@rm -f ${PROG}
    15         -
    16         -tarball: clean
    17         -	@rm -f ${PROG}-${VER}.tar.gz
    18         -	@tar -czf ${PROG}-${VER}.tar.gz *
           15  +%.o: %.c ${HEADERS}
    19     16   
    20     17   install: ${PROG}
    21     18   	@install -Dm755 ${PROG} ${DESTDIR}${PREFIX}/bin/${PROG}
    22         -	@install -Dm666 ${PROG}.1 ${DESTDIR}${MANDIR}/man1/${PROG}.1
    23         -	@install -Dm666 ${PROG}.config.5 ${DESTDIR}${MANDIR}/man5/${PROG}.config.5
    24         -	@install -Dm666 ${PROG}.icons.5 ${DESTDIR}${MANDIR}/man5/${PROG}.icons.5
           19  +	@mkdir -p ${DESTDIR}${PREFIX}/share/${PROG}
           20  +	@install -m644 -t ${DESTDIR}${PREFIX}/share/${PROG}/ share/*
           21  +	@install -Dm644 doc/alopex.1 ${DESTDIR}${PREFIX}/share/man/man1/alopex.1
           22  +
           23  +${MANPAGES}: alopex.%: alopex-%.tex
           24  +	@latex2man $< doc/$@
           25  +
           26  +man: ${MANPAGES}
           27  +
           28  +clean:
           29  +	@rm -f ${PROG}-${VER}.tar.gz
           30  +	@rm -f ${MODULES:%=%.o}
           31  +
           32  +distclean: clean
           33  +	@rm -f ${PROG}
           34  +
           35  +dist: distclean
           36  +	@tar -czf ${PROG}-${VER}.tar.gz *
    25     37   
    26         -
    27         -
           38  +.PHONY: clean dist distclean man

Changes to PKGBUILD.

     1      1   # Maintainer: Jesse McClure AKA "Trilby" <jmcclure [at] cns [dot] umass [dot] edu>
     2      2   _gitname="alopex"
     3      3   pkgname="${_gitname}-git"
     4         -pkgver=2.291.1763f16
            4  +pkgver=4.420.bbd6ee2
     5      5   pkgrel=1
     6         -pkgdesc="A Tiny, Tabbed, Tiling Window Manager with Fur"
            6  +pkgdesc="A Tabbed, Tiling Window Manager with Fur"
     7      7   url="http://trilbywhite.github.io/alopex/"
     8         -arch=('any')
     9         -license=('GPLv3')
    10         -depends=('libx11' 'libxrandr')
            8  +arch=('x86_64' 'i686')
            9  +license=('GPL3')
           10  +depends=('libxinerama' 'cairo')
    11     11   makedepends=('git')
    12     12   source=("${_gitname}::git://github.com/TrilbyWhite/alopex.git")
    13     13   sha256sums=('SKIP')
    14     14   
    15     15   pkgver() {
    16     16   	cd "${_gitname}";
    17         -	echo "2.$(git rev-list --count HEAD).$(git describe --always )"
    18         -}
    19         -
    20         -prepare() {
    21         -	_dir="$HOME/.config/alopex"
    22         -	[[ -n "$XDG_CONFIG_HOME" ]] && _dir="$XDG_CONFIG_HOME/alopex"
    23         -	if [[ -d "$_dir" ]]; then
    24         -		for _file in {config,icons,theme}.h; do
    25         -			if [[ -a "${_dir}/${_file}" ]]; then
    26         -				cp "${_dir}/${_file}" "${srcdir}/${_gitname}/${_file}"
    27         -				msg2 "Using ${_file%.h} from $_dir/$_file"
    28         -				msg2 "Check the default $_file for changes"
    29         -			fi
    30         -		done
    31         -	fi
           17  +	echo "4.$(git rev-list --count HEAD).$(git describe --always )"
    32     18   }
    33     19   
    34     20   build() {
    35     21   	cd "${_gitname}"
    36     22   	make
    37     23   }
    38     24   
    39     25   package() {
    40     26   	cd "${_gitname}"
    41     27   	make PREFIX=/usr DESTDIR="${pkgdir}" install
    42     28   }

Changes to README.md.

            1  +
     1      2   Alopex
     2      3   ======
     3      4   Don't be a lagopus!
     4      5   
     5         -[![alopex banner](https://raw.github.com/TrilbyWhite/alopex/gh-pages/res/alopex.jpg)](http://trilbywhite.github.com/alopex)
            6  +[![alopex banner](https://raw.github.com/TrilbyWhite/alopex/gh-pages/res/alopex.jpg)See the website here](http://trilbywhite.github.com/alopex)
            7  +
            8  +
            9  +
           10  +### 22 March 2014
     6     11   
           12  +- There may be issues with the cairo drawing functions used by alopex
           13  +  and some nvidia drivers.  Unfortunately I have no way of tracking down
           14  +  this issue.  If you have a nvidia card, either 1) use the FOSS
           15  +  drivers, 2) use another WM, and/or 3) help pinpoint if and where the
           16  +  issue lies between cairo and nvidia and report it to their devs.
     7     17   
     8         -
           18  +- There is a known bug with gtk3 windows not being drawn.  This is next
           19  +  on my chopping block and a fix can be expected soon.

Added TODO.

            1  +
            2  +reconfigure on monitor changes.

Deleted alopex.1.

     1         -'\" t
     2         -.\"     Title: alopex
     3         -.\"    Author: [Sam Stuewe]
     4         -.\"      Date: 2013-04-22
     5         -.\"    Manual: \ \&
     6         -.\"    Source: \ \& 2.0
     7         -.\"  Language: English
     8         -.\"
     9         -.TH "ALOPEX" "1" "2013-04-23" "\ \& 2\&.0" "\ \&"
    10         -.ie \n(.g .ds Aq \(aq
    11         -.el       .ds Aq '
    12         -.nh
    13         -.ad l
    14         -.\"
    15         -.\" <- Main Content ->
    16         -.SH "NAME"
    17         -Alopex \- A Tabbed Tiling Window Manager
    18         -.SH "SYNOPSIS"
    19         -.sp
    20         -xinit /usr/bin/\fBalopex\fR "/path/to/statusbar-script.sh"
    21         -.sp
    22         -.SH "DESCRIPTION"
    23         -Almost all configuration for \fBalopex\fR is done at compile-time\&. Customizations such as keybinds, statusbar icons, tag appearances and window rules can be achieved through three C header files\&: config\&.h, icons\&.h and theme\&.h\&.
    24         -.sp
    25         -The default headers will provide simple, sane defaults, but users should expect to customize the setup to their liking\&.
    26         -.sp
    27         -.SH "WINDOW LAYOUTS"
    28         -\fBAlopex\fR offers three window layouts\&: rstack, bstack and monocle\&. Both stack modes divide the screen into two sections, the master region and the stack\&. Monocle keeps the screen unified in one region\&. All layouts render a tab per-client to the right of the tags and the left of the statusbar\&.
    29         -.sp
    30         -.RS 4
    31         -.nf
    32         -\fIrstack\fR    \-\-  master on left, stack on right; clients stack vertically
    33         -\fIbstack\fR    \-\-  master on top, stack on bottom; clients stack horizontally
    34         -\fImonocle\fR   \-\-  master region fills the screen
    35         -.fi
    36         -.sp
    37         -.RE
    38         -These three layouts are further supplemented by transient, floating and fullscreen modes\&.
    39         -.sp
    40         -.SH "THEMES"
    41         -Themes for \fBalopex\fR are sets of standard \fI#RRGGBB\fR hex codes assigned to various parts of the interface\&. By default, two themes are provided called "WinterCoat" and "SummerCoat" with several others under construction\&. However, through creating a custom theme\&.h located at \fI$XDG_CONFIG_HOME/alopex/theme\&.h\fR or \fI$HOME/.alopex_theme.h\fR, creating custom themes is very simple\&.
    42         -.sp
    43         -.SH "STATUSBAR"
    44         -A single argument can be passed to \fBalopex\fR to render a statusbar\&. To avoid a CPU race, \fBalopex\fR creates a simple statusbar displaying a clock\&. However, by passing a script or program that can output text (such as conky), far more complex statusbars can be used easily\&.
    45         -.sp
    46         -In this text output, colors and icons can be specified through simple bracketed codes\&. Color codes, when passed, will color all text (and icons) following them until another color code is encountered\&. They are called in the following manner\&:
    47         -.sp
    48         -.RS 4
    49         -{#RRGGBB}
    50         -.sp
    51         -#RRGGBB is a standard hex color-code
    52         -.RE
    53         -.sp
    54         -In a similar manner, minimalist icons may be rendered on the statusbar\&. Icons are called in the following manner\&:
    55         -.sp
    56         -.RS 4
    57         -{i #}
    58         -.sp
    59         -# should be replaced by the number of the icon as designated by the array at the bottom of icons\&.h\&.
    60         -.sp
    61         -.RE
    62         -.SH "MULTIHEAD SETUP"
    63         -\fBAlopex\fR offers support for 16 external displays\&. Auto\-detection and setup of external displays is not supported, but is planned for a future release\&.
    64         -.sp
    65         -Along with being assigned to tags, each client is given an identifier which determines on what display the client will appear\&. Should the number applied to the client exceed the number of the highest display available, that client will appear on the highest numbered display available\&.
    66         -.sp
    67         -.RE
    68         -.SH "SEE ALSO"
    69         -\fBalopex\&.config\fR(5) \fBalopex\&.icons\fR(5)

Deleted alopex.c.

     1         -/**************************************************************************\
     2         -* ALOPEX - a tiny tabbed tagging tiling wm
     3         -*
     4         -* Author: Jesse McClure, copyright 2012-2013
     5         -* License: GPLv3
     6         -*
     7         -* Based on code from TinyWM by Nick Welch <mack@incise.org>, 2005,
     8         -* with coode influence from DWM by the Suckless team (suckless.org),
     9         -* and concepts inspired by i3 (i3wm.org).
    10         -*
    11         -*    This program is free software: you can redistribute it and/or modify
    12         -*    it under the terms of the GNU General Public License as published by
    13         -*    the Free Software Foundation, either version 3 of the License, or
    14         -*    (at your option) any later version.
    15         -*
    16         -*    This program is distributed in the hope that it will be useful,
    17         -*    but WITHOUT ANY WARRANTY; without even the implied warranty of
    18         -*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    19         -*    GNU General Public License for more details.
    20         -*
    21         -*    You should have received a copy of the GNU General Public License
    22         -*    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    23         -*
    24         -*
    25         -\**************************************************************************/
    26         -
    27         -
    28         -#include <stdlib.h>
    29         -#include <stdio.h>
    30         -#include <string.h>
    31         -#include <unistd.h>
    32         -#include <locale.h>
    33         -#include <X11/Xlib.h>
    34         -#include <X11/keysym.h>
    35         -#include <X11/XKBlib.h>
    36         -#include <X11/Xatom.h>
    37         -#include <X11/Xutil.h>
    38         -#include <X11/cursorfont.h>
    39         -#include <X11/extensions/Xrandr.h>
    40         -
    41         -#define MAX(a,b)	((a)>(b) ? (a) : (b))
    42         -
    43         -#define FLAG_ANY		0xFFFF
    44         -#define FLAG_FLOATING	0x0010
    45         -#define FLAG_TRANSIENT	0x0030
    46         -#define FLAG_FULLSCREEN	0x0040
    47         -#define FLAG_TOPSTACK	0x0080
    48         -#define FLAG_URG_HINT	0x0400
    49         -#define FLAG_FOC_HINT	0x0300
    50         -#define FOCUS_NOINPUT	0x0000
    51         -#define FOCUS_PASSIVE	0x0100
    52         -#define FOCUS_LOCAL		0x0200
    53         -#define FOCUS_GLOBAL	0x0300
    54         -
    55         -enum { Background, Default, Occupied, Selected, Urgent, Title,
    56         -	TabFocused, TabFocusedBG, TabTop, TabTopBG, TabDefault, TabDefaultBG,
    57         -	TagLine, LASTColor };
    58         -enum { MOff, MMove, MResize };
    59         -
    60         -typedef struct {
    61         -	unsigned int mod;
    62         -	KeySym keysym;
    63         -	void (*func)(const char *);
    64         -	const char *arg;
    65         -} Key;
    66         -
    67         -typedef struct {
    68         -	unsigned int mod, button;
    69         -	void (*func)(const char *);
    70         -	const char *arg;
    71         -} Button;
    72         -
    73         -typedef struct {
    74         -	const char *name, *class;
    75         -	int tags, flags;
    76         -} Rule;
    77         -
    78         -#define NO_ICON		-1
    79         -typedef struct {
    80         -	const char *pre;
    81         -	int icon;
    82         -	const char *post;
    83         -} Tagcon;
    84         -
    85         -typedef struct Monitor Monitor;
    86         -typedef struct Client Client;
    87         -struct Client {
    88         -	Window win, parent;
    89         -	Client *next;
    90         -	int x,y,w,h;
    91         -	unsigned int tags, flags;
    92         -	char *title;
    93         -	Monitor *m;
    94         -};
    95         -struct Monitor {
    96         -	Monitor *next;
    97         -	Client *master, *stack;
    98         -	int x, y, w, h;
    99         -	int count;
   100         -	Pixmap buf;
   101         -	Window bar;
   102         -};
   103         -
   104         -
   105         -/*********************** [1] PROTOTYPES & VARIABLES ***********************/
   106         -/* 1.0 EVENT HANDLER PROTOTYPES */
   107         -static void buttonpress(XEvent *);
   108         -static void buttonrelease(XEvent *);
   109         -static void configurenotify(XEvent *);
   110         -static void configurerequest(XEvent *);
   111         -static void enternotify(XEvent *);
   112         -static void expose(XEvent *);
   113         -static void keypress(XEvent *);
   114         -static void maprequest(XEvent *);
   115         -static void motionnotify(XEvent *);
   116         -static void propertynotify(XEvent *);
   117         -static void unmapnotify(XEvent *);
   118         -
   119         -/* 1.1 BINDABLE FUNCTION PROTOTYPES */
   120         -static void fullscreen(const char *);
   121         -static void killclient(const char *);
   122         -static void mouse(const char *);
   123         -static void quit(const char *);
   124         -static void spawn(const char *);
   125         -static void tag(const char *);
   126         -static void tile_conf(const char *);
   127         -static void tile(const char *);
   128         -static void toggle(const char *);
   129         -static void window(const char *);
   130         -static void windowlist(const char *);
   131         -
   132         -/* 1.2 ALOPEX INTERNAL PROTOTYPES */
   133         -static inline Bool tile_check(Client *, Monitor *);
   134         -static int apply_rules(Client *);
   135         -static int draw();
   136         -static int get_hints(Client *);
   137         -static int get_monitors();
   138         -static int neighbors(Client *,Bool);
   139         -static GC setcolor(int);
   140         -static int swap(Client *, Client *);
   141         -static int tile_bstack(Monitor *);
   142         -static int tile_monocle(Monitor *);
   143         -static int tile_rstack(Monitor *);
   144         -static Client *wintoclient(Window);
   145         -static int xerror(Display *,XErrorEvent *);
   146         -
   147         -/* 1.3 GLOBAL VARIABLES */
   148         -#include "icons.h"
   149         -#include "theme.h"
   150         -#include "config.h"
   151         -static Display *dpy;
   152         -static int scr;
   153         -static Window root;
   154         -static Pixmap sbar, iconbuf;
   155         -static GC gc,bgc;
   156         -static Colormap cmap;
   157         -static XColor color;
   158         -//static XFontStruct *fontstruct;
   159         -static XButtonEvent mouseEvent;
   160         -static Monitor *mons = NULL;
   161         -static Bool running = True;
   162         -static XFontSet xfs;
   163         -static int fontheight, barheight, statuswidth = 0, min_len = 2048;
   164         -static int mouseMode = MOff, ntilemode = 0;
   165         -static Client *clients = NULL, *focused = NULL, *nextwin, *prevwin, *altwin;
   166         -static FILE *inpipe;
   167         -static const char *noname_window = "(UNNAMED)";
   168         -static unsigned int tagsUrg = 0, tagsSel = 1, tagsOcc = 0, maxTiled = 1;
   169         -static int RREvent, RRError;
   170         -static void (*handler[LASTEvent]) (XEvent *) = {
   171         -	[ButtonPress]		= buttonpress,
   172         -	[ButtonRelease]		= buttonrelease,
   173         -	[ConfigureNotify]	= configurenotify,
   174         -	[ConfigureRequest]	= configurerequest,
   175         -	[EnterNotify]		= enternotify,
   176         -	[Expose]			= expose,
   177         -	[KeyPress]			= keypress,
   178         -	[MapRequest]		= maprequest,
   179         -	[PropertyNotify]	= propertynotify,
   180         -	[MotionNotify]		= motionnotify,
   181         -	[UnmapNotify]		= unmapnotify,
   182         -};
   183         -
   184         -/************************ [2] FUNCTION DEFINITIONS ************************/
   185         -/* 2.0 EVENT HANDLERS */
   186         -
   187         -void buttonpress(XEvent *ev) {
   188         -	Client *c;
   189         -	XButtonEvent *e = &ev->xbutton;
   190         -	if (!( (c=wintoclient(e->subwindow)) && e->state) ) return;
   191         -	if (c && e->button < 4) {
   192         -		focused = c;
   193         -		if (c->flags & FLAG_FLOATING) XRaiseWindow(dpy,c->win);
   194         -	}
   195         -	int i; mouseEvent = *e;
   196         -	for (i = 0; i < sizeof(buttons)/sizeof(buttons[0]); i++)
   197         -		if ( (e->button == buttons[i].button) && buttons[i].func &&
   198         -				buttons[i].mod == ((e->state&~Mod2Mask)&~LockMask) )
   199         -			buttons[i].func(buttons[i].arg);
   200         -	if (mouseMode != MOff)
   201         -		XGrabPointer(dpy,root,True,PointerMotionMask | ButtonReleaseMask,
   202         -				GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
   203         -	draw();
   204         -}
   205         -
   206         -void buttonrelease(XEvent *ev) {
   207         -	XUngrabPointer(dpy, CurrentTime);
   208         -	mouseMode = MOff;
   209         -	tile(tile_modes[ntilemode]);
   210         -}
   211         -
   212         -void configurenotify(XEvent *ev) {
   213         -	if (ignore_root_resize) return;
   214         -	XConfigureEvent *e = &ev->xconfigure;
   215         -	if (e->window != root) return;
   216         -	get_monitors();
   217         -	tile(tile_modes[ntilemode]);
   218         -}
   219         -
   220         -void configurerequest(XEvent *ev) {
   221         -	XConfigureRequestEvent *e = &ev->xconfigurerequest;
   222         -	Client *c;
   223         -	if ( (c=wintoclient(e->window)) ) {
   224         -		if ( (e->value_mask & CWWidth) && (e->value_mask & CWHeight) ) {
   225         -			if ( (e->width==c->m->w) && (e->height==c->m->h) )
   226         -				c->flags |= FLAG_FULLSCREEN;
   227         -			else
   228         -				c->flags &= ~FLAG_FULLSCREEN;
   229         -			c->x = e->x; c->y = e->y; c->w = e->width; c->h = e->height;
   230         -		}
   231         -		draw();
   232         -		return;
   233         -	}
   234         -	XWindowChanges wc;
   235         -	wc.x = e->x; wc.y = e->y; wc.width = e->width; wc.height = e->height;
   236         -	wc.sibling = e->above; wc.stack_mode = e->detail;
   237         -	wc.border_width = borderwidth;
   238         -	XConfigureWindow(dpy,e->window,e->value_mask,&wc);
   239         -	XFlush(dpy);
   240         -}
   241         -
   242         -void enternotify(XEvent *ev) {
   243         -	if (!focusfollowmouse) return;
   244         -	Client *c = wintoclient(ev->xcrossing.window);
   245         -	if (c) { focused = c; draw(); }
   246         -}
   247         -
   248         -void expose(XEvent *ev) {
   249         -	draw();
   250         -}
   251         -
   252         -void keypress(XEvent *ev) {
   253         -	unsigned int i;
   254         -	XKeyEvent *e = &ev->xkey;
   255         -	KeySym keysym = XkbKeycodeToKeysym(dpy,(KeyCode)e->keycode,0,0);
   256         -	for (i = 0; i < sizeof(keys)/sizeof(keys[0]); i++) {
   257         -		if ( (keysym == keys[i].keysym) && keys[i].func &&
   258         -				keys[i].mod == ((e->state&~Mod2Mask)&~LockMask) )
   259         -			keys[i].func(keys[i].arg);
   260         -	}
   261         -}
   262         -
   263         -//TODO: where does this code belong?
   264         -static inline Monitor *mouse_mon() {
   265         -	Window w; int x,y,n; unsigned int u;
   266         -	XQueryPointer(dpy,root,&w,&w,&x,&y,&n,&n,&u);
   267         -	Monitor *m;
   268         -	for (m = mons; m; m = m->next)
   269         -		if (m->x < x && m->x + m->w > x &&
   270         -			m->y < y && m->y + m->h > y)
   271         -		return m;
   272         -	return mons;
   273         -}
   274         -
   275         -void maprequest(XEvent *ev) {
   276         -//TODO: cleanup needed
   277         -	Client *c, *p;
   278         -	XWindowAttributes wa;
   279         -	XMapRequestEvent *e = &ev->xmaprequest;
   280         -	if (!XGetWindowAttributes(dpy,e->window,&wa)||wa.override_redirect) return;
   281         -	if (wintoclient(e->window)) return;
   282         -	if (!(c=calloc(1,sizeof(Client)))) exit(1);
   283         -	c->m = mouse_mon();
   284         -	c->win = e->window;
   285         -	c->w = wa.width; c->h = wa.height;
   286         -	if (c->x < 0) c->x = 0; if (c->y < 0) c->y = 0;
   287         -	c->x = (c->m->w - c->w)/2; c->y = (c->m->h - c->h)/2;
   288         -	c->tags = (tagsSel & 0xFFFF ? tagsSel &0xFFFF : ~tagsOcc & (tagsOcc + 1));
   289         -	apply_rules(c);
   290         -	if ( !(tagsSel & 0xFFFF) ) tagsSel |= c->tags;
   291         -	if (c->tags == 0) c->tags = 1;
   292         -	if ( (c->w==c->m->w) && (c->h==c->m->h) ) c->flags |= FLAG_FULLSCREEN;
   293         -	if (XGetTransientForHint(dpy,c->win,&c->parent))
   294         -		c->flags |= FLAG_TRANSIENT;
   295         -	else
   296         -		c->parent = e->parent;
   297         -XTextProperty name; char **list = NULL; int n;
   298         -XGetTextProperty(dpy,c->win,&name,XA_WM_NAME);
   299         -XmbTextPropertyToTextList(dpy,&name,&list,&n);
   300         -if (n && *list) {
   301         -c->title = strdup(*list);
   302         -XFreeStringList(list);
   303         -}
   304         -else {
   305         -if ( (p=wintoclient(c->parent)) ) c->title = strdup(p->title);
   306         -else c->title = strdup(noname_window);
   307         -}
   308         -//	if (!XFetchName(dpy,c->win,&c->title) || c->title == NULL) {
   309         -//		if ( (p=wintoclient(c->parent)) ) c->title = strdup(p->title);
   310         -//		else c->title = strdup(noname_window);
   311         -//	}
   312         -	get_hints(c);
   313         -	XSelectInput(dpy,c->win,PropertyChangeMask | EnterWindowMask);
   314         -	if (clients && attachmode == 1) {
   315         -		for (p = clients; p && p->next && !tile_check(p,c->m); p = p->next);
   316         -		c->next = p->next; p->next = c;
   317         -	}
   318         -	else if (clients && attachmode == 2) {
   319         -		for (p = clients; p->next; p = p->next); p->next = c;
   320         -	}
   321         -	else {
   322         -		c->next = clients; clients = c;
   323         -	}
   324         -	XSetWindowBorderWidth(dpy,c->win,borderwidth);
   325         -	XRaiseWindow(dpy,c->win);
   326         -	if (c->tags & tagsSel) focused = c;
   327         -	if (!(c->flags & FLAG_FLOATING)) tile(tile_modes[ntilemode]);
   328         -	draw();
   329         -	XMapWindow(dpy,c->win);
   330         -	draw();
   331         -}
   332         -
   333         -void motionnotify(XEvent *ev) {
   334         -	int xdiff, ydiff;
   335         -	while (XCheckTypedEvent(dpy,MotionNotify,ev));
   336         -	XButtonEvent *e = &ev->xbutton;
   337         -	xdiff = e->x_root - mouseEvent.x_root;
   338         -	ydiff = e->y_root - mouseEvent.y_root;
   339         -	if (mouseMode == MMove) {
   340         -		XDefineCursor(dpy,focused->win,XCreateFontCursor(dpy,XC_fleur));
   341         -		focused->x+=xdiff; focused->y+=ydiff; draw();
   342         -	}
   343         -	else if (mouseMode == MResize) {
   344         -		XDefineCursor(dpy,focused->win,XCreateFontCursor(dpy,XC_sizing));
   345         -		focused->w+=xdiff; focused->h+=ydiff; draw();
   346         -	}
   347         -	focused->flags |= FLAG_FLOATING;
   348         -	mouseEvent.x_root+=xdiff; mouseEvent.y_root+=ydiff;
   349         -}
   350         -
   351         -void propertynotify(XEvent *ev) {
   352         -	XPropertyEvent *e = &ev->xproperty;
   353         -	Client *c, *p;
   354         -	if (!(c=wintoclient(e->window)) ) return;
   355         -	if (e->atom == XA_WM_NAME) {
   356         -		XFree(c->title); c->title = NULL;
   357         -		XTextProperty name; char **list = NULL; int n;
   358         -		XGetTextProperty(dpy,c->win,&name,XA_WM_NAME);
   359         -		XmbTextPropertyToTextList(dpy,&name,&list,&n);
   360         -		if (n && *list) {
   361         -		c->title = strdup(*list);
   362         -		XFreeStringList(list);
   363         -		}
   364         -		else {
   365         -		if ( (p=wintoclient(c->parent)) ) c->title = strdup(p->title);
   366         -		else c->title = strdup(noname_window);
   367         -		}
   368         -	}
   369         -	else if (e->atom == XA_WM_HINTS) get_hints(c);
   370         -	else if (e->atom == XA_WM_CLASS) apply_rules(c);
   371         -	else return;
   372         -	draw();
   373         -	// TODO Size hints for fullscreen?
   374         -}
   375         -
   376         -void unmapnotify(XEvent *ev) {
   377         -	Client *c,*t;
   378         -	if (!(c=wintoclient(ev->xunmap.window)) || ev->xunmap.send_event) return;
   379         -	if (c == focused) {
   380         -		neighbors(c,False);
   381         -		if (nextwin) focused = nextwin;
   382         -		else focused = prevwin;
   383         -	}
   384         -	if (c == clients) clients = c->next;
   385         -	else {
   386         -		for (t = clients; t && t->next != c; t = t->next);
   387         -		t->next = c->next;
   388         -	}
   389         -	XFree(c->title);
   390         -	free(c); c = NULL;
   391         -	tile(tile_modes[ntilemode]);
   392         -	draw();
   393         -}
   394         -
   395         -/* 2.1 BINDABLE FUNCTIONS */
   396         -
   397         -void fullscreen(const char *arg) {
   398         -	if (!focused) return;
   399         -	focused->flags ^= FLAG_FULLSCREEN;
   400         -	XRaiseWindow(dpy,focused->win);
   401         -	draw();
   402         -}
   403         -
   404         -void killclient(const char *arg) {
   405         -	if (!focused) return;
   406         -	XEvent ev;
   407         -	ev.type = ClientMessage; ev.xclient.window = focused->win;
   408         -	ev.xclient.message_type = XInternAtom(dpy,"WM_PROTOCOLS",True);
   409         -	ev.xclient.format = 32;
   410         -	ev.xclient.data.l[0] = XInternAtom(dpy,"WM_DELETE_WINDOW",True);
   411         -	ev.xclient.data.l[1] = CurrentTime;
   412         -	XSendEvent(dpy,focused->win,False,NoEventMask,&ev);
   413         -}
   414         -
   415         -void mouse(const char *arg) {
   416         -	if (arg[0] == 'm') mouseMode = MMove;
   417         -	else if (arg[0] == 'r') mouseMode = MResize;
   418         -}
   419         -
   420         -void quit(const char *arg) {
   421         -	running = False;
   422         -}
   423         -
   424         -void spawn(const char *arg) {
   425         -	system(arg);
   426         -}
   427         -
   428         -void tag(const char *arg) {
   429         -	int i = arg[2] - 49;
   430         -	if (arg[0] == 's') tagsSel = ((tagsSel & 0xFFFF0000) | (1<<i));
   431         -	else if (arg[0] == 'f') tagsSel = ( tagsSel<<16 | tagsSel >>16);
   432         -	else if (arg[0] == 't') tagsSel ^= (1<<i);
   433         -	else if (arg[0] == 'a' && focused ) focused->tags ^= (1<<i);
   434         -	else if (arg[0] == 'm' && focused ) focused->tags = (1<<i);
   435         -	tile(tile_modes[ntilemode]);
   436         -	Client *c,*t=NULL;
   437         -	if (!focused || !(focused->tags & tagsSel)) {
   438         -		for (c = clients; c; c = c->next) if (c->tags & tagsSel) {
   439         -			if (!t) t = c;
   440         -			if (c->flags & FLAG_FULLSCREEN) t = c;
   441         -		}
   442         -		if (t) focused = t;
   443         -	}
   444         -	draw();
   445         -}
   446         -
   447         -void tile_conf(const char *arg) {
   448         -	if (arg[0] == 'i') tilebias += 4;
   449         -	else if (arg[0] == 'd') tilebias -= 4;
   450         -	else if (arg[0] == '+') stackcount++;
   451         -	else if (arg[0] == '-') stackcount--;
   452         -	else if (arg[0] == 'a') stackcount = maxTiled;
   453         -	else if (arg[0] == 'o') stackcount = 1;
   454         -	if (stackcount >= maxTiled) stackcount = maxTiled - 1;
   455         -	if (stackcount < 1) stackcount = 1;
   456         -	if (tilebias > min_len/2 - win_min) tilebias = min_len/2 - win_min;
   457         -	else if (tilebias < win_min - min_len/2) tilebias = win_min - min_len/2;
   458         -	tile(tile_modes[ntilemode]);
   459         -}
   460         -
   461         -void tile(const char *arg) {
   462         -	char mode = arg[0];
   463         -	int i;
   464         -	Client *c;
   465         -	for (i = 0; tile_modes[i]; i++) 
   466         -		if (mode == tile_modes[i][0]) ntilemode = i;
   467         -	if (mode == 'c')
   468         -		mode = tile_modes[(ntilemode=(tile_modes[++ntilemode]?ntilemode:0))][0];
   469         -	Monitor *m;
   470         -	maxTiled = 0;
   471         -	for (i = 0, m = mons; m; i++, m = m->next) m->count = 0;
   472         -	for (c = clients; c; c = c->next)
   473         -		if (c->tags & tagsSel && !(c->flags & FLAG_FLOATING)) {
   474         -			c->m->count++;
   475         -			maxTiled = MAX(maxTiled,c->m->count);
   476         -		}
   477         -	if (maxTiled == 0) return;
   478         -	for (i = 0, m = mons; m; i++, m = m->next) {
   479         -		if (m->count == 0) continue;
   480         -		if (m->count > stackcount + 1) m->count = stackcount + 1;
   481         -		if (m->count == 1) tile_monocle(m);
   482         -		else if (mode == 'b') tile_bstack(m);
   483         -		else if (mode == 'm') tile_monocle(m);
   484         -		else if (mode == 'r') tile_rstack(m);
   485         -	}
   486         -	if (focused) {
   487         -		XRaiseWindow(dpy,focused->win);
   488         -		for (c = clients; c; c = c->next)
   489         -			if ( (c->tags & tagsSel) && (c->flags & FLAG_FLOATING))
   490         -				XRaiseWindow(dpy,c->win);
   491         -	}
   492         -	draw();
   493         -}
   494         -
   495         -void toggle(const char *arg) {
   496         -	Monitor *m;
   497         -	if (arg[0] == 'p') topbar = !topbar;
   498         -	else if (arg[0] == 'v') showbar = !showbar;
   499         -	else if (arg[0] == 'f' && focused) focused->flags ^= FLAG_FLOATING;
   500         -	else if (arg[0] == 'r') ignore_root_resize = !ignore_root_resize;
   501         -else if (arg[0] == 'm' ) {
   502         -	Client *c;
   503         -	if (focused) m = focused->m;
   504         -	else m = mouse_mon();
   505         -	if (m && m->next) m = m->next;
   506         -	else m = mons;
   507         -	for (c = clients; c && !tile_check(c,m); c = c->next);
   508         -	if (c) focused=c;
   509         -}	
   510         -	for (m = mons; m; m = m->next)
   511         -		XMoveWindow(dpy,m->bar,(showbar ? m->x : -4*mons[0].w),
   512         -				(topbar ? 0 : m->h-barheight));
   513         -	tile(tile_modes[ntilemode]);
   514         -}
   515         -
   516         -void window(const char *arg) {
   517         -	if (!focused) return;
   518         -	Monitor *m,*mm = mons;
   519         -	if (arg[0] == '+' || arg[0] == '-') { /* move to monitor */
   520         -		if (arg[0] == '+' && focused->m->next) {
   521         -			focused->m = focused->m->next;
   522         -		}
   523         -		else {
   524         -			for (m = mons; m != focused->m; m = m->next) mm = m;
   525         -			focused->m = mm;
   526         -		}
   527         -		tile(tile_modes[ntilemode]);
   528         -		return;
   529         -	}
   530         -	if (arg[2] < 95) {
   531         -		neighbors(focused,True);
   532         -	}
   533         -	else {
   534         -		if (focused->flags & FLAG_FLOATING) return;
   535         -		neighbors(focused,False);
   536         -	}
   537         -	Client *t = NULL;
   538         -	if (arg[2] == 'p') t = prevwin;
   539         -	else if (arg[2] == 'P') t = prevwin;
   540         -	else if (arg[2] == 'n') t = nextwin;
   541         -	else if (arg[2] == 'N') t = nextwin;
   542         -	else if (arg[2] == 'a') t = altwin;
   543         -	if (!t) return;
   544         -	if (arg[0] == 'f') focused = t;
   545         -	else if (arg[0] == 's') { swap(focused, t); focused = t; }
   546         -	XRaiseWindow(dpy,focused->win);
   547         -	draw();
   548         -}
   549         -
   550         -void windowlist(const char *arg) {
   551         -	Client *c;
   552         -	const char *wlname = "/tmp/alopex_windows";
   553         -	FILE *wl = fopen(wlname,"w");
   554         -	for (c = clients; c; c = c->next) {
   555         -		fprintf(wl,"%p %s\n",c,c->title);
   556         -		printf("%p %s\n",c,c->title);
   557         -	}
   558         -	fclose(wl);
   559         -	if ( (wl=popen(arg,"r")) ) {
   560         -		if (fscanf(wl,"%p",&c)==1) {
   561         -			focused = c;
   562         -			if (!(c->tags & tagsSel)) c->tags |= tagsSel;
   563         -			draw();
   564         -		}
   565         -		pclose(wl);
   566         -	}
   567         -}
   568         -
   569         -/* 2.2 WM INTERNAL FUNCTIONS */
   570         -
   571         -static inline Bool tile_check(Client *c, Monitor *m) {
   572         -	return (c&&(c->tags&tagsSel) && !(c->flags&FLAG_FLOATING) && (c->m==m));
   573         -}
   574         -
   575         -static int apply_rules(Client *c) {
   576         -	XClassHint *hint = XAllocClassHint();
   577         -	XGetClassHint(dpy, c->win, hint);
   578         -	int i, m;
   579         -	const char *rc, *rn, *hc = hint->res_class, *hn = hint->res_name;
   580         -	for (i = 0; i < sizeof(rules)/sizeof(rules[0]); i++) {
   581         -		rc = rules[i].class; rn = rules[i].name; m = 0;
   582         -		if (rc && hc && !strncmp(rc,hc,strlen(rc))) m++;
   583         -		if (rn && hn && !strncmp(rn,hn,strlen(rn))) m++;
   584         -		if ( (m && !(rc && rn)) || (m == 2) ) {
   585         -			if (rules[i].tags > 0) c->tags = rules[i].tags;
   586         -			c->flags |= rules[i].flags;
   587         -		}
   588         -	}
   589         -	XFree(hint->res_name); XFree(hint->res_class); XFree(hint);
   590         -	return 0;
   591         -}
   592         -
   593         -static inline void draw_tab(Pixmap buf, Client *c,int *x,int tw) {
   594         -	int col1 = (c->flags & FLAG_URG_HINT ? Urgent : (c==focused?Title:Default));
   595         -	int col2 = (c==focused ? TabFocused : ( ((c==c->m->master || c==c->m->stack) && 
   596         -			!(tile_modes[ntilemode][0] == 'm')) ? TabTop : TabDefault ));
   597         -	XPoint top_pts[6] = { {*x,barheight}, {0,2-barheight}, {2,-2},
   598         -		{tw,0}, {2,2}, {0,barheight-2} };
   599         -	XPoint bot_pts[6] = { {*x,0}, {0,barheight-3}, {2,2}, {tw,0},
   600         -			{2,-2}, {0,3-barheight} };
   601         -	*x+=8;
   602         -	XFillPolygon(dpy,buf,setcolor(col2+1),(topbar ? top_pts : bot_pts),6,
   603         -		Convex,CoordModePrevious);
   604         -	top_pts[0].x -=1;
   605         -XmbDrawString(dpy,buf,xfs,setcolor(col1),*x,fontheight,c->title,strlen(c->title));
   606         -//	XDrawString(dpy,buf,setcolor(col1),*x,fontheight,c->title,strlen(c->title));
   607         -	XFillRectangle(dpy,buf,bgc,*x+tw-5,0,tw,barheight);
   608         -	XDrawLines(dpy,buf,setcolor(col2),(topbar?top_pts:bot_pts),
   609         -			6,CoordModePrevious);
   610         -	*x+=tw;
   611         -}
   612         -
   613         -static void draw_tabs(Pixmap buf, int x, int w, int mid, Monitor *m) {
   614         -	Client *c;
   615         -	int count, tab1w, tabw;
   616         -	/* get count - skip if zero */
   617         -	for (count = 0, c = clients; c; c = c->next) if (tile_check(c,m)) count++;
   618         -	if (!count) return;
   619         -	/* set tab widths */
   620         -	if (tile_modes[ntilemode][0]=='m' || count==1) tab1w = tabw = w/count - 8;
   621         -	else { tab1w = mid-x; tabw = (x+w-mid - 2)/(count-1) - 8; }
   622         -	if (tabw < 20) tabw = 20;
   623         -	/* draw master title and tab */
   624         -	for (c = clients; !(tile_check(c,m)); c = c->next);
   625         -	draw_tab(buf,c,&x,tab1w);
   626         -	if (count == 1) return;
   627         -	/* draw stack titles and tabs */
   628         -	for (c = c->next; c; c = c->next)
   629         -		if (tile_check(c,m)) draw_tab(buf,c,&x,tabw);
   630         -}
   631         -
   632         -int draw() {
   633         -	tagsUrg &= ~tagsSel; tagsOcc = 0; Monitor *m;
   634         -	/* windows */
   635         -	Client *stack = clients;
   636         -	for (m = mons; m; m = m->next) m->master = m->stack = NULL;
   637         -	XSetWindowAttributes wa;
   638         -	while (stack) {
   639         -		tagsOcc |= stack->tags;
   640         -		if (!(stack->tags & tagsSel)) { /* not on selected tag(s) */
   641         -			XMoveWindow(dpy,stack->win,-2*mons[0].w,0);
   642         -			stack = stack->next; continue;
   643         -		}
   644         -		else if (!(stack->flags & FLAG_FLOATING)) { /* tiled */
   645         -			if (!stack->m->master) stack->m->master = stack;
   646         -			else if (!stack->m->stack) stack->m->stack = stack;
   647         -			else if (stack->flags & FLAG_TOPSTACK) stack->m->stack = stack;
   648         -		}
   649         -		stack->flags &= ~FLAG_TOPSTACK;
   650         -		if (stack->flags & FLAG_FULLSCREEN)
   651         -			XMoveResizeWindow(dpy,stack->win,stack->m->x-borderwidth,
   652         -					stack->m->y-borderwidth,stack->m->w,stack->m->h);
   653         -		else
   654         -			XMoveResizeWindow(dpy,stack->win,stack->x,
   655         -					stack->y,stack->w,stack->h);
   656         -		if (stack == focused) setcolor(Selected);
   657         -		else setcolor(Occupied);
   658         -		wa.border_pixel = color.pixel;
   659         -		XChangeWindowAttributes(dpy,stack->win,CWBorderPixel,&wa);
   660         -		stack = stack->next;
   661         -	}
   662         -	if (focused) {
   663         -		if ( (focused != focused->m->master) && !(focused->flags & FLAG_FLOATING) )
   664         -			focused->m->stack = focused;
   665         -		if ( (focused->flags & FLAG_FOC_HINT) > 1) {
   666         -			XEvent ev;
   667         -			ev.type = ClientMessage; ev.xclient.window = focused->win;
   668         -			ev.xclient.message_type = XInternAtom(dpy,"WM_PROTOCOLS",True);
   669         -			ev.xclient.format = 32;
   670         -			ev.xclient.data.l[0] = XInternAtom(dpy,"WM_TAKE_FOCUS",True);
   671         -			ev.xclient.data.l[1] = CurrentTime;
   672         -			XSendEvent(dpy,focused->win,False,NoEventMask,&ev);
   673         -		}
   674         -		else {
   675         -			XSetInputFocus(dpy,focused->win,RevertToPointerRoot,CurrentTime);
   676         -		}
   677         -		focused->flags &= ~FLAG_URG_HINT;
   678         -	}
   679         -	for (m = mons; m ; m = m->next) {
   680         -		if (m->stack) m->stack->flags |= FLAG_TOPSTACK;
   681         -		/* clear buffers */
   682         -		XFillRectangle(dpy,m->buf,setcolor(Background),0,0,m->w,barheight);
   683         -	}
   684         -	/* tags */
   685         -	m = mons; /* tags are drawn on main screen only */
   686         -	int i,x=10,w=0,col, tagsAlt = (tagsSel>>16);
   687         -	for (i = 0; i < sizeof(tagcons)/sizeof(tagcons[0]); i++) {
   688         -		if (!((tagsOcc|tagsSel) & (1<<i))) continue;
   689         -		col = (tagsUrg & (1<<i) ? Urgent :
   690         -			(tagsOcc & (1<<i) ? Occupied : Default));
   691         -		if (focused && focused->tags & (1<<i)) col = Selected;
   692         -			w = 0;
   693         -			if (tagcons[i].pre) {
   694         -XmbDrawString(dpy,m->buf,xfs,setcolor(col),x,fontheight,
   695         -tagcons[i].pre,strlen(tagcons[i].pre));
   696         -w += XmbTextEscapement(xfs,tagcons[i].pre,strlen(tagcons[i].pre));
   697         -//				XDrawString(dpy,m->buf,setcolor(col),x,fontheight,
   698         -//						tagcons[i].pre,strlen(tagcons[i].pre));
   699         -//				w += XTextWidth(fontstruct,tagcons[i].pre,strlen(tagcons[i].pre));
   700         -			}
   701         -			if (tagcons[i].icon > -1) {
   702         -			XFillRectangle(dpy,iconbuf,bgc,0,0,iconwidth,iconheight);
   703         -			XDrawPoints(dpy,iconbuf,setcolor(col),icons[tagcons[i].icon].pts,
   704         -					icons[tagcons[i].icon].n,CoordModeOrigin);
   705         -			XCopyArea(dpy,iconbuf,m->buf,gc,0,0,iconwidth,iconheight,
   706         -					x+w,(barheight-iconheight)/2);
   707         -			w += iconwidth;
   708         -			}
   709         -			if (tagcons[i].post) {
   710         -					w += 2;
   711         -XmbDrawString(dpy,m->buf,xfs,setcolor(col),x+w,fontheight,
   712         -tagcons[i].post,strlen(tagcons[i].post));
   713         -w += XmbTextEscapement(xfs,tagcons[i].post,strlen(tagcons[i].post));
   714         -//					XDrawString(dpy,m->buf,setcolor(col),x+w,fontheight,
   715         -//						tagcons[i].post,strlen(tagcons[i].post));
   716         -//					w += XTextWidth(fontstruct,tagcons[i].post,strlen(tagcons[i].post));
   717         -			}
   718         -			setcolor(TagLine);
   719         -			if (tagsSel & (1<<i)) {
   720         -				XDrawLine(dpy,m->buf,gc,x-2,barheight-1,x+w+2,barheight-1);
   721         -				XDrawPoint(dpy,m->buf,gc,x-2,barheight-2);
   722         -				XDrawPoint(dpy,m->buf,gc,x+w+2,barheight-2);
   723         -			}
   724         -			if (tagsAlt & (1<<i)) {
   725         -				XDrawLine(dpy,m->buf,gc,x-2,0,x+w+2,0);
   726         -				XDrawPoint(dpy,m->buf,gc,x-2,1);
   727         -				XDrawPoint(dpy,m->buf,gc,x+w+2,1);
   728         -			}
   729         -			x+=w+5;
   730         -	}
   731         -	if ( (x+=5) < tagspace ) x = tagspace; /* add padding */
   732         -	/* titles / tabs */
   733         -	for (i = 0, m = mons; m; i++, m = m->next)
   734         -		draw_tabs(m->buf,(i?2:x),m->w-(i?8:x+statuswidth+10),
   735         -				m->w/2+tilebias-6,m);
   736         -	/* status */
   737         -	if (statuswidth)
   738         -		XCopyArea(dpy,sbar,mons[0].buf,gc,0,0,statuswidth,
   739         -				barheight,mons[0].w-statuswidth,0);
   740         -	for (m = mons; m; m = m->next)
   741         -		XCopyArea(dpy,m->buf,m->bar,gc,0,0,m->w,barheight,0,0);
   742         -	XFlush(dpy);
   743         -	return 0;
   744         -}
   745         -
   746         -int get_hints(Client *c) {
   747         -	XWMHints *hint;
   748         -	if ( (hint=XGetWMHints(dpy,c->win)) ) {
   749         -		if (hint->flags & XUrgencyHint) {
   750         -			tagsUrg |= c->tags;
   751         -			c->flags |= FLAG_URG_HINT;
   752         -		}
   753         -		else if (hint->flags & InputHint && !hint->input) {
   754         -			c->flags |= FLAG_FOC_HINT; /* TODO: termine Local vs Global */
   755         -		}
   756         -		XFree(hint);
   757         -	}
   758         -	return 0;
   759         -}
   760         -
   761         -int get_monitors() {
   762         -	/* free current monitors */
   763         -	Monitor *m; Client *c;
   764         -	for (m = mons; m; m = m->next) {
   765         -		XFreePixmap(dpy,m->buf);
   766         -		XDestroyWindow(dpy,m->bar);
   767         -	}
   768         -	if (mons) free(mons);
   769         -	/* get xrandr info */
   770         -	XSetWindowAttributes wa;
   771         -	wa.override_redirect = True;
   772         -	wa.event_mask = ExposureMask;
   773         -	XRRScreenResources *xrr_sr = XRRGetScreenResources(dpy,root);
   774         -	XRROutputInfo *xrr_out_info;
   775         -	XRRCrtcInfo *xrr_crtc_info;
   776         -	int i, nscr = xrr_sr->noutput;
   777         -	mons = (Monitor *) calloc(nscr,sizeof(Monitor));
   778         -	/* loop through monitors */
   779         -	for (i = 0; i < nscr; i++) {
   780         -		xrr_out_info = XRRGetOutputInfo(dpy, xrr_sr, xrr_sr->outputs[i]);
   781         -		if (!xrr_out_info->crtc) {
   782         -			nscr = i;
   783         -			mons = (Monitor *) realloc(mons,nscr * sizeof(Monitor));
   784         -			XRRFreeOutputInfo(xrr_out_info);
   785         -			break;
   786         -		}
   787         -		xrr_crtc_info = XRRGetCrtcInfo(dpy, xrr_sr, xrr_out_info->crtc);
   788         -		m = &mons[i];
   789         -		m->x = xrr_crtc_info->x;
   790         -		m->y = xrr_crtc_info->y;
   791         -		m->w = xrr_crtc_info->width;
   792         -		m->h = xrr_crtc_info->height;
   793         -		min_len = (min_len > m->w ? m->w : min_len);
   794         -		min_len = (min_len > m->h ? m->h : min_len);
   795         -		XRRFreeCrtcInfo (xrr_crtc_info);
   796         -		XRRFreeOutputInfo(xrr_out_info);
   797         -		m->bar = XCreateSimpleWindow(dpy,root,m->x,
   798         -			(topbar ? m->y : m->h - barheight), m->w,barheight,0,0,0);
   799         -		m->buf = XCreatePixmap(dpy,root,m->w,barheight,DefaultDepth(dpy,scr));
   800         -		XChangeWindowAttributes(dpy,m->bar,CWOverrideRedirect|CWEventMask,&wa);
   801         -		XMapWindow(dpy,m->bar);
   802         -	}
   803         -	XRRFreeScreenResources(xrr_sr);
   804         -	for (i = 0; i < nscr - 1; i++) mons[i].next = &mons[i+1];
   805         -	for (c = clients; c; c = c->next) {
   806         -		for (m = mons; m; m = m->next)
   807         -			if (m->x <= c->x && m->x + m->w > c->x &&
   808         -					m->y <= c->y && m->y + m->h > c->y)
   809         -				c->m = m;
   810         -	}
   811         -#ifdef WALLPAPER
   812         -	system(CMD(WALLPAPER));
   813         -#endif
   814         -	return 0;
   815         -}
   816         -
   817         -int neighbors(Client *c, Bool floaters) {
   818         -	prevwin = NULL; nextwin = NULL; altwin = NULL;
   819         -	if (!(c->tags & tagsSel)) return -1;
   820         -	Client *stack;
   821         -	if (floaters) {
   822         -		for (stack = clients; stack && stack != c; stack = stack->next)
   823         -			if (stack&&(stack->tags&tagsSel) && (stack->m==c->m)) prevwin = stack; 
   824         -		if (!stack) return -1;
   825         -		for (nextwin = stack->next; nextwin; nextwin = nextwin->next)
   826         -			if (stack&&(stack->tags&tagsSel) && (stack->m==c->m)) break;
   827         -	}
   828         -	else {
   829         -		for (stack = c->m->master; stack && stack != c; stack = stack->next)
   830         -			if (tile_check(stack,c->m)) prevwin = stack;
   831         -		if (!stack) return -1;
   832         -		for (nextwin = stack->next; nextwin; nextwin = nextwin->next)
   833         -			if (tile_check(nextwin,c->m)) break;
   834         -		if (c->m && c->m->master == focused) altwin = c->m->stack;
   835         -		else if (c->m) altwin = c->m->master;
   836         -	}
   837         -	return 0;
   838         -}
   839         -
   840         -GC setcolor(int col) {
   841         -	XAllocNamedColor(dpy,cmap,colors[col],&color,&color);
   842         -	XSetForeground(dpy,gc,color.pixel);
   843         -	return gc;
   844         -}
   845         -
   846         -int status(char *msg) {
   847         -	char col[8] = "#000000", *t,*c = msg;
   848         -	int l, arg, lastwidth = statuswidth;
   849         -	statuswidth = 0;
   850         -	XFillRectangle(dpy,sbar,setcolor(Background),0,0,mons[0].w/2,barheight);
   851         -	setcolor(Default);
   852         -	while (*c != '\n') {
   853         -		if (*c == '{') {
   854         -			if (*(++c) == '#') {
   855         -				strncpy(col,c,7);
   856         -				XAllocNamedColor(dpy,cmap,col,&color,&color);
   857         -				XSetForeground(dpy,gc,color.pixel);
   858         -			}
   859         -			else if (*c == 'i' && sscanf(c,"i %d",&arg) == 1) {
   860         -				XFillRectangle(dpy,iconbuf,bgc,0,0,iconwidth,iconheight);
   861         -				XDrawPoints(dpy,iconbuf,gc,icons[arg].pts,icons[arg].n,
   862         -					CoordModeOrigin);
   863         -				XCopyArea(dpy,iconbuf,sbar,gc,0,0,iconwidth,iconheight,
   864         -						statuswidth,(barheight-iconheight)/2);
   865         -				statuswidth+=iconwidth+1;
   866         -			}
   867         -			c = strchr(c,'}')+1;
   868         -		}
   869         -		else {
   870         -			if ( (t=strchr(c,'{'))==NULL) t = strchr(c,'\n');
   871         -			if ( (l = (t == NULL ? 0 : t - c) ) ) {
   872         -XmbDrawString(dpy,sbar,xfs,gc,statuswidth,fontheight,c,l);
   873         -statuswidth += XmbTextEscapement(xfs,c,l);
   874         -//				XDrawString(dpy,sbar,gc,statuswidth,fontheight,c,l);
   875         -//				statuswidth += XTextWidth(fontstruct,c,l);
   876         -			}
   877         -			c+=l;
   878         -		}
   879         -	}
   880         -	if (statuswidth == lastwidth) {
   881         -		XCopyArea(dpy,sbar,mons[0].bar,gc,0,0,statuswidth,barheight,
   882         -				mons[0].w-statuswidth,0);
   883         -		XFlush(dpy);
   884         -	}
   885         -	else draw();
   886         -	return 0;
   887         -}
   888         -
   889         -int swap(Client *a, Client *b) {
   890         -	if (!a || !b) return -1;
   891         -	Client t;
   892         -	t.title = a->title; a->title=b->title; b->title = t.title;
   893         -	t.tags = a->tags; a->tags = b->tags; b->tags = t.tags;
   894         -	t.flags = a->flags; a->flags = b->flags; b->flags = t.flags;
   895         -	t.win = a->win; a->win = b->win; b->win = t.win;
   896         -	t.m = a->m; a->m = b->m; b->m = t.m;
   897         -	if (a->flags & FLAG_TOPSTACK) {
   898         -		a->flags &= ~FLAG_TOPSTACK; b->flags |= FLAG_TOPSTACK;
   899         -	}
   900         -	else if (b->flags & FLAG_TOPSTACK) {
   901         -		b->flags &= ~FLAG_TOPSTACK; a->flags |= FLAG_TOPSTACK;
   902         -	}
   903         -	return 0;
   904         -}
   905         -
   906         -#define TILE_CALC	\
   907         -	int x = m->x + tilegap, w = m->w - 2*(tilegap + borderwidth),\
   908         -		y = m->y + (showbar ? (topbar ? barheight : 0) : 0) + tilegap,\
   909         -		h = m->h - (showbar ? barheight : 0) - 2*(tilegap + borderwidth);
   910         -
   911         -int tile_bstack(Monitor *m) {
   912         -	TILE_CALC
   913         -	Client *c, *t = NULL;
   914         -	for (c = clients; !tile_check(c,m); c = c->next);
   915         -	int wh = (h - tilegap)/2 - borderwidth;
   916         -	int ww = w/(m->count - 1) - tilegap/2;
   917         -	c->x = x; c->y = y;	c->w = w; c->h = wh + tilebias;
   918         -	int i = 0;
   919         -	while ( (c=c->next) ) {
   920         -		if (!tile_check(c,m)) continue;
   921         -		c->x = x + i*(ww + tilegap + borderwidth);
   922         -		c->y = y + wh + tilegap + 2*borderwidth + tilebias;
   923         -		c->w = MAX(ww - borderwidth, win_min);
   924         -		c->h = wh - tilebias;
   925         -		if (!t && i == m->count - 2) t = c;
   926         -		i = ( i == m->count - 2 ? m->count - 2 : i + 1);
   927         -	}
   928         -	while (t) {
   929         -		if (tile_check(t,m)) t->w = MAX(x + w - t->x,win_min);
   930         -		t = t->next;
   931         -	}
   932         -	return 0;
   933         -}
   934         -
   935         -int tile_monocle(Monitor *m) {
   936         -	TILE_CALC
   937         -	Client *c = clients;
   938         -	for (c = clients; !tile_check(c,m); c = c->next);
   939         -	if (c) do {
   940         -		if (!tile_check(c,m)) continue;
   941         -		c->x = x; c->y = y;	c->w = w; c->h = h;
   942         -	} while ( (c=c->next) );
   943         -	return 0;
   944         -}
   945         -
   946         -int tile_rstack(Monitor *m) {
   947         -	TILE_CALC
   948         -	Client *c, *t = NULL;
   949         -	for (c = clients; !tile_check(c,m); c = c->next);
   950         -	int ww = (w - tilegap)/2 - borderwidth;
   951         -	int wh = h/(m->count - 1) - tilegap/2;
   952         -	c->x = x; c->y = y; c->w = ww + tilebias; c->h = h;
   953         -	int i = 0;
   954         -	while ( (c=c->next) ) {
   955         -		if (!tile_check(c,m)) continue;
   956         -		c->x = x + ww + tilegap + 2*borderwidth + tilebias;
   957         -		c->y = y + i*(wh + tilegap + borderwidth);
   958         -		c->w = ww - tilebias;
   959         -		c->h = MAX(wh - borderwidth,win_min);
   960         -		if (!t && i == m->count - 2) t = c;
   961         -		i = ( i == m->count - 2 ? m->count - 2 : i + 1);
   962         -	}
   963         -	while (t) {
   964         -		if (tile_check(t,m)) t->h = MAX(y + h - t->y, win_min);
   965         -		t = t->next;
   966         -	}
   967         -	return 0;
   968         -}
   969         -
   970         -Client *wintoclient(Window w) {
   971         -	Client *c;
   972         -	for (c = clients; c && c->win != w; c = c->next);
   973         -	return c;
   974         -}
   975         -
   976         -int xerror(Display *d, XErrorEvent *ev) {
   977         -	char msg[1024];
   978         -	XGetErrorText(dpy,ev->error_code,msg,sizeof(msg));
   979         -	fprintf(stderr,"[ALOPEX] (%d:%d) %s\n",ev->request_code,ev->error_code,msg);
   980         -	return 0;
   981         -}
   982         -
   983         -int main(int argc, const char **argv) {
   984         -	if (argc > 1) inpipe = popen(argv[1] ,"r");
   985         -	else inpipe = popen("while :; do date \"+%I:%M %p\"; sleep 10; done","r");
   986         -	/* init X */
   987         -	if (!(setlocale(LC_CTYPE,"") && XSupportsLocale())) return 1;
   988         -	if (!XSetLocaleModifiers("")) return 2;
   989         -	if (!(dpy=XOpenDisplay(0x0))) return 3;
   990         -	if (!(XRRQueryExtension(dpy,&RREvent,&RRError))) return 4;
   991         -	scr = DefaultScreen(dpy);
   992         -	root = DefaultRootWindow(dpy);
   993         -	XSetErrorHandler(xerror);
   994         -	XDefineCursor(dpy,root,XCreateFontCursor(dpy,alopex_cursor));
   995         -	/* gc init */
   996         -	cmap = DefaultColormap(dpy,scr);
   997         -	XColor color;
   998         -	XGCValues val;
   999         -char **missing, **names, *def; int nmiss;
  1000         -xfs = XCreateFontSet(dpy,(char *) font,&missing,&nmiss,&def);
  1001         -if (!xfs) return 5;
  1002         -XFontStruct **fss;
  1003         -XFontsOfFontSet(xfs,&fss,&names);
  1004         -if (missing) XFreeStringList(missing);
  1005         -fontheight = fss[0]->ascent;
  1006         -barheight = fss[0]->ascent+fss[0]->descent+2;
  1007         -//	val.font = XLoadFont(dpy,font);
  1008         -//	fontstruct = XQueryFont(dpy,val.font);
  1009         -//	fontheight = fontstruct->ascent+1;
  1010         -//	barheight = fontstruct->ascent+fontstruct->descent+2;
  1011         -	gc = XCreateGC(dpy,root,0,&val);
  1012         -	bgc = DefaultGC(dpy,scr);
  1013         -	XAllocNamedColor(dpy,cmap,colors[Background],&color,&color);
  1014         -	XSetForeground(dpy,bgc,color.pixel);
  1015         -	/* monitors, bar windows, and buffers */
  1016         -	get_monitors();
  1017         -	sbar = XCreatePixmap(dpy,root,mons[0].w/2,barheight,DefaultDepth(dpy,scr));
  1018         -	iconbuf = XCreatePixmap(dpy,root,iconwidth,iconheight,
  1019         -			DefaultDepth(dpy,scr));
  1020         -	/* configure root window */
  1021         -	XSetWindowAttributes wa;
  1022         -	wa.event_mask = ExposureMask |FocusChangeMask | SubstructureNotifyMask |
  1023         -			ButtonReleaseMask | PropertyChangeMask | SubstructureRedirectMask |
  1024         -			StructureNotifyMask;
  1025         -	XChangeWindowAttributes(dpy,root,CWEventMask,&wa);
  1026         -	XSelectInput(dpy,root,wa.event_mask);
  1027         -	//XRRSelectInput(dpy,root,RREvent & RRScreenChangeNotify);
  1028         -	/* key and mouse bindings */
  1029         -	unsigned int mods[] = {0, LockMask, Mod2Mask, LockMask|Mod2Mask};
  1030         -	KeyCode code;
  1031         -	XUngrabKey(dpy,AnyKey,AnyModifier,root);
  1032         -	int i,j;
  1033         -	for (i = 0; i < sizeof(keys)/sizeof(keys[0]); i++)
  1034         -		if ( (code=XKeysymToKeycode(dpy,keys[i].keysym)) )
  1035         -			for (j = 0; j < 4; j++)
  1036         -				XGrabKey(dpy,code,keys[i].mod|mods[j],root,True,
  1037         -						GrabModeAsync,GrabModeAsync);
  1038         -	for (i = 0; i < sizeof(buttons)/sizeof(buttons[0]); i++)
  1039         -		if (buttons[i].mod) for (j = 0; j < 4; j++)
  1040         -			XGrabButton(dpy,buttons[i].button,buttons[i].mod|mods[j],root,True,
  1041         -					ButtonPressMask,GrabModeAsync,GrabModeAsync,None,None);
  1042         -	/* main loop */
  1043         -	draw();
  1044         -	XEvent ev;
  1045         -	int xfd, sfd;
  1046         -	fd_set fds;
  1047         -	sfd = fileno(inpipe);
  1048         -	xfd = ConnectionNumber(dpy);
  1049         -	char *line = (char *) calloc(max_status_line+1,sizeof(char));
  1050         -	while (running) {
  1051         -		FD_ZERO(&fds);
  1052         -		FD_SET(sfd,&fds);
  1053         -		FD_SET(xfd,&fds);
  1054         -		select(xfd+1,&fds,0,0,NULL);
  1055         -		if (FD_ISSET(xfd,&fds)) while (XPending(dpy)) {
  1056         -			XNextEvent(dpy,&ev);
  1057         -			if (ev.type == (RREvent & RRScreenChangeNotify)) get_monitors();
  1058         -			else if (handler[ev.type]) handler[ev.type](&ev);
  1059         -		}
  1060         -		if (FD_ISSET(sfd,&fds)) {
  1061         -			if (fgets(line,max_status_line,inpipe))
  1062         -				status(line);
  1063         -		}
  1064         -	}
  1065         -	/* clean up */
  1066         -	Monitor *m;
  1067         -	for (m = mons; m; m = m->next) {
  1068         -		XFreePixmap(dpy,m->buf);
  1069         -		XDestroyWindow(dpy,m->bar);
  1070         -	}
  1071         -	free(mons);
  1072         -	XDestroyWindow(dpy,sbar);
  1073         -	free(line);
  1074         -XFreeFontSet(dpy,xfs);
  1075         -//	XFreeFontInfo(NULL,fontstruct,1);
  1076         -	XUnloadFont(dpy,val.font);
  1077         -	XCloseDisplay(dpy);
  1078         -	return 0;
  1079         -}
  1080         -
  1081         -// vim: ts=4	
  1082         -

Deleted alopex.config.5.

     1         -'\" t
     2         -.\"     Title: alopex.config
     3         -.\"    Author: [Sam Stuewe]
     4         -.\"      Date: 2013-04-22
     5         -.\"    Manual: \ \&
     6         -.\"    Source: \ \& 2.0
     7         -.\"  Language: English
     8         -.\"
     9         -.TH "ALOPEX\&.CONFIG" "5" "2013-04-22" "\ \& 2\&.0" "\ \&"
    10         -.ie \n(.g .ds Aq \(aq
    11         -.el       .ds Aq '
    12         -.nh
    13         -.ad l
    14         -.\"
    15         -.\" <- Main Content ->
    16         -.SH "NAME"
    17         -alopex.config \- Configuration Options
    18         -.SH "SYNOPSIS"
    19         -.sp
    20         -alopex\&.config
    21         -.SH "DESCRIPTION"
    22         -.sp
    23         -A custom configuration for \fBalopex\fR can be placed at \fI$XDG_CONFIG_HOME/alopex/config.h\fR or \fI$HOME/.alopex_conf.h\fR\&. It is a C header file, editable with your favorite text editor\&. Once editing is finished, \fBalopex\fR must be (re)built using the custom configuration\&.
    24         -.SH "APPEARANCE SETTINGS"
    25         -.PP
    26         -font
    27         -.RS 4
    28         -An xfontsel value of a valid bitmap font to be used on the statusbar\&.
    29         -.RE
    30         -.PP
    31         -*tile_modes
    32         -.RS 4
    33         -Determines the default status, cycle order and availability of the tiling modes\&. The last value in the array should be \fINULL\fR\&. The first mode in the array will be the default mode when \fBalopex\fR starts\&; the order of the modes when cycling is determined by the order of the modes listed in the array\&. Removing a mode from the array effectively disables that mode's usage\&.
    34         -.RE
    35         -.PP
    36         -tagcons
    37         -.RS 4
    38         -Determines the appearance of tags on the statusbar\&. Each sub-array is made up of three values\&: a text prefix, an icon and a text suffix\&. Each text affix must be quoted, the icon should not be\&. Replacing either text affix with \fINULL\fR (not quoted), will result in the replaced string not appearing\&. Replacing an icon identifier with \fI-1\fR or \fINO_ICON\fR will result in no icon being displayed\&. See \fBalopex\&.icons\fR(5) for more information\&.
    39         -.RE
    40         -.PP
    41         -alopex_cursor
    42         -.RS 4
    43         -The X11 cursor designated for \fBalopex\fR to render\&. (Defaults to \fIXC_left_ptr\fR)
    44         -.RE
    45         -.PP
    46         -borderwidth
    47         -.RS 4
    48         -Width of a border to be drawn around each window\&. Setting to 0 results in no border being drawn\&. (Defaults to 0)
    49         -.RE
    50         -.PP
    51         -tilegap
    52         -.RS 4
    53         -Toggles the "seemless tab mode"\&. Values above 0 will enable the use of nicer\-looking tabs with a gap between statusbar and the windows\&. (Defaults to 0)
    54         -.RE
    55         -.PP
    56         -tagspace
    57         -.RS 4
    58         -Sets the minimum space on the left of the statusbar of which the master tab will stay to the right\&. 0 will keep the master tab flush with the right\-most displayed tag\&. (Defaults to 0)
    59         -.RE
    60         -.PP
    61         -max_status_line
    62         -.RS 4
    63         -The maximum input length you might feed to the stdin reader\&. (Defaults to 256)
    64         -.RE
    65         -.PP
    66         -win_min
    67         -.RS 4
    68         -The smallest allowable width or height of a window\&. This effects the increasing and decreasing of \fItilebias\fR and can protect windows from being "crushed" when too many are open\&. (Defaults to 20)
    69         -.RE
    70         -.PP
    71         -focusfollowmouse
    72         -.RS 4
    73         -Whether window focus can be grabbed by mouse\-movement\&. (Defaults to False)
    74         -.RE
    75         -.PP
    76         -showbar
    77         -.RS 4
    78         -Whether the statusbar should be displayed\&. (Defaults to True)
    79         -.RE
    80         -.PP
    81         -topbar
    82         -.RS 4
    83         -Whether or not the statusbar should be displayed at the top or bottom of the screen\&. True displays the bar at the top\&; False displays the bar at the bottom\&. (Defaults to True)
    84         -.RE
    85         -.PP
    86         -tilebias
    87         -.RS 4
    88         -The number of pixels that the master area will be increased in size at the expense of the same number of pixels being taken from the stack section\&. 0 leaves the two sections at parity\&. (Defaults to 0)
    89         -.RE
    90         -.PP
    91         -attachmode
    92         -.RS 4
    93         -Where new new windows will be placed when created\&. 0 places them at the master section\&; 1 places them at the top of the stack\&; 2 places them at the bottom of the stack\&. (Defaults to 0)
    94         -.RE
    95         -.PP
    96         -stackcount
    97         -.RS 4
    98         -How many windows can be visible in the stack region at a given time\&. (Defaults to 3)
    99         -.RE
   100         -.SH "BEHAVIORAL ARRAYS"
   101         -.PP
   102         -\fIKey\fR
   103         -.RS 4
   104         -Defines the available keybinds\&. Each keybind has four comma\-separated components\&: the modifier, the key, the function and the argument\&.
   105         -.sp
   106         -Four modifiers are defined by default, \fIKEY1\fR through \fIKEY4\fR (Super, Alternate, Control and Shift respectively)\&. Using multiple modifiers for a single keybind can be achieved by listing multiple modifiers separated by \&|s\&. To omit the need for a modifier (useful for media keys), use 0 for the value of the modifier.
   107         -.sp
   108         -The key may be specified either by hex definition or by X11 Keysym\&. See \fBxev\fR(1) for more information on how to discover these values\&.
   109         -.sp
   110         -The following functions are available with an explanation of their accepted arguments\&:
   111         -.sp
   112         -.RS 4
   113         -spawn \- run a program
   114         -.RS 8
   115         -.nf
   116         -CMD("program \-flags \-\-switches arguments")
   117         -CMD(FUNCTION)
   118         -.fi
   119         -.RE
   120         -.sp
   121         -quit \- cleanly exit \fBalopex\fR
   122         -.RS 8
   123         -NULL
   124         -.RE
   125         -.sp
   126         -killclient \- kill the focused program
   127         -.RS 8
   128         -NULL
   129         -.RE
   130         -.sp
   131         -fullscreen \- toggle the focused client fullscreen
   132         -.RS 8
   133         -NULL
   134         -.RE
   135         -.sp
   136         -toggle
   137         -.RS 8
   138         -.nf
   139         -"floating"       \-\- toggle focused client to floating mode
   140         -"place bar"      \-\- toggle statusbar between the top and bottom
   141         -"visible bar"    \-\- toggle visibility of the statusbar
   142         -"monitor focus"  \-\- toggle focus between monitors
   143         -.fi
   144         -.RE
   145         -.sp
   146         -tile \- modify tile mode properties
   147         -.RS 8
   148         -.nf
   149         -"cycle"    \-\- cycle through available tiling layouts
   150         -"bstack"   \-\- switch to the bstack tiling layout
   151         -"rstack"   \-\- switch to the rstack tiling layout
   152         -"monocle"  \-\- switch to the monocle layout
   153         -.fi
   154         -.RE
   155         -.sp
   156         -tile_conf \- modify tiling appearance
   157         -.RS 8
   158         -.nf
   159         -"increase"  \-\- increment \fItilebias\fR in favor of the master section
   160         -"decrease"  \-\- increment \fItilebias\fR in favor of the stack
   161         -"+"         \-\- increase the number of visible windows in the stack
   162         -"-"         \-\- decrease the number of visible windows in the stack
   163         -"all"       \-\- make all windows in the stack section visible
   164         -"one"       \-\- only allow one window in the stack to be visible
   165         -.fi
   166         -.RE
   167         -.sp
   168         -tag \- perform tagging operations
   169         -.RS 8
   170         -"flip"  \-\- switch between views
   171         -.RE
   172         -.sp
   173         -window \- focus and move windows
   174         -.RS 8
   175         -.nf
   176         -"f prev"  \-\- focus previous
   177         -"f next"  \-\- focus next
   178         -"f alt"   \-\- focus alternate
   179         -"s prev"  \-\- swap window with previous
   180         -"s next"  \-\- swap window with next
   181         -"s alt"   \-\- swap window with alternate
   182         -"+"       \-\- Increase focused window's monitor identifier
   183         -"-"       \-\- Decrease focused window's monitor identifier
   184         -.fi
   185         -.sp
   186         -Capitalizing "Next" and "Prev" include floating windows
   187         -.RE
   188         -.RE
   189         -.sp
   190         -A special definition after the modifier masks efficiently defines keybinds for tagging operations\&. When calling this special function, two comma\-separated components must be specified\&: the key and the tag\&. They key is an X11 keysym, and the tag is the ordinal number of the tag in the \fItagcons\fR array with the first position being labeled "1"\&.
   191         -.sp
   192         -Unlike other keybind declarations, \fITagKey\fR declarations are not surrounded by brackets ('{' and '}'), they are called in the following manner\&:
   193         -.RS 4
   194         -.sp
   195         -TagKey(     KEYSYM,       TAGNUMBER     )
   196         -.RE
   197         -.sp
   198         -There should be one declaration for each tag in the \fItagcons\fR array\&.
   199         -.RE
   200         -.RE
   201         -.RE
   202         -.PP
   203         -\fIButton\fR
   204         -.RS 4
   205         -Defines actions to be bound to mouse buttons\&. As with the \fIKey\fR array, it is made up of four comma\-separated components\&: the modifier, the button, the function and the argument\&.
   206         -.sp
   207         -All four pre\-defined modifiers are accepted\&. The button is specified by numeral only \fI1\fR through \fI7\fR, by defalt\&. All functions and arguments from the \fIKey\fR array are available plus one additional function\&:
   208         -.RS 4
   209         -.sp
   210         -mouse
   211         -.RS 8
   212         -.nf
   213         -"move"    \-\- drag window
   214         -"resize"  \-\- resize window
   215         -.fi
   216         -.RE
   217         -.RE
   218         -.RE
   219         -.sp
   220         -.PP
   221         -\fIRule\fR
   222         -.RS 4
   223         -Defines window management rules\&. This array is made up of four comma\-separated components\&: the name, the class, tags and flags\&.
   224         -.sp
   225         -The name and class refer to X11's values of \fBresource name\fR and \fBresource class\fR from \fIWM_CLASS\fR\&. To determine their values, see \fBxprop\fR(1)\&. Either name or class may be replaced by NULL to ignore their values\&. If both are specified, then the rule will only be applied in cases where both values match\&.
   226         -.sp
   227         -The tags allow the user to specify windows which match the name and class conditions to be automatically assigned given tags\&.
   228         -.sp
   229         -.RS 4
   230         -These tag declarations are sets of 16 bits where each bit represents the client's assignment to a particular tag (0 meaning unassigned and 1 meaning assigned)\&. For example, if a window were to be assigned to tag 1, and another to be assigned to all 16 tags, they would be represented (in binary) as "0000000000000001" and "1111111111111111"\&. Because C cannot represent binary numbers, these two sequences can be represented in decimal, hex, bitwise-or statements or sums of powers of 2\&:
   231         -.sp
   232         -.nf
   233         -1           65535
   234         -0x0001      0xFFFF
   235         -(1<<0)      (1<<0) | (1<<1) ... (1<<15)
   236         -2^0         2^0 + 2^1 ... 2^15
   237         -.fi
   238         -.sp
   239         -To not assign tags to matched windows, use a value of 0\&.
   240         -.RE
   241         -.sp
   242         -The flags refer to special properties that can be assigned to windows for particular behaviors\&:
   243         -.RS 4
   244         -.sp
   245         -.nf
   246         -FLAG_FLOATING    \-\- force floating mode
   247         -FLAG_FULLSCREEN  \-\- force fullscreen mode
   248         -FLAG_URG_HINT    \-\- give window urgent status upon opening
   249         -.fi
   250         -.sp
   251         -To not assign any special properties, use 0\&.
   252         -.RE
   253         -.RE
   254         -.SH "FUNCTION DEFINITIONS"
   255         -.PP
   256         -\fIXRANDR_CMD\fR
   257         -.RS 4
   258         -The command to use for managing external monitors\&. The default value is not sane for all setups\&; It must be customized for your setup to be functional\&. See \fBxrandr\fR(1) for more information\&.
   259         -.PP
   260         -.RE
   261         -\fIWALLPAPER\fR
   262         -.RS 4
   263         -An optional command to be run in concert with \fIXRANDR_CMD\fR to keep the wallpaper looking clean even through managing external displays\&.
   264         -.RE
   265         -.PP
   266         -\fIPer-User\fR
   267         -.RS 4
   268         -.sp
   269         -#define FUNCTION    "command -flags --switches arguments"
   270         -.sp
   271         -Using the above structure, you would be able to use \fICMD(FUNCTION)\fR as an argument for the \fIspawn\fR function in the \fIKey\fR array\&.
   272         -.RE
   273         -.SH "SPECIAL INCLUDES"
   274         -.PP
   275         -\fIKeysyms\fR
   276         -.RS 4
   277         -.sp
   278         -By including the following line, you will be able to use XF86 keysyms rather than just X11 keysyms\&:
   279         -.sp
   280         -.RS 4
   281         -#include <X11/XF86keysym.h>
   282         -.RE
   283         -.RE
   284         -.SH "SEE ALSO"
   285         -.sp
   286         -\fBalopex\fR(1) \fBalopex\&.icons\fR(5)

Deleted alopex.icons.5.

     1         -'\" t
     2         -.\"     Title: alopex.icons
     3         -.\"    Author: [Sam Stuewe]
     4         -.\"      Date: 2013-04-22
     5         -.\"    Manual: \ \&
     6         -.\"    Source: \ \& 2.0
     7         -.\"  Language: English
     8         -.\"
     9         -.TH "ALOPEX\&.ICONS" "5" "2013-04-22" "\ \& 2\&.0" "\ \&"
    10         -.ie \n(.g .ds Aq \(aq
    11         -.el       .ds Aq '
    12         -.nh
    13         -.ad l
    14         -.\"
    15         -.\" <- Main Content ->
    16         -.SH "NAME"
    17         -alopex.icons \- Custom Iconsets
    18         -.SH "SYNOPSIS"
    19         -.sp
    20         -alopex\&.icons
    21         -.SH "DESCRIPTION"
    22         -.sp
    23         -A custom iconset for \fBalopex\fR can be placed at \fI$XDG_CONFIG_HOME/alopex/icons.h\fR or \fI$HOME/.alopex_icons.h\fR\&. It is a C header file, editable with your favorite text editor\&. Once editing is finished, \fBalopex\fR must be (re)built using the custom iconset\&.
    24         -.SH "SETTINGS"
    25         -.PP
    26         -By default, icons are 10 pixels by 10 pixels\&. However, this can easily be changed by modifying the following values\&:
    27         -.sp
    28         -.RS 4
    29         -.nf
    30         -iconwidth
    31         -iconheight
    32         -.fi
    33         -.RE
    34         -.SH "DECLARATIONS"
    35         -.PP
    36         -Each icon is defined separately in an array which specifies which pixels will be rendered as active which will not\&. This array is made up of a set of sub\-arrays\&. Each sub\-array is a coordinate pair of active pixels\&. A template icon is provided that, if used, would be a solid 10 by 10 square block\&. This template can easily be copied and modified\&.
    37         -.SH "ORDER"
    38         -.PP
    39         -At the bottom of the icons\&.h file, the \fIIcon\fR array establishes the ordinal designation of each icon and which icons are available\&. These designations are made in the following manner\&:
    40         -.RS 4
    41         -.sp
    42         -[#]     = MAKE_ICON(icon_name),
    43         -.sp
    44         -# refers to the ordinal designation, and, of course, icon_name refers to the name given to the specific icon array\&.
    45         -.RE
    46         -.SH "SEE ALSO"
    47         -.sp
    48         -\fBalopex\fR(1) \fBalopex\&.config\fR(5)

Deleted config.h.

     1         -/* copyright J.McClure 2012-2013, see alopex.c or COPYING for details */
     2         -
     3         -
     4         -static const char font[] =
     5         -	"-misc-fixed-medium-r-normal--13-120-75-75-c-70-*-*";
     6         -static const char *tile_modes[] =
     7         -	{"rstack", "bstack","monocle", NULL};
     8         -
     9         -/* each tagcon entry defines and icon and/or a name for each tag.
    10         -   You may use any combination of entries for any tags including
    11         -   using names (pre/post) for some, icons for others, and both for
    12         -   yet others.  Technically you can have usable tags without any
    13         -   indicator text or icon, which may not have practical purpose
    14         -   other than "hiding" client windows.  For no icon use NO_ICON
    15         -   or a -1, for no text use NULL. */
    16         -static const Tagcon tagcons[] = {
    17         -	/* pre		icon		post */
    18         -	{ NULL,		20,			"one"},
    19         -	{ NULL,		21,			"two" },
    20         -	{ NULL,		22,			"three" },
    21         -	{ "4:",		NO_ICON,	"four" },
    22         -	{ "5:",		NO_ICON,	"five" },
    23         -	{ "6:",		NO_ICON,	"six" },
    24         -};
    25         -
    26         -static const char	alopex_cursor		= XC_left_ptr;
    27         -static const int	borderwidth			= 0;
    28         -/* set gap between the windows */
    29         -static const int	tilegap				= 0;
    30         -/* set a minimum space on the left of the bar that the master tab will
    31         -   stay to the right of.  Setting to zero will keep the master tab flush
    32         -   against the last displayed tag name */
    33         -static const int	tagspace			= 0;
    34         -/* set to the maximum input you might feed to the stdin reader */
    35         -static const int	max_status_line		= 256;
    36         -/* smallest allowable width or height for a window
    37         -   This effects increasing and decreasing the tilebias, and can protect
    38         -   windows from getting completely "crushed" when too many are opened
    39         -   in rstack/bstack modes */
    40         -static const int	win_min				= 20;
    41         -static const Bool	focusfollowmouse	= False;
    42         -static Bool			showbar				= True;
    43         -static Bool			topbar				= True;
    44         -/* tilebias is set as a number of pixels to increase the master (and thus
    45         -   decrease the stack) from half the screen width.  Zero means the two will
    46         -   share the screen equally. */
    47         -static int			tilebias			= 0;
    48         -/* attachmode determines where new windows will be placed.
    49         -   0 = master, 1 = aside (top of stack), 2 = bottom */
    50         -static const int	attachmode			= 0;
    51         -/* stackcount sets how many clients can me visible in the stack region.
    52         -   For "ttwm" tiling mode, set stackcount to 1.  The value can be changed
    53         -   via a key binding (default Mod+ or Mod-). */
    54         -static int			stackcount			= 3;
    55         -/* Workaround for SDL games: set to true if you only ever use one
    56         -   monitor or otherwise want alopex to ignore any reconfigurations of
    57         -   the root window.  */
    58         -static Bool			ignore_root_resize	= False;
    59         -
    60         -#define DMENU		"dmenu_run -fn \"-misc-fixed-medium-r-normal--13-120-75-75-c-70-*-*\" -nb \"#101010\" -nf \"#484862\" -sb \"#080808\" -sf \"#FFDD0E\""
    61         -
    62         -#ifdef THEME_NAME
    63         -#define TERM		"urxvt -name " THEME_NAME
    64         -#else
    65         -#define TERM		"urxvt" 		/* or "urxvtc","xterm","terminator",etc */
    66         -#endif
    67         -
    68         -#define CMD(app)	app "&"
    69         -
    70         -/* these are just examples - be sure to edit for your setup.
    71         -   Uncomment and define WALLPAPER suitably to have the wallpaper */
    72         -
    73         -#define XRANDR_CMD		"xrandr --output LVDS1 --auto --output VGA1 --auto --left-of LVDS1"
    74         -//#define WALLPAPER		"feh --bg-scale ~/images/bg.jpg"
    75         -
    76         -/* key definitions */
    77         -#define KEY1 Mod4Mask
    78         -#define KEY2 Mod1Mask
    79         -#define KEY3 ControlMask
    80         -#define KEY4 ShiftMask
    81         -#define TagKey(KEY,TAG) \
    82         -	{ KEY1,				KEY,		tag,	"s " TAG }, \
    83         -	{ KEY1|KEY2,		KEY,		tag,	"t " TAG }, \
    84         -	{ KEY1|KEY3,		KEY,		tag,	"m " TAG }, \
    85         -	{ KEY1|KEY4,		KEY,		tag,	"a " TAG },
    86         -
    87         -static Key keys[] = {
    88         -	/* modifier			key			function	argument */
    89         -	/* launchers + misc: */
    90         -	{ KEY1,				XK_Return,	spawn,		CMD(TERM)		},
    91         -	{ KEY1,				XK_p,		spawn,		CMD(DMENU)		},
    92         -	{ KEY1,				XK_w,		spawn,		CMD("luakit")	},
    93         -	{ KEY1|KEY4,		XK_q,		quit,		NULL			},
    94         -	{ KEY2,				XK_F4,		killclient,	NULL			},
    95         -	{ KEY1,				XK_f,		fullscreen,	NULL			},
    96         -	{ KEY1,				XK_Menu,	windowlist,	"interrobang alopex"},
    97         -	{ KEY1|KEY2,		XK_f,		toggle,		"floating"		},
    98         -	{ KEY1|KEY2,		XK_r,		toggle,		"root resize"	},
    99         -	{ KEY1,				XK_x,		toggle,		"place bar"		},
   100         -	{ KEY1,				XK_a,		toggle,		"visible bar"	},
   101         -	{ 0,				0x1008ff59,	spawn,		XRANDR_CMD		},
   102         -	/* tiling:
   103         -		tile modes, increase/decrease master region size,
   104         -		increment or decrement (+/-) the number of stack clients,
   105         -		select for all or one ("ttwm tiling") stack clients */
   106         -	{ KEY1,				XK_space,	tile,		"cycle"			},
   107         -	{ KEY1,				XK_b,		tile,		"bstack"		},
   108         -	{ KEY1,				XK_r,		tile,		"rstack"		},
   109         -	{ KEY1,				XK_m,		tile,		"monocle"		},
   110         -	{ KEY1,				XK_i,		tile_conf,	"increase"		},
   111         -	{ KEY1,				XK_d,		tile_conf,	"decrease"		},
   112         -	{ KEY1,				XK_equal,	tile_conf,	"+"				},
   113         -	{ KEY1,				XK_minus,	tile_conf,	"-"				},
   114         -	{ KEY1,				XK_period,	tile_conf,	"all"			},
   115         -	{ KEY1,				XK_comma,	tile_conf,	"one"			},
   116         -	/* tagging:
   117         -		flip between alternate views, set tags */
   118         -	{ KEY2,				XK_Tab,		tag,		"flip"			},
   119         -		TagKey(			XK_1,					"1"		)
   120         -		TagKey(			XK_2,					"2"		)
   121         -		TagKey(			XK_3,					"3"		)
   122         -		TagKey(			XK_4,					"4"		)
   123         -		TagKey(			XK_5,					"5"		)
   124         -		TagKey(			XK_6,					"6"		)
   125         -	/* window focus/movement:
   126         -		f=focus previous, next, or alternate  window in tag(s)
   127         -		s=swap window with previous, next, or alternate  window
   128         -		capital "Next" or "Prev" include floating windows
   129         -		+/- adjust a windows monitor number */
   130         -	{ KEY1,				XK_k,		window,		"f prev"		},
   131         -	{ KEY1,				XK_j,		window,		"f next"		},
   132         -	{ KEY1|KEY4,		XK_k,		window,		"f Prev"		},
   133         -	{ KEY1|KEY4,		XK_j,		window,		"f Next"		},
   134         -	{ KEY1,				XK_Left,	window,		"f prev"		},
   135         -	{ KEY1,				XK_Right,	window,		"f next"		},
   136         -	{ KEY1,				XK_h,		window,		"s prev"		},
   137         -	{ KEY1,				XK_l,		window,		"s next"		},
   138         -	{ KEY1,				XK_Up,		window,		"s prev"		},
   139         -	{ KEY1,				XK_Down,	window,		"s next"		},
   140         -	{ KEY1,				XK_Tab,		window,		"f alt"			},
   141         -	{ KEY1|KEY4,		XK_Tab,		window,		"s alt"			},
   142         -	{ KEY1|KEY4,		XK_equal,	window,		"+"				},
   143         -	{ KEY1|KEY4,		XK_minus,	window,		"-"				},
   144         -	{ KEY1|KEY4,		XK_space,	toggle,		"monitor focus"	},
   145         -};
   146         -
   147         -static Button buttons[] = {
   148         -	/* modifier			button		function 	arg */
   149         -	{ KEY1,				1,			mouse,		"move"		},
   150         -	{ KEY1,				2,			toggle,		"floating"	},
   151         -	{ KEY1,				3,			mouse,		"resize"	},
   152         -	{ KEY1,				4,			window,		"s prev"	},
   153         -	{ KEY1,				5,			window,		"s next"	},
   154         -	{ KEY1,				6,			window,		"f prev"	},
   155         -	{ KEY1,				7,			window,		"f next"	},
   156         -};
   157         -
   158         -static Rule rules[] = {
   159         -	/* name				class		tags		flags */
   160         -	/* tags/flags=0 means no change to default */
   161         -	{ NULL,				"float",	0,			FLAG_FLOATING },
   162         -	{ "float",			NULL,		0,			FLAG_FLOATING },
   163         -};
   164         -
   165         -// vim: ts=4

Added doc/alopex-1.tex.

            1  +\documentclass{latex2man}
            2  +
            3  +\begin{Name}{1}{alopex}{Jesse McClure}{window manager}{Alopex - A Tabbed, Tiling Window Manager with Fur}
            4  +
            5  +\Prog{Alopex} - A Tabbed, Tiling Window Manager with Fur
            6  +
            7  +\end{Name}
            8  +
            9  +\section{Synopsis}
           10  +xinit alopex \oArg{theme}
           11  +
           12  +\section{Description}
           13  +
           14  +\Prog{Alopex} is a dynamic tiling window manager with a container
           15  +concept inspired by i3 but implemented quite differently.  Client
           16  +windows are not statically assigned to a given container, instead,
           17  +containers each have a configurable maximum number of clients, and
           18  +clients fill each container in sequence.  Within containers, multiple
           19  +clients are displayed as tabs.
           20  +
           21  +There are three container layouts: rstack, bstack, and
           22  +monocle.  Stack modes divide the screen into two sections, the master
           23  +region and the stack.  Monocle uses the full area for one container.
           24  +All layouts stack clients within containers displaying a tab for each
           25  +client in the container's title bar.  These layouts are supplimented by
           26  +per-client floating and full-screen modes.
           27  +
           28  +\Prog{Alopex} uses a tag concept rather than the more common
           29  +workspace/desktop metaphor.  The default configuration, however, is
           30  +optimized for a workspace-like work flow.  This can be modified as
           31  +desired.
           32  +
           33  +\section{Configuration}
           34  +
           35  +Configuration is implemented via an X resources data base file which is
           36  +read on startup.  A well-commented example configuration file is
           37  +distributed with \Prog{alopex} and can be found at
           38  +\File{/usr/share/alopex/config}.  Further information on customizing and
           39  +configuring alopex can be found on the github wiki.
           40  +
           41  +
           42  +\section{Status Input}
           43  +
           44  +A child process specified in the configuration file can be launched to
           45  +provide status input to be displayed along side the tabs in containers'
           46  +bars.  This child process should send text information to its standard
           47  +output which will then be read in by \Prog{alopex}.
           48  +
           49  +Each line must contain three ampersands which delineate four text
           50  +segments.  The first two segments are always displayed in the first
           51  +container's bar: the first before the tag indicators, the second
           52  +immediately after the tag indicators.  The third segment is displayed at
           53  +the right side of the second container's bar (or the right of the first
           54  +container if there is only one visible).  The fourth segment is
           55  +displayed at the right side of the last visible container.
           56  +
           57  +Plain text is printed as-is into the above-specified status bar region.
           58  +Text within curly-braces is interpreted as a special command.  These
           59  +commands can specify a foreground color, set a font, display an icon
           60  +or paint the foreground color with an icon mask.
           61  +
           62  +\subsection{Status Commands}
           63  +
           64  +\begin{description}
           65  +\item[\Opt{R G B A}]
           66  +	Set color with Red Green Blue and Alpha values specified as floating
           67  +	point numbers from 0 to 1
           68  +\item[\OptArg{i}{#}]
           69  +	Draw icon number # in full color
           70  +\item[\OptArg{I}{#}]
           71  +	Use icon number # as mask for the currently selected color
           72  +\item[\Opt{f}]
           73  +	Select default font
           74  +\item[\Opt{F}]
           75  +	Select bold font
           76  +
           77  +\section{Author}
           78  +Copyright \copyright 2012-2014 Jesse McClure \\
           79  +License GPLv3: GNU GPL version 3 \URL{http://gnu.org/licenses/gpl.html} \\
           80  +This is free software: you are free to change and redistribute it. \\
           81  +There is NO WARRANTY, to the extent permitted by law.
           82  +
           83  +Submit bug reports via github: \\
           84  +\URL{http://github/com/TrilbyWhite/alopex.git}
           85  +
           86  +I would like your feedback.  If you enjoy \Prog{Alopex} see the bottom
           87  +of the site below for detauls on submitting comments: \\
           88  +\URL{http://mccluresk9.com/software.html}
           89  +
           90  +Documentation added and edited collaboratively by Jesse McClure and Sam
           91  +Stuewe.  Any concerns or comments regarding documentation may be
           92  +submitted to \Email{halosghost@archlinux.info}.
           93  +
           94  +\section{See Also}
           95  +The most up to date documentation can be found at
           96  +\URL{https://github.com/TrilbyWhite/alopex/wiki}
           97  +
           98  +\LatexManEnd

Added doc/alopex.1.

            1  +'\" t
            2  +.\" Manual page created with latex2man on Thu Mar 20 14:23:46 EDT 2014
            3  +.\" NOTE: This file is generated, DO NOT EDIT.
            4  +.de Vb
            5  +.ft CW
            6  +.nf
            7  +..
            8  +.de Ve
            9  +.ft R
           10  +
           11  +.fi
           12  +..
           13  +.TH "ALOPEX" "1" "20 March 2014" "window manager " "window manager "
           14  +.SH NAME
           15  +
           16  +.PP
           17  +Alopex
           18  +\- A Tabbed, Tiling Window Manager with Fur 
           19  +.PP
           20  +.SH SYNOPSIS
           21  +
           22  +xinit alopex [\fItheme\fP]
           23  +.PP
           24  +.SH DESCRIPTION
           25  +
           26  +.PP
           27  +Alopex
           28  +is a dynamic tiling window manager with a container 
           29  +concept inspired by i3 but implemented quite differently. Client 
           30  +windows are not statically assigned to a given container, instead, 
           31  +containers each have a configurable maximum number of clients, and 
           32  +clients fill each container in sequence. Within containers, multiple 
           33  +clients are displayed as tabs. 
           34  +.PP
           35  +There are three container layouts: rstack, bstack, and 
           36  +monocle. Stack modes divide the screen into two sections, the master 
           37  +region and the stack. Monocle uses the full area for one container. 
           38  +All layouts stack clients within containers displaying a tab for each 
           39  +client in the container\&'s title bar. These layouts are supplimented by 
           40  +per\-client floating and full\-screen modes. 
           41  +.PP
           42  +Alopex
           43  +uses a tag concept rather than the more common 
           44  +workspace/desktop metaphor. The default configuration, however, is 
           45  +optimized for a workspace\-like work flow. This can be modified as 
           46  +desired. 
           47  +.PP
           48  +.SH CONFIGURATION
           49  +
           50  +.PP
           51  +Configuration is implemented via an X resources data base file which is 
           52  +read on startup. A well\-commented example configuration file is 
           53  +distributed with alopex
           54  +and can be found at 
           55  +/usr/share/alopex/config\&.
           56  +Further information on customizing and 
           57  +configuring alopex can be found on the github wiki. 
           58  +.PP
           59  +.SH STATUS INPUT
           60  +
           61  +.PP
           62  +A child process specified in the configuration file can be launched to 
           63  +provide status input to be displayed along side the tabs in containers\&' 
           64  +bars. This child process should send text information to its standard 
           65  +output which will then be read in by alopex\&.
           66  +.PP
           67  +Each line must contain three ampersands which delineate four text 
           68  +segments. The first two segments are always displayed in the first 
           69  +container\&'s bar: the first before the tag indicators, the second 
           70  +immediately after the tag indicators. The third segment is displayed at 
           71  +the right side of the second container\&'s bar (or the right of the first 
           72  +container if there is only one visible). The fourth segment is 
           73  +displayed at the right side of the last visible container. 
           74  +.PP
           75  +Plain text is printed as\-is into the above\-specified status bar region. 
           76  +Text within curly\-braces is interpreted as a special command. These 
           77  +commands can specify a foreground color, set a font, display an icon 
           78  +or paint the foreground color with an icon mask. 
           79  +.PP
           80  +.SS STATUS COMMANDS
           81  +.PP
           82  +.TP
           83  +\fBR G B A\fP
           84  + Set color with Red Green Blue and Alpha values specified as floating 
           85  +point numbers from 0 to 1 
           86  +.TP
           87  +\fBi\fP\fI#\fP
           88  + Draw icon number # in full color 
           89  +.TP
           90  +\fBI\fP\fI#\fP
           91  + Use icon number # as mask for the currently selected color 
           92  +.TP
           93  +\fBf\fP
           94  + Select default font 
           95  +.TP
           96  +\fBF\fP
           97  + Select bold font 
           98  +.PP
           99  +.SH AUTHOR
          100  +
          101  +Copyright (C)2012\-2014 Jesse McClure 
          102  +.br
          103  +License GPLv3: GNU GPL version 3 \fBhttp://gnu.org/licenses/gpl.html\fP
          104  +.br
          105  +This is free software: you are free to change and redistribute it. 
          106  +.br
          107  +There is NO WARRANTY, to the extent permitted by law. 
          108  +.PP
          109  +Submit bug reports via github: 
          110  +.br
          111  +\fBhttp://github/com/TrilbyWhite/alopex.git\fP
          112  +.PP
          113  +I would like your feedback. If you enjoy Alopex
          114  +see the bottom 
          115  +of the site below for detauls on submitting comments: 
          116  +.br
          117  +\fBhttp://mccluresk9.com/software.html\fP
          118  +.PP
          119  +Documentation added and edited collaboratively by Jesse McClure and Sam 
          120  +Stuewe. Any concerns or comments regarding documentation may be 
          121  +submitted to \fBhalosghost@archlinux.info\fP\&.
          122  +.PP
          123  +.SH SEE ALSO
          124  +
          125  +The most up to date documentation can be found at 
          126  +\fBhttps://github.com/TrilbyWhite/alopex/wiki\fP
          127  +.PP
          128  +.\" NOTE: This file is generated, DO NOT EDIT.

Deleted icons.h.

     1         -/* ICONS.H
     2         -   default icon set for alopex. Icon art contributions by github users:
     3         -     UnderCooled
     4         -	 HalosGhost
     5         -*/
     6         -
     7         -#ifndef __ALOPEX_ICONS_H__
     8         -#define __ALOPEX_ICONS_H__		"ALOPEX Icons 0.9"
     9         -
    10         -#define MAKE_ICON(x)	{ (sizeof(x)/sizeof(x[0])), (XPoint *) x }
    11         -
    12         -static const int iconwidth = 10;
    13         -static const int iconheight = 10;
    14         -
    15         -typedef struct Icon {
    16         -	int n;
    17         -	XPoint *pts;
    18         -} Icon;
    19         -
    20         -/*
    21         -static const XPoint template_icon[] = {
    22         -	{0,0},	{1,0},	{2,0},	{3,0},	{4,0},	{5,0},	{6,0},	{7,0},	{8,0},	{9,0},
    23         -	{0,1},	{1,1},	{2,1},	{3,1},	{4,1},	{5,1},	{6,1},	{7,1},	{8,1},	{9,1},
    24         -	{0,2},	{1,2},	{2,2},	{3,2},	{4,2},	{5,2},	{6,2},	{7,2},	{8,2},	{9,2},
    25         -	{0,3},	{1,3},	{2,3},	{3,3},	{4,3},	{5,3},	{6,3},	{7,3},	{8,3},	{9,3},
    26         -	{0,4},	{1,4},	{2,4},	{3,4},	{4,4},	{5,4},	{6,4},	{7,4},	{8,4},	{9,4},
    27         -	{0,5},	{1,5},	{2,5},	{3,5},	{4,5},	{5,5},	{6,5},	{7,5},	{8,5},	{9,5},
    28         -	{0,6},	{1,6},	{2,6},	{3,6},	{4,6},	{5,6},	{6,6},	{7,6},	{8,6},	{9,6},
    29         -	{0,7},	{1,7},	{2,7},	{3,7},	{4,7},	{5,7},	{6,7},	{7,7},	{8,7},	{9,7},
    30         -	{0,8},	{1,8},	{2,8},	{3,8},	{4,8},	{5,8},	{6,8},	{7,8},	{8,8},	{9,8},
    31         -	{0,9},	{1,9},	{2,9},	{3,9},	{4,9},	{5,9},	{6,9},	{7,9},	{8,9},	{9,9},
    32         -};
    33         -*/
    34         -
    35         -static const XPoint clock_icon[] = {
    36         -							{3,0},	{4,0},	{5,0},	{6,0},
    37         -					{2,1},									{7,1},
    38         -			{1,2},					{4,2},							{8,2},
    39         -	{0,3},							{4,3},									{9,3},
    40         -	{0,4},							{4,4},								 	{9,4},
    41         -	{0,5},							{4,5},	{5,5},	{6,5},	{7,5},			{9,5},
    42         -	{0,6},																	{9,6},
    43         -			{1,7},													{8,7},
    44         -					{2,8},									{7,8},
    45         -							{3,9},	{4,9},	{5,9},	{6,9},
    46         -};
    47         -
    48         -static const XPoint cpu_icon[] = {
    49         -	{0,0},	{1,0},	{2,0},	{3,0},	{4,0},	{5,0},	{6,0},	{7,0},	{8,0},	{9,0},
    50         -	{0,1},																	{9,1},
    51         -	{0,2},					{3,2},	{4,2},	{5,2},	{6,2},					{9,2},
    52         -	{0,3},					{3,3},					{6,3},					{9,3},
    53         -	{0,4},					{3,4},			{5,4},	{6,4},					{9,4},
    54         -	{0,5},					{3,5},	{4,5},	{5,5},	{6,5},					{9,5},
    55         -	{0,6},					{3,6},	{4,6},	{5,6},	{6,6},					{9,6},
    56         -	{0,7},																	{9,7},
    57         -	{0,8},	{1,8},	{2,8},	{3,8},	{4,8},	{5,8},	{6,8},	{7,8},	{8,8},	{9,8},
    58         -	{0,9},			{2,9},			{4,9},			{6,9},			{8,9},
    59         -};
    60         -
    61         -static const XPoint mem_icon[] = {
    62         -			{1,0},	{2,0},	{3,0},	{4,0},	{5,0},	{6,0},	{7,0},	{8,0},
    63         -	{0,1},																	{9,1},
    64         -	{0,2},	{1,2},			{3,2},	{4,2},	{5,2},	{6,2},			{8,2},	{9,2},
    65         -	{0,3},					{3,3},	{4,3},	{5,3},	{6,3},					{9,3},
    66         -	{0,4},	{1,4},			{3,4},	{4,4},	{5,4},	{6,4},			{8,4},	{9,4},
    67         -	{0,5},					{3,5},	{4,5},	{5,5},	{6,5},					{9,5},
    68         -	{0,6},	{1,6},			{3,6},	{4,6},	{5,6},	{6,6},			{8,6},	{9,6},
    69         -	{0,7},																	{9,7},
    70         -	{0,8},	{1,8},	{2,8},	{3,8},	{4,8},	{5,8},	{6,8},	{7,8},	{8,8},	{9,8},
    71         -	{0,9},																	{9,9},
    72         -};
    73         -
    74         -static const XPoint speaker_hi_icon[] = {
    75         -									{4,0},			{6,0},
    76         -							{3,1},	{4,1},					{7,1},
    77         -					{2,2},	{3,2},	{4,2},							{8,2},
    78         -	{0,3},	{1,3},	{2,3},	{3,3},	{4,3},			{6,3},					{9,3},
    79         -	{0,4},	{1,4},	{2,4},	{3,4},	{4,4},					{7,4},			{9,4},
    80         -	{0,5},	{1,5},	{2,5},	{3,5},	{4,5},					{7,5},			{9,5},
    81         -	{0,6},	{1,6},	{2,6},	{3,6},	{4,6},			{6,6},					{9,6},
    82         -					{2,7},	{3,7},	{4,7},							{8,7},
    83         -							{3,8},	{4,8},					{7,8},
    84         -									{4,9},			{6,9},
    85         -};
    86         -
    87         -static const XPoint speaker_mid_icon[] = {
    88         -									{4,0},
    89         -							{3,1},	{4,1},			{6,1},
    90         -					{2,2},	{3,2},	{4,2},					{7,2},
    91         -	{0,3},	{1,3},	{2,3},	{3,3},	{4,3},							{8,3},
    92         -	{0,4},	{1,4},	{2,4},	{3,4},	{4,4},							{8,4},
    93         -	{0,5},	{1,5},	{2,5},	{3,5},	{4,5},							{8,5},
    94         -	{0,6},	{1,6},	{2,6},	{3,6},	{4,6},							{8,6},
    95         -					{2,7},	{3,7},	{4,7},					{7,7},
    96         -							{3,8},	{4,8},			{6,8},
    97         -									{4,9},			
    98         -};
    99         -
   100         -static const XPoint speaker_low_icon[] = {
   101         -									{4,0},
   102         -							{3,1},	{4,1},
   103         -					{2,2},	{3,2},	{4,2},
   104         -	{0,3},	{1,3},	{2,3},	{3,3},	{4,3},
   105         -	{0,4},	{1,4},	{2,4},	{3,4},	{4,4},
   106         -	{0,5},	{1,5},	{2,5},	{3,5},	{4,5},
   107         -	{0,6},	{1,6},	{2,6},	{3,6},	{4,6},
   108         -					{2,7},	{3,7},	{4,7},
   109         -							{3,8},	{4,8},
   110         -									{4,9},			
   111         -};
   112         -
   113         -static const XPoint speaker_mute_icon[] = {
   114         -											{5,0},							{9,0},
   115         -							{3,1},			{5,1},							{9,1},
   116         -					{2,2},	{3,2},	{4,2},			{6,2},			{8,2},
   117         -	{0,3},	{1,3},	{2,3},	{3,3},	{4,3},			{6,3},			{8,3},
   118         -	{0,4},	{1,4},	{2,4},	{3,4},	{4,4},					{7,4},
   119         -	{0,5},	{1,5},	{2,5},	{3,5},	{4,5},					{7,5},	
   120         -	{0,6},	{1,6},	{2,6},	{3,6},	{4,6},			{6,6},			{8,6},
   121         -					{2,7},	{3,7},	{4,7},			{6,7},			{8,7},
   122         -							{3,8},			{5,8},							{9,8},
   123         -											{5,9},							{9,9},
   124         -};
   125         -
   126         -static const XPoint wifi_full_icon[] = {
   127         -													{8,0},	
   128         -										{6,1},		{8,1},	
   129         -							{4,2},		{6,2},		{8,2},	
   130         -				{2,3},		{4,3},		{6,3},		{8,3},	
   131         -	{0,4},		{2,4},		{4,4},		{6,4},		{8,4},	
   132         -  	{0,5},		{2,5},		{4,5},		{6,5},		{8,5},	
   133         -	{0,6},		{2,6},		{4,6},		{6,6},		{8,6},	
   134         -	{0,7},		{2,7},		{4,7},		{6,7},		{8,7},	
   135         -	{0,8},		{2,8},		{4,8},		{6,8},		{8,8},	
   136         -	{0,9},		{2,9},		{4,9},		{6,9},		{8,9},	
   137         -};
   138         -
   139         -static const XPoint wifi_hi_icon[] = {
   140         -													{8,0},	
   141         -													{8,1},	
   142         -										{6,2},		{8,2},	
   143         -										{6,3},		{8,3},	
   144         -							{4,4},		{6,4},		{8,4},	
   145         -  							{4,5},		{6,5},		{8,5},	
   146         -				{2,6},		{4,6},		{6,6},		{8,6},	
   147         -				{2,7},		{4,7},		{6,7},		{8,7},	
   148         -	{0,8},		{2,8},		{4,8},		{6,8},		{8,8},	
   149         -	{0,9},		{2,9},		{4,9},		{6,9},		{8,9},	
   150         -};
   151         -
   152         -static const XPoint wifi_mid_icon[] = {
   153         -													{8,1},	
   154         -													{8,2},	
   155         -										{6,3},		{8,3},	
   156         -										{6,4},		{8,4},	
   157         -							{4,5},		{6,5},		{8,5},	
   158         -  							{4,6},		{6,6},		{8,6},	
   159         -				{2,7},		{4,7},		{6,7},		{8,7},	
   160         -				{2,8},		{4,8},		{6,8},		{8,8},	
   161         -				{2,9},		{4,9},		{6,9},		{8,9},	
   162         -};
   163         -
   164         -static const XPoint wifi_low_icon[] = {
   165         -										{6,3},	
   166         -										{6,4},	
   167         -							{4,5},		{6,5},	
   168         -  							{4,6},		{6,6},	
   169         -				{2,7},		{4,7},		{6,7},	
   170         -				{2,8},		{4,8},		{6,8},	
   171         -				{2,9},		{4,9},		{6,9},	
   172         -};
   173         -
   174         -static const XPoint wifi_off_icon[] = {
   175         -							{4,7},		{6,7},	
   176         -  							{4,8},		{6,8},	
   177         -				{2,9},		{4,9},		{6,9},	
   178         -};
   179         -
   180         -static const XPoint mail_new_icon[] = {
   181         -			{1,0},	{2,0},	{3,0},	{4,0},	{5,0},	{6,0},	{7,0},	{8,0},
   182         -	{0,1},			{2,1},	{3,1},	{4,1},	{5,1},	{6,1},	{7,1},			{9,1},
   183         -	{0,2},					{3,2},	{4,2},	{5,2},	{6,2},					{9,2},
   184         -	{0,3},	{1,3},					{4,3},	{5,3},					{8,3},	{9,3},
   185         -	{0,4},	{1,4},	{2,4},									{7,4},	{8,4},	{9,4},
   186         -	{0,5},	{1,5},	{2,5},	{3,5},					{6,5},	{7,5},	{8,5},	{9,5},
   187         -	{0,6},	{1,6},	{2,6},	{3,6},	{4,6},	{5,6},	{6,6},	{7,6},	{8,6},	{9,6},
   188         -	{0,7},	{1,7},	{2,7},	{3,7},	{4,7},	{5,7},	{6,7},	{7,7},	{8,7},	{9,7},
   189         -	{0,8},	{1,8},	{2,8},	{3,8},	{4,8},	{5,8},	{6,8},	{7,8},	{8,8},	{9,8},
   190         -			{1,9},	{2,9},	{3,9},	{4,9},	{5,9},	{6,9},	{7,9},	{8,9},
   191         -};
   192         -
   193         -static const XPoint mail_none_icon[] = {
   194         -			{1,0},	{2,0},	{3,0},	{4,0},	{5,0},	{6,0},	{7,0},	{8,0},
   195         -	{0,1},																	{9,1},
   196         -	{0,2},																	{9,2},
   197         -	{0,3},			{2,3},									{7,3},			{9,3},
   198         -	{0,4},					{3,4},					{6,4},					{9,4},
   199         -	{0,5},							{4,5},	{5,5},							{9,5},
   200         -	{0,6},																	{9,6},
   201         -	{0,7},																	{9,7},
   202         -	{0,8},																	{9,8},
   203         -			{1,9},	{2,9},	{3,9},	{4,9},	{5,9},	{6,9},	{7,9},	{8,9},
   204         -};
   205         -
   206         -static const XPoint batt_full_icon[] = {
   207         -							{3,0},	{4,0},	{5,0},	{6,0},
   208         -	{0,1},	{1,1},	{2,1},	{3,1},					{6,1},	{7,1},	{8,1},	{9,1},
   209         -	{0,2},					{3,2},			{5,2},			{7,2},			{9,2},
   210         -	{0,3},			{2,3},			{4,3},			{6,3},					{9,3},
   211         -	{0,4},					{3,4},			{5,4},			{7,4},			{9,4},
   212         -	{0,5},			{2,5},			{4,5},			{6,5},					{9,5},
   213         -	{0,6},					{3,6},			{5,6},			{7,6},			{9,6},
   214         -	{0,7},			{2,7},			{4,7},			{6,7},					{9,7},
   215         -	{0,8},					{3,8},			{5,8},			{7,8},			{9,8},
   216         -			{1,9},	{2,9},	{3,9},	{4,9},	{5,9},	{6,9},	{7,9},	{8,9},
   217         -};
   218         -
   219         -static const XPoint batt_hi_icon[] = {
   220         -							{3,0},	{4,0},	{5,0},	{6,0},
   221         -	{0,1},	{1,1},	{2,1},	{3,1},					{6,1},	{7,1},	{8,1},	{9,1},
   222         -	{0,2},													{7,2},			{9,2},
   223         -	{0,3},											{6,3},					{9,3},
   224         -	{0,4},									{5,4},			{7,4},			{9,4},
   225         -	{0,5},							{4,5},			{6,5},					{9,5},
   226         -	{0,6},					{3,6},			{5,6},			{7,6},			{9,6},
   227         -	{0,7},			{2,7},			{4,7},			{6,7},					{9,7},
   228         -	{0,8},					{3,8},			{5,8},			{7,8},			{9,8},
   229         -			{1,9},	{2,9},	{3,9},	{4,9},	{5,9},	{6,9},	{7,9},	{8,9},
   230         -};
   231         -
   232         -static const XPoint batt_mid_icon[] = {
   233         -							{3,0},	{4,0},	{5,0},	{6,0},
   234         -	{0,1},	{1,1},	{2,1},	{3,1},					{6,1},	{7,1},	{8,1},	{9,1},
   235         -	{0,2},																	{9,2},
   236         -	{0,3},													{7,3},			{9,3},
   237         -	{0,4},											{6,4},					{9,4},
   238         -	{0,5},									{5,5},			{7,5},			{9,5},
   239         -	{0,6},							{4,6},			{6,6},					{9,6},
   240         -	{0,7},					{3,7},			{5,7},			{7,7},			{9,7},
   241         -	{0,8},			{2,8},			{4,8},			{6,8},					{9,8},
   242         -			{1,9},	{2,9},	{3,9},	{4,9},	{5,9},	{6,9},	{7,9},	{8,9},
   243         -};
   244         -
   245         -static const XPoint batt_low_icon[] = {
   246         -							{3,0},	{4,0},	{5,0},	{6,0},
   247         -	{0,1},	{1,1},	{2,1},	{3,1},					{6,1},	{7,1},	{8,1},	{9,1},
   248         -	{0,2},																	{9,2},
   249         -	{0,3},																	{9,3},
   250         -	{0,4},																	{9,4},
   251         -	{0,5},													{7,5},			{9,5},
   252         -	{0,6},											{6,6},					{9,6},
   253         -	{0,7},									{5,7},			{7,7},			{9,7},
   254         -	{0,8},							{4,8},			{6,8},					{9,8},
   255         -			{1,9},	{2,9},	{3,9},	{4,9},	{5,9},	{6,9},	{7,9},	{8,9},
   256         -};
   257         -
   258         -static const XPoint batt_zero_icon[] = {
   259         -							{3,0},	{4,0},	{5,0},	{6,0},
   260         -	{0,1},	{1,1},	{2,1},	{3,1},					{6,1},	{7,1},	{8,1},	{9,1},
   261         -	{0,2},																	{9,2},
   262         -	{0,3},																	{9,3},
   263         -	{0,4},																	{9,4},
   264         -	{0,5},																	{9,5},
   265         -	{0,6},																	{9,6},
   266         -	{0,7},																	{9,7},
   267         -	{0,8},																	{9,8},
   268         -			{1,9},	{2,9},	{3,9},	{4,9},	{5,9},	{6,9},	{7,9},	{8,9},
   269         -};
   270         -
   271         -static const XPoint batt_charge_icon[] = {
   272         -													{6,0},	{7,0},
   273         -											{5,1},	{6,1},
   274         -									{4,2},	{5,2},	
   275         -							{3,3},	{4,3},		
   276         -					{2,4},	{3,4},	{4,4},	{5,4},	{6,4},	{7,4},	{8,4},
   277         -			{1,5},	{2,5},	{3,5},	{4,5},	{5,5},	{6,5},	{7,5},
   278         -											{5,6},	{6,6},
   279         -									{4,7},	{5,7},
   280         -							{3,8},	{4,8},
   281         -					{2,9},	{3,9},
   282         -};
   283         -
   284         -static const XPoint arch_icon[] = {
   285         -									{4,0},	{5,0},
   286         -									{4,1},	{5,1},
   287         -							{3,2},	{4,2},	{5,2},	{6,2},
   288         -							{3,3},	{4,3},	{5,3},	{6,3},
   289         -					{2,4},	{3,4},	{4,4},	{5,4},	{6,4},	{7,4},
   290         -					{2,5},	{3,5},					{6,5},	{7,5},
   291         -			{1,6},	{2,6},	{3,6},					{6,6},	{7,6},	{8,6},
   292         -			{1,7},	{2,7},	{3,7},					{6,7},	{7,7},	{8,7},
   293         -	{0,8},	{1,8},	{2,8},									{7,8},	{8,8},	{9,8},
   294         -	{0,9},	{1,9},													{8,9},	{9,9},
   295         -};
   296         -
   297         -static const XPoint app_term[] = { 
   298         -   {0,0},   {1,0},   {2,0},   {3,0},   {4,0},   {5,0},   {6,0},   {7,0},   {8,0},   {9,0},
   299         -   {0,1},   {1,1},   {2,1},   {3,1},   {4,1},   {5,1},   {6,1},   {7,1},   {8,1},   {9,1},
   300         -   {0,2},                                                                           {9,2},
   301         -   {0,3},            {2,3},                                                         {9,3},
   302         -   {0,4},            {2,4},   {3,4},                                                {9,4},
   303         -   {0,5},                     {3,5},                                                {9,5},
   304         -   {0,6},            {2,6},   {3,6},                                                {9,6},
   305         -   {0,7},            {2,7},                     {5,7},   {6,7},   {7,7},            {9,7},
   306         -   {0,8},                                                                           {9,8},
   307         -   {0,9},   {1,9},   {2,9},   {3,9},   {4,9},   {5,9},   {6,9},   {7,9},   {8,9},   {9,9},
   308         -};
   309         -
   310         -static const XPoint app_web[] = { 
   311         -                     {2,0},   {3,0},   {4,0},   {5,0},            {7,0},
   312         -            {1,1},                     {4,1},   {5,1},                     {8,1},
   313         -   {0,2},   {1,2},                                                         {8,2},   {9,2},
   314         -   {0,3},                              {4,3},   {5,3},                              {9,3},
   315         -   {0,4},   {1,4},                     {4,4},   {5,4},                     {8,4},   {9,4},
   316         -            {1,5},                     {4,5},   {5,5},                     {8,5},
   317         -                     {2,6},            {4,6},   {5,6},   {6,6},   {7,6},
   318         -                                       {4,7},   {5,7},
   319         -                                       {4,8},   {5,8},
   320         -                                       {4,9},   {5,9},
   321         -};
   322         -
   323         -static const XPoint app_stats[] = { 
   324         -   {0,0},
   325         -   {0,1},
   326         -   {0,2},                     {3,2},
   327         -   {0,3},            {2,3},            {4,3},
   328         -   {0,4},            {2,4},                     {4,4},
   329         -   {0,5},   {1,5},                              {5,5},
   330         -   {0,6},   {1,6},                                    {5,6},   {6,6},
   331         -   {0,7},                                                         {7,7},
   332         -   {0,8},                                                                  {8,8},   {9,8},
   333         -   {0,9},   {1,9},   {2,9},   {3,9},   {4,9},   {5,9},   {6,9},   {7,9},   {8,9},   {9,9},
   334         -};
   335         -
   336         -static const XPoint app_docs[] = { 
   337         -            {1,0},   {2,0},   {3,0},   {4,0},   {5,0},
   338         -            {1,1},                                       {6,1},
   339         -            {1,2},                                                {7,2},
   340         -            {1,3},            {3,3},   {4,3},   {5,3},                     {8,3},
   341         -            {1,4},                                                         {8,4},
   342         -            {1,5},            {3,5},   {4,5},   {5,5},   {6,5},            {8,5},
   343         -            {1,6},                                                         {8,6},
   344         -            {1,7},            {3,7},   {4,7},   {5,7},   {6,7},            {8,7},
   345         -            {1,8},                                                         {8,8},
   346         -            {1,9},   {2,9},   {3,9},   {4,9},   {5,9},   {6,9},   {7,9},   {8,9},
   347         -};
   348         -
   349         -static const XPoint app_music[] = { 
   350         -                              {3,0},   {4,0},   {5,0},   {6,0},   {7,0},   {8,0},   {9,0},
   351         -                              {3,1},   {4,1},   {5,1},   {6,1},   {7,1},   {8,1},   {9,1},
   352         -                              {3,2},                                                {9,2},
   353         -                              {3,3},                                                {9,3},
   354         -                              {3,4},                                                {9,4},
   355         -            {1,5},   {2,5},   {3,5},                                                {9,5},
   356         -   {0,6},   {1,6},   {2,6},   {3,6},                              {7,6},   {8,6},   {9,6},
   357         -   {0,7},   {1,7},   {2,7},   {3,7},                     {6,7},   {7,7},   {8,7},   {9,7},
   358         -            {1,8},   {2,8},                              {6,8},   {7,8},   {8,8},   {9,8},
   359         -                                                                  {7,9},   {8,9},
   360         -};
   361         -
   362         -static const XPoint app_video[] = { 
   363         -   {0,0},            {2,0},                                       {7,0},            {9,0},
   364         -   {0,1},   {1,1},   {2,1},                                       {7,1},   {8,1},   {9,1},
   365         -   {0,2},            {2,2},   {3,2},   {4,2},   {5,2},   {6,2},   {7,2},            {9,2},
   366         -   {0,3},   {1,3},   {2,3},                                       {7,3},   {8,3},   {9,3},
   367         -   {0,4},            {2,4},                                       {7,4},            {9,4},
   368         -   {0,5},   {1,5},   {2,5},                                       {7,5},   {8,5},   {9,5},
   369         -   {0,6},            {2,6},                                       {7,6},            {9,6},
   370         -   {0,7},   {1,7},   {2,7},   {3,7},   {4,7},   {5,7},   {6,7},   {7,7},   {8,7},   {9,7},
   371         -   {0,8},            {2,8},                                       {7,8},            {9,8},
   372         -   {0,9},   {1,9},   {2,9},                                       {7,9},   {8,9},   {9,9},
   373         -};
   374         -
   375         -static const XPoint app_games[] = {
   376         -                     {2,0},   {3,0},   {4,0},   {5,0},   {6,0},   {7,0},
   377         -                     {2,1},                                       {7,1},
   378         -   {0,2},   {1,2},   {2,2},                                       {7,2},   {8,2},   {9,2},
   379         -   {0,3},                              {4,3},                                       {9,3},
   380         -   {0,4},                              {4,4},   {5,4},                              {9,4},
   381         -   {0,5},                              {4,5},   {5,5},                              {9,5},
   382         -   {0,6},                              {4,6},                                       {9,6},
   383         -   {0,7},   {1,7},   {2,7},                                       {7,7},   {8,7},   {9,7},
   384         -                     {2,8},                                       {7,8},
   385         -                     {2,9},   {3,9},   {4,9},   {5,9},   {6,9},   {7,9},
   386         -};
   387         -
   388         -static const XPoint app_images[] = { 
   389         -   {0,0},   {1,0},   {2,0},   {3,0},   {4,0},   {5,0},   {6,0},   {7,0},   {8,0},   {9,0},
   390         -   {0,1},                                                                           {9,1},
   391         -   {0,2},                                                                           {9,2},
   392         -   {0,3},                                                                           {9,3},
   393         -   {0,4},                                                                           {9,4},
   394         -   {0,5},            {2,5},   {3,5},   {4,5},                                       {9,5},
   395         -   {0,6},   {1,6},   {2,6},   {3,6},   {4,6},   {5,6},                     {8,6},   {9,6},
   396         -   {0,7},   {1,7},   {2,7},   {3,7},   {4,7},   {5,7},   {6,7},   {7,7},   {8,7},   {9,7},
   397         -   {0,8},   {1,8},   {2,8},   {3,8},   {4,8},   {5,8},   {6,8},   {7,8},   {8,8},   {9,8},
   398         -   {0,9},   {1,9},   {2,9},   {3,9},   {4,9},   {5,9},   {6,9},   {7,9},   {8,9},   {9,9},
   399         -};
   400         -
   401         -static const Icon icons[] = {
   402         -	[0]		= MAKE_ICON(clock_icon),
   403         -	[1]		= MAKE_ICON(cpu_icon),
   404         -	[2]		= MAKE_ICON(mem_icon),
   405         -	[3]		= MAKE_ICON(speaker_hi_icon),
   406         -	[4]		= MAKE_ICON(speaker_mid_icon),
   407         -	[5]		= MAKE_ICON(speaker_low_icon),
   408         -	[6]		= MAKE_ICON(speaker_mute_icon),
   409         -	[7]		= MAKE_ICON(wifi_full_icon),
   410         -	[8]		= MAKE_ICON(wifi_hi_icon),
   411         -	[9]		= MAKE_ICON(wifi_mid_icon),
   412         -	[10]	= MAKE_ICON(wifi_low_icon),
   413         -	[11]	= MAKE_ICON(wifi_off_icon),
   414         -	[12]	= MAKE_ICON(mail_new_icon),
   415         -	[13]	= MAKE_ICON(mail_none_icon),
   416         -	[14]	= MAKE_ICON(batt_full_icon),
   417         -	[15]	= MAKE_ICON(batt_hi_icon),
   418         -	[16]	= MAKE_ICON(batt_mid_icon),
   419         -	[17]	= MAKE_ICON(batt_low_icon),
   420         -	[18]	= MAKE_ICON(batt_zero_icon),
   421         -	[19]	= MAKE_ICON(batt_charge_icon),
   422         -	[20]	= MAKE_ICON(arch_icon),
   423         -	[21]	= MAKE_ICON(app_term),
   424         -	[22]	= MAKE_ICON(app_web),
   425         -	[23]	= MAKE_ICON(app_stats),
   426         -	[24]	= MAKE_ICON(app_docs),
   427         -	[25]	= MAKE_ICON(app_music),
   428         -	[26]	= MAKE_ICON(app_video),
   429         -	[27]	= MAKE_ICON(app_games),
   430         -	[28]	= MAKE_ICON(app_images),
   431         -};
   432         -
   433         -// vim: ts=4
   434         -#endif /* __ALOPEX_ICONS_H__ */
   435         -
   436         -

Added share/config.

            1  +!! Alopex resource database
            2  +!! By: Jesse McClure (c) 2014
            3  +!! License: CC-BY-SA
            4  +!!   http://creativecommons.org/licenses/by-sa/4.0/
            5  +
            6  +! including a specific theme file (rather than all three) will
            7  +!  slghtly reduce memory use.  By default all three are included
            8  +#include "/usr/share/alopex/themes"
            9  +
           10  +!----- Theme name -----!
           11  +! Used to apply theme specific settings, defaults to icecap
           12  +! Thi can be overriden by passing a theme name on the command line
           13  +Alopex.Theme:           icecap
           14  +! Other config settings can be set differently for different themes.
           15  +! For example the following three entries could all be sepcified:
           16  +!    *.Tiling.Split:           0
           17  +!    icecap.Tiling.Split:      10
           18  +!    tundra.Tiling.Split:      -10
           19  +! This would allow the split to be set on a per theme basis, so simply
           20  +!   changing the them name here, or on the command line, would load a
           21  +!   different subset of settings.  As can be read in the xrdb docs,
           22  +!   a matching implicitly named specifier takes precident over wildcards.
           23  +
           24  +!----- Bar -----!
           25  +! A program or script that sends status strings to it's stdout
           26  +*.Bar.StatInput:			/path/to/stat
           27  +! Font info
           28  +*.Bar.Font:					/usr/share/fonts/TTF/DroidSansMono.ttf
           29  +*.Bar.BoldFont:			/usr/share/fonts/TTF/DroidSans-Bold.ttf
           30  +*.Bar.FontSize:			14
           31  +! PNG file with 10x10 grid of icons 1-100
           32  +*.Bar.Icons:				/path/to/icons.png
           33  +! Height of bars: "default" bases height on font extents
           34  +*.Bar.Height:           default
           35  +! Options: visible/hidden top/bottom
           36  +*.Bar.Options:				visible top
           37  +
           38  +!----- Tiling -----!
           39  +! PNG for wallpaper
           40  +*.Tiling.Background:		/path/to/background.png
           41  +! Pixel count for how much larger the first container is than others
           42  +*.Tiling.Split:			0
           43  +! Padding between tiles (e.g. "useless gap")
           44  +*.Tiling.Padding:			0
           45  +! Number of clients per container, there will always be one more
           46  +!  container than specified here to hold any/all overflow
           47  +*.Tiling.Containers:		1 3 3
           48  +! rstack bstack or monocle
           49  +*.Tiling.Mode:				rstack
           50  +! pixels for the top bottom left and right of monitor that will not
           51  +!  be used: space can be reserved for external bars/trays/docks
           52  +*.Tiling.Margin:			0 0 0 0
           53  +
           54  +!----- Tags -----!
           55  +! icon-tex text-icon icon text to specify what shows in tags
           56  +*.Tags.Mode:            icon-text
           57  +! specify a single '-' for a name to not show a name for tag
           58  +*.Tags.Names:				one two three four five
           59  +! specify a -1 for a tag to now show an icon
           60  +*.Tags.Icons:				1 2 3 4 5
           61  +! space between tags
           62  +*.Tags.Padding:			5
           63  +
           64  +!----- Clients -----!
           65  +*.Clients.FollowMouse:	false
           66  +! top bottom above or below
           67  +*.Clients.Attach:			top
           68  +
           69  +!----- Rules -----!
           70  +! Each rule needs either a name, class, or both plus a specification
           71  +!  for flags (float fullscreen) and/or tags (list for multiple)
           72  +*.Rule.00.Name:			Float
           73  +*.Rule.00.Flags:			float
           74  +*.Rule.01.Class:			Float
           75  +*.Rule.01.Flags:			float
           76  +*.Rule.02.Class:			Firefox
           77  +*.Rule.02.Tags:			2
           78  +
           79  +!----- Binds -----!
           80  +! Each key can have up to five bindings using different modifiers
           81  +! Each key is numbered from 00-99
           82  +! See "Commands" description in a man page or github wiki for
           83  +!  a description of the command language used for bindings
           84  +!  NOTE: the wiki is currently outdated
           85  +! Modifier definitions
           86  +*.Bind.Mod.First:			Super
           87  +*.Bind.Mod.Second:		Super Alt
           88  +*.Bind.Mod.Third:			Super Shift
           89  +*.Bind.Mod.Fourth:		Super Control
           90  +*.Bind.Mod.Fifth:			Alt
           91  +! General bindings
           92  +*.Bind.00.Key:			q
           93  +*.Bind.00.Third:		quit
           94  +*.Bind.01.Key:			Return
           95  +*.Bind.01.First:		exec urxvt
           96  +*.Bind.02.Key:			w
           97  +*.Bind.02.First:		exec firefox
           98  +*.Bind.03.Key:			F4
           99  +*.Bind.03.Fifth:		kill
          100  +! Tiling mode
          101  +*.Bind.50.Key:			space
          102  +*.Bind.50.First:		layout
          103  +*.Bind.50.Second:		layout default
          104  +*.Bind.50.Third:		layout monocle
          105  +! Floating / Fullscren:
          106  +*.Bind.51.Key:			f
          107  +*.Bind.51.First:		float
          108  +*.Bind.51.Third:		fullscreen
          109  +! Focus / Move
          110  +! focus (top|bottom|up|down)
          111  +! move (top|bottom|up|down)
          112  +! win # move (above|below)
          113  +*.Bind.60.Key:			Tab
          114  +*.Bind.60.First:		focus previous
          115  +*.Bind.60.Third:		focus floater
          116  +*.Bind.60.Fifth:		view
          117  +*.Bind.61.Key:			h
          118  +*.Bind.61.First:		focus top
          119  +*.Bind.61.Third:		move top
          120  +*.Bind.62.Key:			j
          121  +*.Bind.62.First:		focus down
          122  +*.Bind.62.Third:		move down
          123  +*.Bind.63.Key:			k
          124  +*.Bind.63.First:		focus up
          125  +*.Bind.63.Third:		move up
          126  +*.Bind.64.Key:			l
          127  +*.Bind.64.First:		focus bottom
          128  +*.Bind.64.Third:		move bottom
          129  +! Modify Settings
          130  +! bar (top|bottom|show|hide|toggle) [all]
          131  +*.Bind.70.Key:			x
          132  +*.Bind.70.First:		bar toggle
          133  +*.Bind.70.Second:		bar show all
          134  +*.Bind.70.Third:		bar toggle all
          135  +*.Bind.70.Fourth:		bar hide all
          136  +! (split|gap|number) (increase|decrease|set|reset) [#]
          137  +*.Bind.71.Key:			i
          138  +*.Bind.71.First:		split increase 1
          139  +*.Bind.71.Second:		gap increase 1
          140  +*.Bind.71.Third:		number increase 1
          141  +*.Bind.72.Key:			d
          142  +*.Bind.72.First:		split decrease 1
          143  +*.Bind.72.Second:		gap decrease 1
          144  +*.Bind.72.Third:		number decrease 1
          145  +*.Bind.73.Key:			r
          146  +*.Bind.73.First:		split reset
          147  +*.Bind.73.Second:		gap reset
          148  +*.Bind.73.Third:		number reset
          149  +! Tag bindings
          150  +! [win [#]] tag (toggle|set|add|remove) #
          151  +*.Bind.81.Key:			1
          152  +*.Bind.81.First:		tag set 1
          153  +*.Bind.81.Second:		tag toggle 1
          154  +*.Bind.81.Third:		win tag set 1
          155  +*.Bind.81.Fourth:		win tag toggle 1
          156  +*.Bind.82.Key:			2
          157  +*.Bind.82.First:		tag set 2
          158  +*.Bind.82.Second:		tag toggle 2
          159  +*.Bind.82.Third:		win tag set 2
          160  +*.Bind.82.Fourth:		win tag toggle 2
          161  +*.Bind.83.Key:			3
          162  +*.Bind.83.First:		tag set 3
          163  +*.Bind.83.Second:		tag toggle 3
          164  +*.Bind.83.Third:		win tag set 3
          165  +*.Bind.83.Fourth:		win tag toggle 3
          166  +*.Bind.84.Key:			4
          167  +*.Bind.84.First:		tag set 4
          168  +*.Bind.84.Second:		tag toggle 4
          169  +*.Bind.84.Third:		win tag set 4
          170  +*.Bind.84.Fourth:		win tag toggle 4
          171  +! Window marks:
          172  +*.Bind.92.Key:			F2
          173  +*.Bind.92.First:		w2f
          174  +*.Bind.92.Second:		z2
          175  +*.Bind.93.Key:			F3
          176  +*.Bind.93.First:		win 3f
          177  +*.Bind.93.Second:		z3
          178  +
          179  +!! vim: ft=xdefaults

Added share/flats.

            1  +!! Alopex resource database: theme flats
            2  +!! By: Jesse McClure (c) 2014
            3  +!! License: CC-BY-SA
            4  +
            5  +flats.Tab.Offset:					0.00 0.00 0.00 2.00 0.0
            6  +flats.Tab.Background:			0.08 0.08 0.08 0.00 0.0
            7  +flats.Tab.Border:					0.00 0.20 1.00 0.00 0.5
            8  +flats.Tab.Text:					0.20 0.40 0.80 1.00 -10
            9  +flats.TabFocus.Background:		0.14 0.14 0.14 0.00 0.0
           10  +flats.TabFocus.Border:			0.60 0.90 1.00 0.00 0.5
           11  +flats.TabFocus.Text:				0.90 0.95 1.00 1.00 -10
           12  +flats.TabTop.Background:		0.14 0.14 0.14 0.00 0.0
           13  +flats.TabTop.Border:				0.00 0.40 1.00 0.00 0.5
           14  +flats.TabTop.Text:				0.35 0.75 1.00 1.00 -10
           15  +flats.Status.Offset:				0.00 0.00 0.00 0.00 0.0
           16  +flats.Status.Background:		0.14 0.14 0.14 0.00 0.0
           17  +flats.Status.Border:				0.60 0.90 1.00 0.00 0.0
           18  +flats.Status.Text:				0.80 0.80 0.80 1.00 0.0
           19  +flats.Tag.Occupied:				0.60 0.90 1.00 1.00 0.0
           20  +flats.Tag.View:					0.90 0.95 1.00 1.00 0.0
           21  +flats.Tag.Alt:						0.35 0.75 1.00 1.00 0.0
           22  +flats.Tag.Both:					0.60 1.00 0.60 1.00 0.0
           23  +
           24  +!! vim: ft=xdefaults

Added share/icecap.

            1  +!! Alopex resource database: theme icecap
            2  +!! By: Jesse McClure (c) 2014
            3  +!! License: CC-BY-SA
            4  +
            5  +icecap.Tab.Offset:				2.00 1.00 -4.0 10.0 6.0
            6  +icecap.Tab.Background:			0.04 0.04 0.04 0.60 0.0
            7  +icecap.Tab.Border:				0.00 0.20 1.00 0.45 0.8
            8  +icecap.Tab.Text:					0.25 0.45 1.00 0.40 0.5
            9  +icecap.TabFocus.Background:	0.14 0.14 0.14 1.00 0.0
           10  +icecap.TabFocus.Border:			0.60 0.90 1.00 0.95 1.2
           11  +icecap.TabFocus.Text:			0.90 0.95 1.00 0.90 -10
           12  +icecap.TabTop.Background:		0.14 0.14 0.14 1.00 0.0
           13  +icecap.TabTop.Border:			0.00 0.40 1.00 0.80 1.0
           14  +icecap.TabTop.Text:				0.25 0.65 1.00 0.70 0.5
           15  +icecap.Status.Offset:			1.00 2.00 -2.0 -4.0 5.0
           16  +icecap.Status.Background:		0.14 0.14 0.14 0.40 0.0
           17  +icecap.Status.Border:			1.00 1.00 1.00 0.60 1.0
           18  +icecap.Status.Text:				0.80 0.80 0.80 1.00 0.0
           19  +icecap.Tag.Occupied:				0.00 0.00 1.00 1.00 0.0
           20  +icecap.Tag.View:					1.00 1.00 1.00 1.00 0.0
           21  +icecap.Tag.Alt:					0.80 0.00 0.00 1.00 0.0
           22  +icecap.Tag.Both:					0.80 0.00 0.80 1.00 0.0
           23  +
           24  +!! vim: ft=xdefaults

Added share/polar.

            1  +!! Alopex resource database: theme polar
            2  +!! By: Jesse McClure (c) 2014
            3  +!! License: CC-BY-SA
            4  +
            5  +polar.Tab.Offset:					1.50 1.00 -3.0 2.00 3.0
            6  +polar.Tab.Background:			0.06 0.06 0.06 1.00 0.0
            7  +polar.Tab.Border:					0.00 0.20 1.00 0.45 0.8
            8  +polar.Tab.Text:					0.25 0.45 1.00 0.40 0.5
            9  +polar.TabFocus.Background:		0.14 0.14 0.14 1.00 0.0
           10  +polar.TabFocus.Border:			0.60 0.90 1.00 0.95 1.2
           11  +polar.TabFocus.Text:				0.90 0.95 1.00 0.90 -10
           12  +polar.TabTop.Background:		0.14 0.14 0.14 1.00 0.0
           13  +polar.TabTop.Border:				0.00 0.40 1.00 0.80 1.0
           14  +polar.TabTop.Text:				0.25 0.65 1.00 0.70 0.5
           15  +polar.Status.Offset:				1.50 -2.0 -3.0 1.00 3.0
           16  +polar.Status.Background:		0.14 0.14 0.14 1.00 0.0
           17  +polar.Status.Border:				1.00 1.00 1.00 0.60 1.0
           18  +polar.Status.Text:				0.80 0.80 0.80 1.00 0.0
           19  +polar.Tag.Occupied:				0.00 0.00 1.00 1.00 0.0
           20  +polar.Tag.View:					1.00 1.00 1.00 1.00 0.0
           21  +polar.Tag.Alt:						0.80 0.00 0.00 1.00 0.0
           22  +polar.Tag.Both:					0.80 0.00 0.80 1.00 0.0
           23  +
           24  +!! vim: ft=xdefaults

Added share/taiga.

            1  +!! Alopex resource database: theme taiga
            2  +!! By: Jesse McClure (c) 2014
            3  +!! License: CC-BY-SA
            4  +
            5  +! TODO modify to taiga - right now this is mostly just a copy of icecap
            6  +
            7  +taiga.Tab.Offset:					2.00 2.00 -4.0 -4.0 0.0
            8  +taiga.Tab.Background:			0.20 0.60 0.30 0.60 0.0
            9  +taiga.Tab.Border:					0.35 0.75 0.45 0.60 0.8
           10  +taiga.Tab.Text:					0.90 0.90 0.50 0.40 0.5
           11  +taiga.TabFocus.Background:		0.00 0.50 0.10 1.00 0.0
           12  +taiga.TabFocus.Border:			0.45 1.00 0.65 0.95 1.2
           13  +taiga.TabFocus.Text:				0.90 1.00 0.70 0.90 -10
           14  +taiga.TabTop.Background:		0.00 0.50 0.10 1.00 0.0
           15  +taiga.TabTop.Border:				0.10 0.85 0.60 0.80 1.0
           16  +taiga.TabTop.Text:				0.75 1.00 0.85 0.70 0.5
           17  +taiga.Status.Offset:				2.00 2.00 -4.0 -4.0 0.0
           18  +taiga.Status.Background:		0.10 0.55 0.20 0.40 0.0
           19  +taiga.Status.Border:				0.70 1.00 0.60 0.60 1.0
           20  +taiga.Status.Text:				0.60 0.80 0.60 1.00 0.0
           21  +taiga.Tag.Occupied:				0.40 1.00 0.40 1.00 0.0
           22  +taiga.Tag.View:					0.90 1.00 0.90 1.00 0.0
           23  +taiga.Tag.Alt:						0.80 0.80 0.00 1.00 0.0
           24  +taiga.Tag.Both:					0.60 1.00 0.00 1.00 0.0
           25  +
           26  +!! vim: ft=xdefaults

Added share/themes.

            1  +!! Alopex resource database: themes
            2  +!! By: Jesse McClure (c) 2014
            3  +!! License: CC-BY-SA
            4  +
            5  +#include "/usr/share/alopex/icecap"
            6  +#include "/usr/share/alopex/polar"
            7  +#include "/usr/share/alopex/tundra"
            8  +#include "/usr/share/alopex/taiga"
            9  +
           10  +!! vim: ft=xdefaults

Added share/tundra.

            1  +!! Alopex resource database: theme tundra
            2  +!! By: Jesse McClure (c) 2014
            3  +!! License: CC-BY-SA
            4  +
            5  +tundra.Tab.Offset:				1.00 1.00 -2.0 2.00 3.0
            6  +tundra.Tab.Background:			0.08 0.08 0.08 1.00 0.0
            7  +tundra.Tab.Border:				0.40 0.40 0.34 1.00 0.8
            8  +tundra.Tab.Text:					0.40 0.40 0.34 1.00 0.5
            9  +tundra.TabFocus.Background:	0.14 0.14 0.14 1.00 0.0
           10  +tundra.TabFocus.Border:			0.82 0.68 0.44 1.00 1.2
           11  +tundra.TabFocus.Text:			0.94 0.80 0.68 0.90 -10
           12  +tundra.TabTop.Background:		0.14 0.14 0.14 1.00 0.0
           13  +tundra.TabTop.Border:			0.80 0.53 0.28 1.00 1.0
           14  +tundra.TabTop.Text:				0.40 0.40 0.34 1.00 0.5
           15  +tundra.Status.Offset:			0.00 0.00 0.00 0.00 0.0
           16  +tundra.Status.Background:		0.12 0.10 0.08 1.00 0.0
           17  +tundra.Status.Border:			0.12 0.10 0.08 1.00 0.0
           18  +tundra.Status.Text:				0.94 0.80 0.68 1.00 0.0
           19  +tundra.Tag.Occupied:				0.40 0.40 0.34 1.00 0.0
           20  +tundra.Tag.View:					0.86 0.80 0.50 1.00 0.0
           21  +tundra.Tag.Alt:					1.00 0.15 0.00 1.00 0.0
           22  +tundra.Tag.Both:					0.94 0.50 0.25 1.00 0.0
           23  +
           24  +!! vim: ft=xdefaults

Added src/actions.c.

            1  +
            2  +#include "alopex.h"
            3  +#include "actions.h"
            4  +
            5  +extern Bool tile_check(Monitor *, Client *);
            6  +extern int send_message(Client *, int, int);
            7  +
            8  +
            9  +int command(const char *cmd) {
           10  +	//if (cmd[0] == '!') return spawn(cmd+1);
           11  +	char *tok, *sptr, *str;
           12  +	str = strdup(cmd);
           13  +	for (tok = strtok_r(str, ";", &sptr); tok;
           14  +			tok = strtok_r(NULL, ";", &sptr))
           15  +		word(tok);
           16  +	free(str);
           17  +	return 0;
           18  +}
           19  +
           20  +void conftile(Client *t, const char **arg) {
           21  +	if (!m->focus || !arg[0]) return;
           22  +	int n, *opt = NULL, r;
           23  +	switch (arg[0][0]) {
           24  +		case 'n': opt = &m->focus->n; r = m->focus->nn; break;
           25  +		case 's': opt = &m->split; r = conf.split; break;
           26  +		case 'g': opt = &m->gap; r = conf.gap; break;
           27  +	}
           28  +	if (!opt || !arg[1]) return;
           29  +	if (arg[2]) n = atoi(arg[2]);
           30  +	else n = 1;
           31  +	switch (arg[1][0]) {
           32  +		case 'i': *opt += n; break;
           33  +		case 'd': *opt -= n; break;
           34  +		case 'r': *opt = r; break;
           35  +		case 's': *opt = n; break;
           36  +	}
           37  +}
           38  +
           39  +void floater(Client *t, const char **arg) {
           40  +	if (!t && !(t=winmarks[1])) return;
           41  +	if (t->flags & WIN_FLOAT) t->flags &= ~WIN_FULL;
           42  +	else t->flags |= WIN_FLOAT;
           43  +}
           44  +
           45  +void fullscreen(Client *t, const char **arg) {
           46  +	if (!t && !(t=winmarks[1])) return;
           47  +	if (t->flags & WIN_FULL_TEST) t->flags &= ~WIN_FULL;
           48  +	else t->flags |= WIN_FULL;
           49  +}
           50  +
           51  +void focus(Client *t, const char **arg) {
           52  +	if (t) {
           53  +		winmarks[0] = winmarks[1];
           54  +		winmarks[1] = t;
           55  +		return;
           56  +	}
           57  +	Container *C;
           58  +	Client *c, *a, *b = NULL;
           59  +	if (!(c=winmarks[1])) return;
           60  +	if (strncasecmp(arg[0],"flo",3)==0) { /* focus floating */
           61  +		for (a = winmarks[1]->next; a; a = a->next)
           62  +			if (a->flags & WIN_FLOAT) break;
           63  +		if (!a) for (a = clients; a; a = a->next)
           64  +			if (a->flags & WIN_FLOAT) break;
           65  +		if (!a) return;
           66  +		winmarks[0] = winmarks[1];
           67  +		winmarks[1] = a;
           68  +	}
           69  +	else if (strncasecmp(arg[0],"top",3)==0) { /* focus top */
           70  +		for (C = m->container; C && C->next; C = C->next) {
           71  +			if (C->next == m->focus) {
           72  +				winmarks[0] = winmarks[1];
           73  +				winmarks[1] = C->top;
           74  +			}
           75  +		}
           76  +	}
           77  +	else if (strncasecmp(arg[0],"dow",3)==0) { /* focus down */
           78  +		for (a = c->next; a; a = a->next)
           79  +			if (tile_check(m, a)) break;
           80  +		if (a) {
           81  +			winmarks[0] = winmarks[1];
           82  +			winmarks[1] = a;
           83  +		}
           84  +	}
           85  +	else if (strncasecmp(arg[0],"up",2)==0) { /* focus up */
           86  +		for (a = clients; a && a != c; a = a->next)
           87  +			if (tile_check(m, a)) b = a;
           88  +		if (b) {
           89  +			winmarks[0] = winmarks[1];
           90  +			winmarks[1] = b;
           91  +		}
           92  +	}
           93  +	else if (strncasecmp(arg[0],"bot",3)==0) { /* focus bottom */
           94  +		if (m->focus->next && m->focus->next->top) {
           95  +			winmarks[0] = winmarks[1];
           96  +			winmarks[1] = m->focus->next->top;
           97  +		}
           98  +	}
           99  +	else if (strncasecmp(arg[0],"pre",3)==0) { /* focus previous */
          100  +		if (winmarks[0] && (winmarks[0]->tags & m->tags)) {
          101  +			/* focus previous */
          102  +			a = winmarks[0];
          103  +			winmarks[0] = winmarks[1];
          104  +			winmarks[1] = a;
          105  +		}
          106  +		else { /* focus first container, or next container ... */
          107  +			C = m->container;
          108  +			if (C->top == winmarks[1]) C = C->next;
          109  +			if (C->top)
          110  +				a = C->top;
          111  +			else /* ... only one container -> focus another client */
          112  +				for (a = clients; a; a = a->next)
          113  +					if (a != winmarks[1] && tile_check(m, a)) break;
          114  +			if (a) {
          115  +				winmarks[0] = winmarks[1];
          116  +				winmarks[1] = a;
          117  +			}
          118  +		}
          119  +	}
          120  +}
          121  +
          122  +void killclient(Client *c, const char **arg) {
          123  +	if (!c && !(c=winmarks[1])) return;
          124  +	send_message(c, WM_PROTOCOLS, WM_DELETE_WINDOW);
          125  +}
          126  +
          127  +void layout(Client *c, const char **arg) {
          128  +	if (!arg[0]) { if ( (++m->mode) == LAST_MODE ) m->mode = 0; }
          129  +	else if (strncasecmp(arg[0],"rst",3)==0) m->mode = RSTACK;
          130  +	else if (strncasecmp(arg[0],"bst",3)==0) m->mode = BSTACK;
          131  +	else if (strncasecmp(arg[0],"mon",3)==0) m->mode = MONOCLE;
          132  +	else if (strncasecmp(arg[0],"def",3)==0) m->mode = conf.mode;
          133  +}
          134  +
          135  +void mark_client(Client *t, const char **arg) {
          136  +	int n = atoi(arg[0]);
          137  +	if (!(t=winmarks[1])) return;
          138  +	if (n > 1 && n < 10) winmarks[n] = t;
          139  +	else if (n == 1) { winmarks[0] = winmarks[1]; winmarks[1] = t; }
          140  +}
          141  +
          142  +void mod_bar(Client *t, const char **arg) {
          143  +	if (!arg[0]) return;
          144  +	Container *C;
          145  +	Bar *b;
          146  +	if (!m->focus || !(b=m->focus->bar)) return;
          147  +	int all = 0;
          148  +	if (arg[1] && strncasecmp(arg[1],"all",3)==0) all = 1;
          149  +	if (all) {
          150  +		if (strncasecmp(arg[0],"sho",3)==0)
          151  +			for (C = m->container; C; C = C->next)
          152  +				C->bar->opts &= ~BAR_HIDE;
          153  +		else if (strncasecmp(arg[0],"hid",3)==0)
          154  +			for (C = m->container; C; C = C->next)
          155  +				C->bar->opts |= BAR_HIDE;
          156  +		else if (strncasecmp(arg[0],"tog",3)==0)
          157  +			for (C = m->container; C; C = C->next)
          158  +				C->bar->opts ^= BAR_HIDE;
          159  +		else if (strncasecmp(arg[0],"top",3)==0)
          160  +			for (C = m->container; C; C = C->next)
          161  +				C->bar->opts &= ~BAR_BOTTOM;
          162  +		else if (strncasecmp(arg[0],"bot",3)==0)
          163  +			for (C = m->container; C; C = C->next)
          164  +				C->bar->opts |= BAR_BOTTOM;
          165  +	}
          166  +	else {
          167  +		if (strncasecmp(arg[0],"sho",3)==0) b->opts &= ~BAR_HIDE;
          168  +		else if (strncasecmp(arg[0],"hid",3)==0) b->opts |= BAR_HIDE;
          169  +		else if (strncasecmp(arg[0],"tog",3)==0) b->opts ^= BAR_HIDE;
          170  +		else if (strncasecmp(arg[0],"top",3)==0) b->opts &= ~BAR_BOTTOM;
          171  +		else if (strncasecmp(arg[0],"bot",3)==0) b->opts |= BAR_BOTTOM;
          172  +	}
          173  +}
          174  +
          175  +void monitor(Client *t, const char **arg) {
          176  +//	int n1, n2, n3, n4;
          177  +//	if (*s == 'm') { /* margins */
          178  +//		if (s[1] == 'r')
          179  +//			m->margin = conf.margin;
          180  +//		else {
          181  +//			sscanf(s,"m%d,%d,%d,%d", &n1, &n2, &n3, &n4);
          182  +//			m->margin.top = n1;
          183  +//			m->margin.bottom = n2;
          184  +//			m->margin.left = n3;
          185  +//			m->margin.right = n4;
          186  +//		}
          187  +//	}
          188  +//	else if (*s == 's') { /* swap tags */
          189  +//		sscanf(s,"s%d,%d", &n1, &n2);
          190  +//		Monitor *M, *a = NULL, *b = NULL;
          191  +//		for (M = mons, n3 = 1; M; n3++, M = M->next) {
          192  +//			if (n1 == n3) a = M;
          193  +//			else if (n2 == n3) b = M;
          194  +//		}
          195  +//		if (a && b) {
          196  +//			n4 = a->tags;
          197  +//			a->tags = b->tags;
          198  +//			b->tags = n4;
          199  +//		}
          200  +//	}
          201  +//	else if (*s == 'c') { /* cycle through monitors */
          202  +//		m = m->next;
          203  +//		if (!m) m = mons;
          204  +//	}
          205  +//	else { /* focus another monitor */
          206  +//		n1 = atoi(s);
          207  +//		Monitor *M;
          208  +//		for (M = mons; n1 > 0 && M; n1--, M = M->next) m = M;
          209  +//	}
          210  +//	return 0;
          211  +}
          212  +
          213  +void move(Client *t, const char **arg) {
          214  +	Client *c, *a, *b;
          215  +	if (!(c=winmarks[1]) || !arg || !arg[0]) return;
          216  +	if (t) { /* move focused window relative to t */
          217  +		if (!(m->focus && m->focus->top) || c == t) return;
          218  +		switch (arg[0][0]) {
          219  +			case 'a': pull_client(c); push_client(c, t); break;
          220  +			case 'b': pull_client(c); push_client(c, t->next); break;
          221  +		}
          222  +		return;
          223  +	}
          224  +	/* else move focused in direction */
          225  +	if (strncasecmp(arg[0],"top",3)==0) {
          226  +		pull_client(c); push_client(c, clients);
          227  +	}
          228  +	else if (strncasecmp(arg[0],"dow",3)==0) {
          229  +		for (a = c->next; a; a = a->next)
          230  +			if (tile_check(m, a)) break;
          231  +		if (a) for (a = a->next; a; a = a->next)
          232  +			if (tile_check(m, a)) break;
          233  +		pull_client(c); push_client(c, a);
          234  +	}
          235  +	else if (strncasecmp(arg[0],"up",3)==0) {
          236  +		for (a = clients; a && a != c; a = a->next)
          237  +			if (tile_check(m, a)) b = a;
          238  +		if (b) { pull_client(c); push_client(c, b); }
          239  +	}
          240  +	else if (strncasecmp(arg[0],"up",3)==0) {
          241  +		pull_client(c); push_client(c, NULL);
          242  +	}
          243  +}
          244  +
          245  +void pull_client(Client *c) {
          246  +	Client *cur, *pre = NULL;
          247  +	for (cur = clients; cur != c; cur = cur->next) pre = cur;
          248  +	if (pre) pre->next = cur->next;
          249  +	else clients = cur->next;
          250  +	cur->next = NULL;
          251  +}
          252  +
          253  +void push_client(Client *insert, Client *before) {
          254  +	Client *cur, *pre = NULL;
          255  +	for (cur = clients; cur != before; cur = cur->next) pre = cur;
          256  +	if (pre) pre->next = insert;
          257  +	else clients = insert;
          258  +	insert->next = cur;
          259  +}
          260  +
          261  +void spawn(Client *t, const char **arg) {
          262  +	if (!arg || !arg[0]) return;
          263  +	if (!fork()) {
          264  +		setsid();
          265  +		close(ConnectionNumber(dpy));
          266  +		if (conf.stat) fclose(conf.stat);
          267  +		if (conf.statfd) close(conf.statfd);
          268  +		execvp(arg[0], (char * const *) arg);
          269  +	}
          270  +}
          271  +
          272  +void tag(Client *t, const char **arg) {
          273  +	if (!arg || !arg[0] || !arg[1]) return;
          274  +	int tag = atoi(arg[1]);
          275  +	if (!tag || tag > 15) return;
          276  +	tag = (1<<(tag-1));
          277  +	int *n;
          278  +	if (!t) n = &m->tags;
          279  +	else n = &t->tags;
          280  +	switch (arg[0][0]) { /* set toggle add remove */
          281  +		case 's': *n = (*n & 0xFFFF0000) | tag; break;
          282  +		case 't': *n ^= tag; break;
          283  +		case 'a': *n |= tag; break;
          284  +		case 'r': *n &= ~tag; break;
          285  +	}
          286  +}
          287  +
          288  +void word(const char *word) {
          289  +	char **arg = NULL, *tok, *sptr, *tmp;
          290  +	const char **parg;
          291  +	int i, n;
          292  +	tmp = strdup(word);
          293  +	tok = strtok_r(tmp, " ", &sptr);
          294  +	for (i = 0; tok; i++) {
          295  +		arg = realloc(arg, (i+1) * sizeof(char *));
          296  +		arg[i] = tok;
          297  +		tok = strtok_r(NULL," ", &sptr);
          298  +	}
          299  +	arg = realloc(arg, (i+1) * sizeof(char *));
          300  +	arg[i] = NULL;
          301  +	parg = (const char **) arg;
          302  +	/* get target */
          303  +	Client *wt = NULL;
          304  +	if ( (strncasecmp(arg[0],"win",3)==0) && arg[1] ) {
          305  +		if ( !(n=atoi(arg[1])) ) {
          306  +			n = 1;
          307  +			parg = (const char **) &arg[1];
          308  +		}
          309  +		else {
          310  +			parg = (const char **) &arg[2];
          311  +		}
          312  +		if (n > 0 && n < 10) wt = winmarks[n];
          313  +		if (!wt) return;
          314  +	}
          315  +	/* process command */
          316  +	if (strncasecmp(parg[0],"bar",3) == 0) mod_bar(wt,&parg[1]);
          317  +	else if (strncasecmp(parg[0],"mon",3) == 0) monitor(wt,&parg[1]);
          318  +	else if (strncasecmp(parg[0],"foc",3) == 0) focus(wt,&parg[1]);
          319  +	else if (strncasecmp(parg[0],"flo",3) == 0) floater(wt,&parg[1]);
          320  +	else if (strncasecmp(parg[0],"ful",3) == 0) fullscreen(wt,&parg[1]);
          321  +	else if (strncasecmp(parg[0],"spl",3) == 0) conftile(wt,&parg[0]);
          322  +	else if (strncasecmp(parg[0],"gap",3) == 0) conftile(wt,&parg[0]);
          323  +	else if (strncasecmp(parg[0],"num",3) == 0) conftile(wt,&parg[0]);
          324  +	else if (strncasecmp(parg[0],"lay",3) == 0) layout(wt,&parg[1]);
          325  +	else if (strncasecmp(parg[0],"exe",3) == 0) spawn(wt,&parg[1]);
          326  +	else if (strncasecmp(parg[0],"mov",3) == 0) move(wt,&parg[1]);
          327  +	else if (strncasecmp(parg[0],"kil",3) == 0) killclient(wt,&parg[1]);
          328  +	else if (strncasecmp(parg[0],"qui",3) == 0) running = False;
          329  +	else if (strncasecmp(parg[0],"tag",3) == 0) tag(wt,&parg[1]);
          330  +	else if (strncasecmp(parg[0],"mar",3) == 0) mark_client(wt, &parg[1]);
          331  +	else if (strncasecmp(parg[0],"vie",3) == 0) {
          332  +		n = (m->tags<<16) & 0xFFFF0000;
          333  +		n |= (m->tags>>16) & 0xFFFF;
          334  +		m->tags = n;
          335  +	}
          336  +	free(arg);
          337  +	free(tmp);
          338  +	tile();
          339  +}
          340  +

Added src/actions.h.

            1  +
            2  +#ifndef __ACTIONS_H__
            3  +#define __ACTIONS_H__
            4  +
            5  +extern int command(const char *);
            6  +extern void conftile(Client *, const char **);
            7  +extern void float_full(Client *, const char **);
            8  +extern void focus(Client *, const char **);
            9  +extern void killclient(Client *, const char **);
           10  +extern void layout(Client *, const char **);
           11  +extern void mod_bar(Client *, const char **);
           12  +extern void move(Client *, const char **);
           13  +extern void pull_client(Client *);
           14  +extern void push_client(Client *, Client *);
           15  +extern void spawn(Client *, const char **);
           16  +extern void tag(Client *, const char **);
           17  +extern void word(const char *);
           18  +
           19  +#endif /* __ACTIONS_H__ */

Added src/alopex.c.

            1  +
            2  +#include "alopex.h"
            3  +
            4  +extern int xlib_init(const char *);
            5  +extern int xlib_free();
            6  +extern int main_loop();
            7  +
            8  +void handler(int sig) {
            9  +	if (sig == SIGCHLD)
           10  +		while (waitpid(-1, NULL, WNOHANG) > 0);
           11  +}
           12  +
           13  +void die(const char *fmt, ...) {
           14  +	fprintf(stderr,"ALOPEX: ");
           15  +	va_list arg;
           16  +	va_start(arg, fmt);
           17  +	vfprintf(stderr, fmt, arg);
           18  +	va_end(arg);
           19  +	fprintf(stderr,"\n");
           20  +	exit(1);
           21  +}
           22  +
           23  +int main(int argc, const char **argv) {
           24  +	signal(SIGCHLD, &handler);
           25  +	if (argc > 1) xlib_init(argv[1]);
           26  +	else xlib_init(NULL);
           27  +	main_loop();
           28  +	xlib_free();
           29  +	return 0;
           30  +}

Added src/alopex.h.

            1  +
            2  +#ifndef __ALOPEX_H__
            3  +#define __ALOPEX_H__
            4  +
            5  +#include <stdlib.h>
            6  +#include <stdio.h>
            7  +#include <string.h>
            8  +#include <unistd.h>
            9  +#include <fcntl.h>
           10  +#include <locale.h>
           11  +#include <math.h>
           12  +#include <signal.h>
           13  +#include <sys/types.h>
           14  +#include <sys/stat.h>
           15  +#include <X11/Xlib.h>
           16  +#include <X11/keysym.h>
           17  +#include <X11/XKBlib.h>
           18  +#include <X11/Xatom.h>
           19  +#include <X11/Xutil.h>
           20  +#include <X11/cursorfont.h>
           21  +#include <X11/Xresource.h>
           22  +#include <X11/extensions/Xinerama.h>
           23  +#include <ft2build.h>
           24  +#include FT_FREETYPE_H
           25  +#include <cairo.h>
           26  +#include <cairo-xlib.h>
           27  +#include <cairo-ft.h>
           28  +
           29  +#define BAR_BOTTOM		0x1000
           30  +#define BAR_HIDE			0x2000
           31  +#define BAR_HEIGHT		0x00FF
           32  +#define ATTACH_TOP		0x0000
           33  +#define ATTACH_ABOVE		0x0001
           34  +#define ATTACH_BELOW		0x0002
           35  +#define ATTACH_BOTTOM	0x0003
           36  +#define MONOCLE			0x0000
           37  +#define RSTACK				0x0001
           38  +#define BSTACK				0x0002
           39  +#define LAST_MODE			0x0003
           40  +
           41  +#define WIN_FLOAT       0x0001
           42  +#define WIN_FULL_TEST   0x0002
           43  +#define WIN_FULL        0x0003
           44  +#define WIN_TRANS       0x0005
           45  +#define WIN_FOCUS       0x0010
           46  +#define WIN_URGENT      0x0020
           47  +
           48  +#define NWINMARKS			10
           49  +
           50  +#define MAX_STATUS 4
           51  +/* pre-tags, post-tags, 2nd right, last right */
           52  +
           53  +enum {
           54  +	TabOffset,
           55  +	TabBackground, TabBorder, TabText,
           56  +	TabFocusBackground, TabFocusBorder, TabFocusText,
           57  +	TabTopBackground, TabTopBorder, TabTopText,
           58  +	StatusOffset,
           59  +	StatusBackground, StatusBorder, StatusText,
           60  +	TagOccupied, TagView, TagAlt, TagBoth,
           61  +	ThemeLast
           62  +};
           63  +
           64  +enum {
           65  +	WM_PROTOCOLS, WM_DELETE_WINDOW, WM_STATE, WM_TAKE_FOCUS,
           66  +	WM_NAME,
           67  +	NET_SUPPORTED, NET_WM_NAME, NET_WM_STATE,
           68  +	NET_WM_STATE_FULLSCREEN, NET_ACTIVE_WINDOW,
           69  +	NET_WM_WINDOW_TYPE, NET_WM_TYPE_DIALOG, NET_CLIENT_LIST,
           70  +	ATOM_LAST
           71  +};
           72  +
           73  +enum { TAG_ICON_TEXT, TAG_TEXT_ICON, TAG_TEXT, TAG_ICON };
           74  +
           75  +typedef struct Key {
           76  +	unsigned short int mod;
           77  +	KeySym keysym;
           78  +	const char *arg;
           79  +} Key;
           80  +
           81  +typedef struct Client Client;
           82  +struct Client {
           83  +	Client *next;
           84  +	Window win, parent;
           85  +	char *title;
           86  +	cairo_surface_t *icon;
           87  +	int tags, flags, x, y, w, h;
           88  +};
           89  +
           90  +typedef struct Rule {
           91  +	const char *name;
           92  +	const char *class;
           93  +	int tags;
           94  +	int flags;
           95  +} Rule;
           96  +
           97  +typedef struct Bar {
           98  +	cairo_surface_t *buf;
           99  +	cairo_t *ctx;
          100  +	int opts;
          101  +	int xoff, w, h;
          102  +} Bar;
          103  +
          104  +typedef struct Container Container;
          105  +struct Container {
          106  +	Container *next;
          107  +	Window win;
          108  +	cairo_t *ctx;
          109  +	int x, y, w, h, n, nn;
          110  +	int left_pad, right_pad;
          111  +	Bar *bar;
          112  +	Client *top;
          113  +};
          114  +
          115  +typedef struct Margin {
          116  +	int top, bottom, left, right;
          117  +} Margin;
          118  +
          119  +typedef struct Monitor Monitor;
          120  +struct Monitor {
          121  +	Bar tbar;
          122  +	Monitor *next;
          123  +	Margin margin;
          124  +	int x, y, w, h, gap;
          125  +	int tags, occ, mode, split;
          126  +	Container *container, *focus;
          127  +	cairo_surface_t *bg;
          128  +};
          129  +
          130  +typedef union Theme {
          131  +	struct { double x, y, w, h, r; };
          132  +	struct { double R, G, B, A, e; };
          133  +} Theme;
          134  +
          135  +typedef struct Config {
          136  +	cairo_font_face_t *font, *bfont;
          137  +	Theme theme[ThemeLast];
          138  +	Margin margin;
          139  +	int nkeys;
          140  +	Key *key;
          141  +	int nrules;
          142  +	Rule *rule;
          143  +	int statfd;
          144  +	FILE *stat;
          145  +	char **tag_name;
          146  +	int *tag_icon, tag_count, tag_mode;
          147  +	int gap, split, mode, bar_pad, chain_delay, bar_opts, attach;
          148  +	int font_size;
          149  +	Bool focus_follow;
          150  +} Config;
          151  +
          152  +Monitor *mons, *m;
          153  +Client *clients, *winmarks[NWINMARKS+1];
          154  +Display *dpy;
          155  +int scr;
          156  +Window root;
          157  +GC gc;
          158  +Atom atom[ATOM_LAST];
          159  +Bool running;
          160  +FT_Library ftlib;
          161  +Config conf;
          162  +Bar sbar[MAX_STATUS];
          163  +
          164  +extern void die(const char *, ...);
          165  +extern int tile();
          166  +
          167  +#endif /* __ALOPEX_H__ */

Added src/atoms.c.

            1  +
            2  +#include "alopex.h"
            3  +
            4  +static inline Atom make_atom(const char *a) {
            5  +	return XInternAtom(dpy, a, False);
            6  +}
            7  +
            8  +int atoms_init() {
            9  +	atom[WM_NAME] = XA_WM_NAME;
           10  +	atom[WM_PROTOCOLS] = make_atom("WM_PROTOCOLS");
           11  +	atom[WM_DELETE_WINDOW] = make_atom("WM_DELETE_WINDOW");
           12  +	atom[WM_STATE] = make_atom("WM_STATE");
           13  +	atom[WM_TAKE_FOCUS] = make_atom("WM_TAKE_FOCUS");
           14  +//	atom[NET_SUPPORTED] = make_atom("_NET_SUPPORTED");
           15  +	atom[NET_WM_NAME] = make_atom("_NET_WM_NAME");
           16  +//	atom[NET_WM_STATE] = make_atom("_NET_WM_STATE");
           17  +//	atom[NET_WM_STATE_FULLSCREEN] = make_atom("_NET_WM_STATE_FULLSCREEN");
           18  +//	atom[NET_ACTIVE_WINDOW] = make_atom("_NET_ACTIVE_WINDOW");
           19  +//	atom[NET_WM_WINDOW_TYPE] = make_atom("_NET_WM_WINDOW_TYPE");
           20  +//	atom[NET_WM_TYPE_DIALOG] = make_atom("_NET_WM_TYPE_DIALOG");
           21  +//	atom[NET_CLIENT_LIST] = make_atom("_NET_CLIENT_LIST");
           22  +	return 0;
           23  +}
           24  +
           25  +Atom get_atom(Client *c, int type) {
           26  +	int i;
           27  +	unsigned long ul;
           28  +	unsigned char *uc = NULL;
           29  +	Atom aa, at = None;
           30  +	if (!XGetWindowProperty(dpy, c->win, atom[type], 0L, sizeof(at),
           31  +			False, XA_ATOM, &aa, &i, &ul, &ul, &uc) == Success && uc)
           32  +		return at;
           33  +	at = *(Atom *)uc;
           34  +	XFree(uc);
           35  +	return at;
           36  +}
           37  +
           38  +char *get_text(Client *c, int type) {
           39  +	char **strs = NULL, *ret = NULL;
           40  +	int n;
           41  +	XTextProperty text;
           42  +	XGetTextProperty(dpy, c->win, &text, atom[type]);
           43  +	if (!text.nitems) return NULL;
           44  +	if (text.encoding == XA_STRING) ret = strdup(text.value);
           45  +	else if (XmbTextPropertyToTextList(dpy, &text, &strs, &n)>=Success) {
           46  +		ret = strdup(*strs);
           47  +		XFreeStringList(strs);
           48  +	}
           49  +	XFree(text.value);
           50  +	return ret;
           51  +}
           52  +
           53  +
           54  +int send_message(Client *c, int type, int msg) {
           55  +	XEvent ev;
           56  +	ev.type = ClientMessage;
           57  +	ev.xclient.window = c->win;
           58  +	ev.xclient.message_type = atom[type];
           59  +	//ev.xclient.message_type = XInternAtom(dpy, "WM_PROTOCOLS", True);
           60  +	ev.xclient.format = 32;
           61  +	ev.xclient.data.l[0] = atom[msg];
           62  +	//ev.xclient.data.l[0] = XInternAtom(dpy, "WM_DELETE_WINDOW", True);
           63  +	ev.xclient.data.l[1] = CurrentTime;
           64  +	XSendEvent(dpy, c->win, False, NoEventMask, &ev);
           65  +	return 0;
           66  +}

Added src/config.c.

            1  +
            2  +#include "alopex.h"
            3  +
            4  +extern int free_mons();
            5  +extern int get_mons(const char *, const char *);
            6  +extern int icons_init(const char *);
            7  +extern int icons_free();
            8  +
            9  +static int config_general(XrmDatabase, const char *);
           10  +static int config_binds(XrmDatabase, const char *);
           11  +static int config_rules(XrmDatabase, const char *);
           12  +static int config_theme(XrmDatabase, const char *);
           13  +
           14  +FT_Face face, bface;
           15  +static pid_t pid;
           16  +static XrmDatabase xrdb;
           17  +
           18  +int config_init(const char *theme) {
           19  +	const char *pwd = getenv("PWD");
           20  +	XrmInitialize();
           21  +	if ( (!chdir(getenv("XDG_CONFIG_HOME")) && !chdir("alopex")) ||
           22  +			(!chdir(getenv("HOME")) && !chdir(".config/alopex")) )
           23  +		xrdb = XrmGetFileDatabase("config");
           24  +	if (!xrdb) xrdb = XrmGetFileDatabase("/usr/share/alopex/config");
           25  +	if (!xrdb) die("cannot find a configuration resource database");
           26  +	char *_base = "icecap", *class = "Alopex.Theme", *type;
           27  +	const char *base;
           28  +	XrmValue val;
           29  +	if (theme) base = theme;
           30  +	else if (XrmGetResource(xrdb, class, class, &type, &val))
           31  +		base = val.addr;
           32  +	else base = _base;
           33  +char test[256];
           34  +sprintf(test, "%s.Tab.Offset", base);
           35  +if (!XrmGetResource(xrdb, test, test, &type, &val))
           36  +die("No theme resources found\n");
           37  +	config_binds(xrdb, base);
           38  +	config_general(xrdb, base);
           39  +	config_rules(xrdb, base);
           40  +	config_theme(xrdb, base);
           41  +	chdir(pwd);
           42  +	return 0;
           43  +}
           44  +
           45  +int config_free() {
           46  +	XrmDestroyDatabase(xrdb);
           47  +	if (conf.statfd) {
           48  +		fclose(conf.stat);
           49  +		close(conf.statfd);
           50  +		conf.statfd = 0;
           51  +		kill(pid, SIGKILL);
           52  +		wait(pid);
           53  +	}
           54  +	icons_free();
           55  +	free_mons();
           56  +	int i;
           57  +	if (conf.tag_name) {
           58  +		for (i = 0; conf.tag_name[i]; i++)
           59  +			free(conf.tag_name[i]);
           60  +		free(conf.tag_name);
           61  +	}
           62  +	if (conf.tag_icon) free(conf.tag_icon);
           63  +	cairo_font_face_destroy(conf.font);
           64  +	cairo_font_face_destroy(conf.bfont);
           65  +	FT_Done_Face(face);
           66  +	FT_Done_Face(bface);
           67  +	free(conf.key);
           68  +	conf.key = NULL;
           69  +	conf.nkeys = 0;
           70  +	return 0;
           71  +}
           72  +
           73  +int reconfigure() {
           74  +	config_free();
           75  +	config_init(NULL);
           76  +}
           77  +
           78  +/**** Local functions ****/
           79  +
           80  +enum {
           81  +	STR_Font, STR_BoldFont, STR_IconFile, STR_Options, STR_Background,
           82  +	STR_Containers, STR_Names, STR_Icons, STR_FollowMouse, STR_Attach,
           83  +	STR_StatIn, STR_Mode, STR_Margin, STR_TagMode,
           84  +	STR_Last
           85  +};
           86  +enum { TYPE_S, TYPE_D };
           87  +typedef struct Res {
           88  +	const char *elem, *opt;
           89  +	int type;
           90  +	void *dest;
           91  +} Res;
           92  +
           93  +int config_general(XrmDatabase xrdb, const char *base) {
           94  +	const char *s[STR_Last];
           95  +	memset(s, 0, STR_Last);
           96  +	int bar_height = 0;
           97  +	const char *RES_Bar = "Bar";
           98  +	const char *RES_Background = "Background";
           99  +	const char *RES_Mode = "Mode";
          100  +	const char *RES_Tags = "Tags";
          101  +	const char *RES_Tiling = "Tiling";
          102  +	const char *RES_Padding = "Padding";
          103  +	const char *RES_Clients = "Clients";
          104  +	Res res[] = {
          105  +		{ RES_Bar,    "StatInput",    TYPE_S, &s[STR_StatIn]},
          106  +		{ RES_Bar,    "Font",         TYPE_S, &s[STR_Font]},
          107  +		{ RES_Bar,    "BoldFont",     TYPE_S, &s[STR_BoldFont]},
          108  +		{ RES_Bar,    "FontSize",     TYPE_D, &conf.font_size},
          109  +		{ RES_Bar,    "Height",       TYPE_D, &bar_height},
          110  +		{ RES_Bar,    "Icons",        TYPE_S, &s[STR_IconFile]},
          111  +		{ RES_Bar,    "Options",      TYPE_S, &s[STR_Options]},
          112  +		{ RES_Tiling, RES_Background, TYPE_S, &s[STR_Background]},
          113  +		{ RES_Tiling, "Split",        TYPE_D, &conf.split},
          114  +		{ RES_Tiling, RES_Padding,    TYPE_D, &conf.gap},
          115  +		{ RES_Tiling, "Containers",   TYPE_S, &s[STR_Containers]},
          116  +		{ RES_Tiling, RES_Mode,       TYPE_S, &s[STR_Mode]},
          117  +		{ RES_Tiling, "Margin",       TYPE_S, &s[STR_Margin]},
          118  +		{ RES_Tags,   RES_Mode,       TYPE_S, &s[STR_TagMode]},
          119  +		{ RES_Tags,   "Names",        TYPE_S, &s[STR_Names]},
          120  +		{ RES_Tags,   "Icons",        TYPE_S, &s[STR_Icons]},
          121  +		{ RES_Tags,   RES_Padding,    TYPE_D, &conf.bar_pad},
          122  +		{ "Chains",   "Delay",        TYPE_D, &conf.chain_delay},
          123  +		{ RES_Clients,"FollowMouse",  TYPE_S, &s[STR_FollowMouse]},
          124  +		{ RES_Clients,"Attach",       TYPE_S, &s[STR_Attach]},
          125  +	};
          126  +	int i;
          127  +	char class[256], *type;
          128  +	XrmValue val;
          129  +	for (i = 0; i < sizeof(res)/sizeof(res[0]); i++) {
          130  +		strcpy(class,base);
          131  +		strcat(class,"."); strcat(class,res[i].elem);
          132  +			strcat(class,"."); strcat(class,res[i].opt);
          133  +		if (!XrmGetResource(xrdb, class, class, &type, &val)) continue;
          134  +		if (res[i].type == TYPE_S)
          135  +			*(char **) res[i].dest = val.addr;
          136  +		else if (res[i].type == TYPE_D)
          137  +			 *((int *) res[i].dest) = atoi(val.addr);
          138  +	}
          139  +	/* get fonts */
          140  +	if (FT_New_Face(ftlib, s[STR_Font], 0, &face) |
          141  +			FT_Set_Pixel_Sizes(face, 0, conf.font_size))
          142  +		die("unable to load freetype font \"%s\"",s[STR_Font]);
          143  +	if (FT_New_Face(ftlib, s[STR_BoldFont], 0, &bface) |
          144  +			FT_Set_Pixel_Sizes(bface, 0, conf.font_size))
          145  +		die("unable to load freetype font \"%s\"",s[STR_BoldFont]);
          146  +	conf.font = cairo_ft_font_face_create_for_ft_face(face, 0);
          147  +	conf.bfont = cairo_ft_font_face_create_for_ft_face(bface, 0);
          148  +	/* set options */
          149  +	conf.bar_opts = (bar_height ? bar_height : conf.font_size + 4);
          150  +	if (strcasestr(s[STR_Mode],"rstack")) conf.mode = RSTACK;
          151  +	if (strcasestr(s[STR_Mode],"bstack")) conf.mode = BSTACK;
          152  +	if (strcasestr(s[STR_Mode],"monocle")) conf.mode = MONOCLE;
          153  +	if (strcasestr(s[STR_Options],"bottom")) conf.bar_opts |= BAR_BOTTOM;
          154  +	if (strcasestr(s[STR_Options],"hide")) conf.bar_opts |= BAR_HIDE;
          155  +	if (strcasestr(s[STR_FollowMouse],"true")) conf.focus_follow = True;
          156  +	if (strcasestr(s[STR_Attach],"top")) conf.attach = ATTACH_TOP;
          157  +	if (strcasestr(s[STR_Attach],"above")) conf.attach = ATTACH_ABOVE;
          158  +	if (strcasestr(s[STR_Attach],"below")) conf.attach = ATTACH_BELOW;
          159  +	if (strcasestr(s[STR_Attach],"bottom")) conf.attach = ATTACH_BOTTOM;
          160  +	if (s[STR_Margin]) sscanf(s[STR_Margin],"%d %d %d %d",
          161  +			&conf.margin.top, &conf.margin.bottom,
          162  +			&conf.margin.left, &conf.margin.right);
          163  +	if (!strcasecmp(s[STR_TagMode],"icon-text"))
          164  +		conf.tag_mode = TAG_ICON_TEXT;
          165  +	else if (!strcasecmp(s[STR_TagMode],"text-icon"))
          166  +		conf.tag_mode = TAG_TEXT_ICON;
          167  +	else if (!strcasecmp(s[STR_TagMode],"text"))
          168  +		conf.tag_mode = TAG_TEXT;
          169  +	else if (!strcasecmp(s[STR_TagMode],"icon"))
          170  +		conf.tag_mode = TAG_ICON;
          171  +	/* get tag names and icon numbers */
          172  +	conf.tag_name = NULL;
          173  +	char *name = strtok((char *) s[STR_Names]," ");
          174  +	for (i = 0; name; i++) {
          175  +		conf.tag_name = realloc(conf.tag_name, (i+1) * sizeof(char *));
          176  +		conf.tag_name[i] = strdup(name);
          177  +		name = strtok(NULL," ");
          178  +	}
          179  +	conf.tag_count = i;
          180  +	conf.tag_name = realloc(conf.tag_name, (i+1) * sizeof(char *));
          181  +	conf.tag_name[i] = NULL;
          182  +	conf.tag_icon = NULL;
          183  +	name = strtok((char *) s[STR_Icons]," ");
          184  +	for (i = 0; name; i++) {
          185  +		conf.tag_icon = realloc(conf.tag_icon, (i+1) * sizeof(int));
          186  +		conf.tag_icon[i] = atoi(name);
          187  +		name = strtok(NULL," ");
          188  +	}
          189  +	if (conf.tag_count < i) conf.tag_count = i;
          190  +	conf.tag_icon = realloc(conf.tag_icon, (i+1) * sizeof(int));
          191  +	conf.tag_icon[i] = -1;
          192  +	/* status input */
          193  +	int fd[2], flags;
          194  +	struct stat stbuf;
          195  +	if (s[STR_StatIn] && !stat(s[STR_StatIn],&stbuf) &&
          196  +			(stbuf.st_mode & S_IXUSR) ){
          197  +		pipe(fd);
          198  +		if ( (pid=fork()) ) {
          199  +			close(fd[1]);
          200  +			flags = fcntl(fd[0], F_GETFL, 0);
          201  +			fcntl(fd[0], F_SETFL, flags | O_NONBLOCK);
          202  +			conf.statfd = fd[0];
          203  +			conf.stat = fdopen(fd[0],"r");
          204  +		}
          205  +		else {
          206  +			close(ConnectionNumber(dpy));
          207  +			close(fd[0]);
          208  +			dup2(fd[1], 1);
          209  +		//	close(fd[1]);
          210  +			execlp(s[STR_StatIn], s[STR_StatIn], NULL);
          211  +		}
          212  +	}
          213  +	else {
          214  +		conf.statfd = 0;
          215  +		conf.stat = NULL;
          216  +	}
          217  +	/* external inits */
          218  +	get_mons(s[STR_Background], s[STR_Containers]);
          219  +	icons_init(s[STR_IconFile]);
          220  +	return 0;
          221  +}
          222  +
          223  +#define MAX_MOD	6
          224  +int config_binds(XrmDatabase xrdb, const char *base) {
          225  +	/* get modifiers */
          226  +	int mods[MAX_MOD];
          227  +	memset(mods,0,MAX_MOD);
          228  +	const char *ord[MAX_MOD] = {
          229  +		"None", "First", "Second", "Third", "Fourth", "Fifth"
          230  +	};
          231  +	char class[256], *type;
          232  +	XrmValue val;
          233  +	int i, j, tmod;
          234  +	for (i = 1; i < MAX_MOD; i++) {
          235  +		sprintf(class,"%s.Bind.Mod.%s",base,ord[i]);
          236  +		if (XrmGetResource(xrdb, class, class, &type, &val)) {
          237  +			mods[i] = 0;
          238  +			if (strcasestr(val.addr, "mod5"))
          239  +				mods[i] |= Mod5Mask;
          240  +			if (strcasestr(val.addr,"super") ||
          241  +					strcasestr(val.addr, "win") ||
          242  +					strcasestr(val.addr, "mod4"))
          243  +				mods[i] |= Mod4Mask;
          244  +			if (strcasestr(val.addr, "mod3"))
          245  +				mods[i] |= Mod3Mask;
          246  +			if (strcasestr(val.addr, "mod2"))
          247  +				mods[i] |= Mod2Mask;
          248  +			if (strcasestr(val.addr, "alt") ||
          249  +					strcasestr(val.addr, "mod1"))
          250  +				mods[i] |= Mod1Mask;
          251  +			if (strcasestr(val.addr, "control") ||
          252  +					strcasestr(val.addr,"ctrl"))
          253  +				mods[i] |= ControlMask;
          254  +			if (strcasestr(val.addr, "shift"))
          255  +				mods[i] |= ShiftMask;
          256  +		}
          257  +	}
          258  +	/* loop through bindings */
          259  +	conf.key = NULL;
          260  +	conf.nkeys = 0;
          261  +	int bmax = 100;
          262  +//	sprintf(class,"%s.Bind.Max",base);
          263  +//	if (XrmGetResource(xrdb, class, class, &type, &val))
          264  +//		bmax = atoi(val.addr) + 1;
          265  +	KeySym sym;
          266  +	for (i = 0; i < bmax; i++) {
          267  +		sprintf(class,"%s.Bind.%02d.Key",base,i);
          268  +		if (!XrmGetResource(xrdb, class, class, &type, &val)) continue;
          269  +		if ( (sym=XStringToKeysym(val.addr)) == NoSymbol ) continue;
          270  +		for (j = 0; j < MAX_MOD; j++) {
          271  +			sprintf(class,"%s.Bind.%02d.%s",base,i,ord[j]);
          272  +			if (!XrmGetResource(xrdb, class, class, &type, &val)) continue;
          273  +			conf.key = realloc(conf.key, (conf.nkeys+1) * sizeof(Key));
          274  +			conf.key[conf.nkeys].keysym = sym;
          275  +			conf.key[conf.nkeys].mod = mods[j];
          276  +			conf.key[conf.nkeys].arg = val.addr;
          277  +			conf.nkeys++;
          278  +		}
          279  +	}
          280  +	return 0;
          281  +}
          282  +
          283  +int config_rules(XrmDatabase xrdb, const char *base) {
          284  +	char class[256], *type, *rn, *rc;
          285  +	XrmValue val;
          286  +	conf.rule = NULL;
          287  +	conf.nrules = 0;
          288  +	int i, j, rmax = 100, tags, flags, n[8];
          289  +//	sprintf(class,"%s.Rule.Max",base);
          290  +//	if (XrmGetResource(xrdb, class, class, &type, &val))
          291  +//		rmax = atoi(val.addr) + 1;
          292  +	for (i = 0; i < rmax; i++) {
          293  +		rn = rc = NULL;
          294  +		sprintf(class,"%s.Rule.%02d.Name",base,i);
          295  +		if (XrmGetResource(xrdb, class, class, &type, &val)) rn = val.addr;
          296  +		sprintf(class,"%s.Rule.%02d.Class",base,i);
          297  +		if (XrmGetResource(xrdb, class, class, &type, &val)) rc = val.addr;
          298  +		if (!rn && !rc) continue;
          299  +		conf.rule = realloc(conf.rule, (conf.nrules+1) * sizeof(Rule));
          300  +		conf.rule[conf.nrules].name = rn;
          301  +		conf.rule[conf.nrules].class = rc;
          302  +		conf.rule[conf.nrules].tags = 0;
          303  +		sprintf(class,"%s.Rule.%02d.Tags",base,i);
          304  +		if (XrmGetResource(xrdb, class, class, &type, &val)) {
          305  +			memset(n,0,8 * sizeof(int));
          306  +			sscanf(val.addr,"%d %d %d %d %d %d %d %d",
          307  +					&n[0], &n[1], &n[2], &n[3], &n[4], &n[5], &n[6], &n[7]);
          308  +			for (j = 0; j < 8; j++)
          309  +				if (n[j]) conf.rule[conf.nrules].tags |= (1<<(n[j]-1));
          310  +		}
          311  +		conf.rule[conf.nrules].flags = 0;
          312  +		sprintf(class,"%s.Rule.%02d.Flags",base,i);
          313  +		if (XrmGetResource(xrdb, class, class, &type, &val)) {
          314  +			if (strcasestr(val.addr,"fullscreen"))
          315  +				conf.rule[conf.nrules].flags |= WIN_FULL;
          316  +			if (strcasestr(val.addr,"float"))
          317  +				conf.rule[conf.nrules].flags |= WIN_FLOAT;
          318  +		}
          319  +		conf.nrules++;
          320  +	}
          321  +	return 0;
          322  +}
          323  +
          324  +int config_theme(XrmDatabase xrdb, const char *base) {
          325  +	const char *RES_Tab = "Tab";
          326  +	const char *RES_TabFocus = "TabFocus";
          327  +	const char *RES_TabTop = "TabTop";
          328  +	const char *RES_Status = "Status";
          329  +	const char *RES_Tag = "Tag";
          330  +	const char *RES_Offset = "Offset";
          331  +	const char *RES_Background = "Background";
          332  +	const char *RES_Border = "Border";
          333  +	const char *RES_Text = "Text";
          334  +	Res res[] = {
          335  +		{ RES_Tab,       RES_Offset,     TabOffset,          NULL},
          336  +		{ RES_Tab,       RES_Background, TabBackground,      NULL},
          337  +		{ RES_Tab,       RES_Border,     TabBorder,          NULL},
          338  +		{ RES_Tab,       RES_Text,       TabText,            NULL},
          339  +		{ RES_TabFocus,  RES_Background, TabFocusBackground, NULL},
          340  +		{ RES_TabFocus,  RES_Border,     TabFocusBorder,     NULL},
          341  +		{ RES_TabFocus,  RES_Text,       TabFocusText,       NULL},
          342  +		{ RES_TabTop,    RES_Background, TabTopBackground,   NULL},
          343  +		{ RES_TabTop,    RES_Border,     TabTopBorder,       NULL},
          344  +		{ RES_TabTop,    RES_Text,       TabTopText,         NULL},
          345  +		{ RES_Status,    RES_Offset,     StatusOffset,       NULL},
          346  +		{ RES_Status,    RES_Background, StatusBackground,   NULL},
          347  +		{ RES_Status,    RES_Border,     StatusBorder,       NULL},
          348  +		{ RES_Status,    RES_Text,       StatusText,         NULL},
          349  +		{ RES_Tag,       "Occupied",     TagOccupied,        NULL},
          350  +		{ RES_Tag,       "View",         TagView,            NULL},
          351  +		{ RES_Tag,       "Alt",          TagAlt,             NULL},
          352  +		{ RES_Tag,       "Both",         TagBoth,            NULL},
          353  +	};
          354  +	char class[256], *type;
          355  +	XrmValue val;
          356  +	int i;
          357  +	Theme *q;
          358  +	for (i = 0; i < sizeof(res)/sizeof(res[0]); i++) {
          359  +		sprintf(class,"%s.%s.%s", base, res[i].elem, res[i].opt);
          360  +		if (!XrmGetResource(xrdb, class, class, &type, &val)) continue;
          361  +		q = &conf.theme[res[i].type];
          362  +		sscanf(val.addr,"%lf %lf %lf %lf %lf",
          363  +			&q->R, &q->G, &q->B, &q->A, &q->e);
          364  +	}
          365  +	return 0;
          366  +}

Added src/draw.c.

            1  +
            2  +#include "alopex.h"
            3  +
            4  +static int round_rect(Bar *, int, int, int, int, int, int, int, int);
            5  +static int set_color(cairo_t *, int);
            6  +static int sbar_icon(Bar *, int, Bool);
            7  +static int sbar_text(Bar *, const char *);
            8  +
            9  +static cairo_surface_t *icon_img[100];
           10  +static cairo_format_t icon_fmt = 0;
           11  +
           12  +int draw_bar_sub(Monitor *M, Container *C, Bar *S, int x, Bool bg) {
           13  +	if (C->bar->opts & BAR_HIDE) return 0;
           14  +	if (S->w < 1) return 0;
           15  +	cairo_rectangle(C->bar->ctx, x, 0, S->w, C->bar->h);
           16  +	cairo_clip(C->bar->ctx);
           17  +	if (bg) { /* draw background as needed */
           18  +		int y = M->y - (C->bar->opts & BAR_BOTTOM ? C->y+C->h : C->y-C->bar->h);
           19  +		if (C->top)
           20  +			cairo_set_source_surface(C->bar->ctx, M->bg, M->x - C->x, y);
           21  +		else
           22  +			cairo_set_source_surface(C->bar->ctx, M->bg, M->x - C->x, 0);
           23  +		cairo_paint(C->bar->ctx);
           24  +	}
           25  +	round_rect(C->bar, x, 0, S->w, S->h, StatusOffset,
           26  +			StatusBackground, StatusBorder, StatusText);
           27  +	cairo_set_source_surface(C->bar->ctx, S->buf, x, 0);
           28  +	cairo_paint(C->bar->ctx);
           29  +	cairo_reset_clip(C->bar->ctx);
           30  +	return 0;
           31  +}
           32  +
           33  +int draw_bars(Bool bg) {
           34  +	Monitor *M; Container *C;
           35  +	int n, count;
           36  +	for (M = mons; M; M = M->next) {
           37  +		count = n = 0;
           38  +		for (C = M->container; C; C = C->next) if (C->top) count++;
           39  +		for (C = M->container; C; C = C->next) {
           40  +			/* paint status to buf */
           41  +			if (n == 0) {
           42  +				draw_bar_sub(M, C, &sbar[0], 0, bg);
           43  +				draw_bar_sub(M, C, &M->tbar, sbar[0].w, bg);
           44  +				draw_bar_sub(M, C, &sbar[1], sbar[0].w + M->tbar.w, bg);
           45  +				if (count < 2) {
           46  +					draw_bar_sub(M, C, &sbar[2], C->w-sbar[2].w-sbar[3].w, bg);
           47  +					draw_bar_sub(M, C, &sbar[3], C->w - sbar[3].w, bg);
           48  +				}
           49  +			}
           50  +			else if (n == 1) {
           51  +				if (count == 2) {
           52  +					draw_bar_sub(M, C, &sbar[2], C->w-sbar[2].w-sbar[3].w, bg);
           53  +					draw_bar_sub(M, C, &sbar[3], C->w - sbar[3].w, bg);
           54  +				}
           55  +				else  {
           56  +					draw_bar_sub(M, C, &sbar[2], C->w - sbar[2].w, bg);
           57  +				}
           58  +			}
           59  +			else if (n == count - 1) {
           60  +				draw_bar_sub(M, C, &sbar[3], C->w - sbar[3].w, bg);
           61  +			}
           62  +			/* paint buf to win */
           63  +			cairo_set_source_surface(C->ctx, C->bar->buf, 0, 0);
           64  +			cairo_paint(C->ctx);
           65  +			if ( (++n) >= count ) break;
           66  +		}
           67  +	}
           68  +}
           69  +
           70  +int draw_tab(Container *C, Client *c, int n, int count) {
           71  +	Bar *b = C->bar;
           72  +	int w = (C->w - C->left_pad - C->right_pad)/ count;
           73  +	int x = w * n + C->left_pad;
           74  +	int h = C->bar->opts & BAR_HEIGHT;
           75  +	int theme = 0;
           76  +	if (m->focus == C && C->top == c) theme = 3;
           77  +	else if (C->top == c) theme = 6;
           78  +	round_rect(b, x, 0, w, h, TabOffset, TabBackground + theme,
           79  +			TabBorder + theme, TabText + theme);
           80  +	double off = conf.theme[TabText+theme].r;
           81  +	cairo_text_extents_t ext;
           82  +	cairo_text_extents(b->ctx, c->title, &ext);
           83  +if (c->icon) ext.x_advance += conf.font_size + conf.bar_pad;
           84  +	if (off < 0) off *= -1;
           85  +	else {
           86  +		off *= w - ext.x_advance;
           87  +		if (off < 0) off = 0;
           88  +	}
           89  +if (c->icon) {
           90  +	cairo_save(b->ctx);
           91  +	cairo_set_source_surface(b->ctx, c->icon, x + off,
           92  +			(b->h - conf.font_size) / 2.0);
           93  +	cairo_paint(b->ctx);
           94  +	off += conf.font_size + conf.bar_pad;
           95  +	cairo_restore(b->ctx);
           96  +}
           97  +	cairo_rectangle(b->ctx, x+off, 0, w-off, h);
           98  +	cairo_clip(b->ctx);
           99  +	cairo_move_to(b->ctx, x+off, h - 4); // - 4 ?
          100  +	cairo_show_text(b->ctx, c->title);
          101  +	cairo_reset_clip(b->ctx);
          102  +}
          103  +
          104  +int icons_init(const char *fname) {
          105  +	double iw, ih;
          106  +	int i, j, fs = conf.font_size;
          107  +	cairo_surface_t *img = cairo_image_surface_create_from_png(fname);
          108  +if (cairo_surface_status(img) != CAIRO_STATUS_SUCCESS) return 1;
          109  +	icon_fmt = cairo_image_surface_get_format(img);
          110  +	iw = cairo_image_surface_get_width(img) / 10.0;
          111  +	ih = cairo_image_surface_get_height(img) / 10.0;
          112  +	cairo_t *ctx;
          113  +	for (j = 0; j < 10; j++) for (i = 0; i < 10; i++) {
          114  +		icon_img[j*10+i] = cairo_image_surface_create(icon_fmt, fs, fs);
          115  +		ctx = cairo_create(icon_img[j*10+i]);
          116  +		cairo_scale(ctx, fs/iw, fs/ih);
          117  +		cairo_set_source_surface(ctx, img, -1 * i * iw, -1 * j * ih);
          118  +		cairo_paint(ctx);
          119  +		cairo_destroy(ctx);
          120  +	}
          121  +	cairo_surface_destroy(img);
          122  +	return 0;
          123  +}
          124  +
          125  +int icons_free() {
          126  +	int i;
          127  +	for (i = 0; i < 100; i++)
          128  +		if (icon_img[i]) cairo_surface_destroy(icon_img[i]);
          129  +	return 0;
          130  +}
          131  +
          132  +int round_rect(Bar *b, int x, int y, int w, int h,
          133  +		int off, int bg, int brd, int txt) {
          134  +	const Theme *q = &conf.theme[off];
          135  +	if (b->opts & BAR_BOTTOM) {
          136  +		cairo_save(b->ctx);
          137  +		cairo_scale(b->ctx, 1, -1);
          138  +		cairo_translate(b->ctx, 0, -1 * (b->opts & BAR_HEIGHT));
          139  +	}
          140  +	cairo_new_sub_path(b->ctx);
          141  +	x += q->x; y += q->y; w += q->w; h += q->h;
          142  +	cairo_arc(b->ctx, x + w - q->e, y + q->e, q->e, -0.5 * M_PI, 0);
          143  +	cairo_arc(b->ctx, x + w - q->e, y + h - q->e, q->e, 0, 0.5 * M_PI);
          144  +	cairo_arc(b->ctx, x + q->e, y + h - q->e, q->e, 0.5 * M_PI, M_PI);
          145  +	cairo_arc(b->ctx, x + q->e, y + q->e, q->e, M_PI, 1.5 * M_PI);
          146  +	cairo_close_path(b->ctx);
          147  +	set_color(b->ctx, bg);
          148  +	cairo_fill_preserve(b->ctx);
          149  +	set_color(b->ctx, brd);
          150  +	cairo_set_line_width(b->ctx, conf.theme[brd].r);
          151  +	cairo_stroke(b->ctx);
          152  +	if (b->opts & BAR_BOTTOM) cairo_restore(b->ctx);
          153  +	set_color(b->ctx, txt);
          154  +	return 0;
          155  +}
          156  +
          157  +int sbar_icon(Bar *S, int n, Bool col) {
          158  +// TODO fix the "2"
          159  +	if ( (--n) < 0 || n > 99) return 1;
          160  +	if (!icon_img[n]) return 1;
          161  +	cairo_save(S->ctx);
          162  +	if (col && icon_fmt != CAIRO_FORMAT_A1) {
          163  +		cairo_set_source_surface(S->ctx, icon_img[n], S->xoff, 2);
          164  +		cairo_paint(S->ctx);
          165  +	}
          166  +	else {
          167  +		cairo_mask_surface(S->ctx, icon_img[n], S->xoff, 2);
          168  +	}
          169  +	S->xoff += conf.font_size;
          170  +	cairo_restore(S->ctx);
          171  +	return 0;
          172  +}
          173  +
          174  +int sbar_parse(Bar *S, const char *s) {
          175  +	cairo_save(S->ctx);
          176  +	cairo_set_operator(S->ctx, CAIRO_OPERATOR_CLEAR);
          177  +	cairo_paint(S->ctx);
          178  +	cairo_restore(S->ctx);
          179  +	S->xoff = 0;
          180  +	set_color(S->ctx, StatusText);
          181  +	const char *c; char *t1, *t2, *str;
          182  +	double r, g, b, a;
          183  +	for (c = s; c && *c != '&' && *c != '\0' && *c != '\n'; c++) {
          184  +		if (*c == '{') {
          185  +			if (*(++c) == 'i') sbar_icon(S, atoi((++c)), True);
          186  +			else if (*c == 'I') sbar_icon(S, atoi((++c)), False);
          187  +			else if (*c == 'f') cairo_set_font_face(S->ctx, conf.font);
          188  +			else if (*c == 'F') cairo_set_font_face(S->ctx, conf.bfont);
          189  +			else if (sscanf(c, "%lf %lf %lf %lf", &r, &g, &b, &a) == 4)
          190  +				cairo_set_source_rgba(S->ctx, r, g, b, a);
          191  +			c = strchr(c, '}');
          192  +		}
          193  +		else {
          194  +			str = strdup(c);
          195  +			t1 = strchr(str,'{');
          196  +			t2 = strchr(str,'&');
          197  +			if (t1 && t2 && t1 > t2) t1 = t2;
          198  +			else if (!t1 && t2) t1 = t2;
          199  +			if (!t1) t1 = strchr(str,'\n');
          200  +			*t1 = '\0';
          201  +			c += t1 - str - 1;
          202  +			sbar_text(S, str);
          203  +			free(str);
          204  +		}
          205  +	}
          206  +	if (S->w != S->xoff) {
          207  +		S->w = S->xoff;
          208  +		return 1;
          209  +	}
          210  +	else return 0;
          211  +}
          212  +
          213  +static int sbar_tag_icon(Monitor *M, Bar *S, int i) {
          214  +	if (conf.tag_icon[i] == -1) return 1;
          215  +	else return sbar_icon(S, conf.tag_icon[i], True); //TODO: True -> conf
          216  +}
          217  +
          218  +static int sbar_tag_text(Monitor *M, Bar *S, int i) {
          219  +	if (conf.tag_name[i][0] == '-') return 1;
          220  +	sbar_text(S, conf.tag_name[i]);
          221  +	S->xoff += conf.bar_pad;
          222  +	return 1;
          223  +}
          224  +
          225  +int sbar_tags(Monitor *M) {
          226  +	if (M->container->bar->opts & BAR_HIDE) return 0;
          227  +	Bar *S = &M->tbar;
          228  +	cairo_save(S->ctx);
          229  +	cairo_set_operator(S->ctx, CAIRO_OPERATOR_CLEAR);
          230  +	cairo_paint(S->ctx);
          231  +	cairo_restore(S->ctx);
          232  +	S->xoff = conf.bar_pad;
          233  +	int i, count = 0;
          234  +	for (i = 0; conf.tag_name[i]; i++) {
          235  +		set_color(S->ctx, TagOccupied);
          236  +		if (M->occ & (1<<i)) cairo_set_font_face(S->ctx, conf.bfont);
          237  +		else cairo_set_font_face(S->ctx, conf.font);
          238  +		if ( (M->tags & (1<<i)) && (M->tags & (1<<(1+16))) )
          239  +			set_color(S->ctx, TagBoth);
          240  +		else if (M->tags & (1<<i)) set_color(S->ctx, TagView);
          241  +		else if (M->tags & (1<<(i+16))) set_color(S->ctx, TagAlt);
          242  +		else if (!(M->occ & (1<<i))) continue;
          243  +		switch (conf.tag_mode) {
          244  +			case TAG_ICON_TEXT: count += sbar_tag_icon(M, S, i);
          245  +			case TAG_TEXT: count += sbar_tag_text(M, S, i); break;
          246  +			case TAG_TEXT_ICON: count += sbar_tag_text(M, S, i);
          247  +			case TAG_ICON: count += sbar_tag_icon(M, S, i); break;
          248  +		}
          249  +	}
          250  +	if (!count) S->xoff = 0;
          251  +	S->w = S->xoff;
          252  +	return 0;
          253  +}
          254  +
          255  +int sbar_text(Bar *S, const char *str) {
          256  +	cairo_move_to(S->ctx, S->xoff, S->h - 4);
          257  +	cairo_show_text(S->ctx, str);
          258  +	cairo_text_extents_t ext;
          259  +	cairo_text_extents(S->ctx, str, &ext);
          260  +	S->xoff += ext.x_advance;
          261  +	return 0;
          262  +}
          263  +
          264  +int set_color(cairo_t *ctx, int col) {
          265  +	cairo_set_source_rgba(ctx, conf.theme[col].R, conf.theme[col].G,
          266  +			conf.theme[col].B, conf.theme[col].A);
          267  +}

Added src/tile.c.

            1  +
            2  +#include "alopex.h"
            3  +
            4  +extern int draw_bars(Bool);
            5  +extern int sbar_tags(Monitor *M);
            6  +
            7  +Bool tile_check(Monitor *, Client *);
            8  +
            9  +static int resize_container(Monitor *, Container *, int, int);
           10  +static int tile_container(Monitor *, Container *, Client *, int);
           11  +
           12  +int tile() {
           13  +	if ( !winmarks[1] || !(winmarks[1]->tags & m->tags) ) {
           14  +		winmarks[0] = winmarks[1];
           15  +		winmarks[1] = NULL;
           16  +	}
           17  +	Monitor *M;
           18  +	Container *C;
           19  +	Client *c, *pc, *t;
           20  +	int num, cn, numC, ord;
           21  +	int mview = 0;
           22  +	for (M = mons; M; M = M->next) {
           23  +		M->tags &= ~mview;
           24  +		mview |= M->tags;
           25  +		/* calculate how many containers will be used: */
           26  +		if (M->mode == MONOCLE) {
           27  +			M->focus = M->container;
           28  +			numC = 0;
           29  +			M->occ = 0;
           30  +			for (c = clients; c; c = c->next) {
           31  +				M->occ |= (c->tags & 0xFFFF);
           32  +				if (tile_check(M, c)) {
           33  +					if (!winmarks[1]) winmarks[1] = c;
           34  +					if (c == winmarks[1]) M->container->top = c;
           35  +					numC = 1;
           36  +				}
           37  +			}
           38  +		}
           39  +		else { /* {r/b}stack: */
           40  +			c = clients;
           41  +			M->occ = 0;
           42  +			for (numC = 0, C = M->container; C; C = C->next, numC++) {
           43  +				cn = (M->mode == MONOCLE ? 1024 : (C->n > 0 ? C->n : 1024));
           44  +				t = NULL;
           45  +				for (num = 0, pc = c; c && num < cn; c = c->next) {
           46  +					/* fill C up to max clients */
           47  +					M->occ |= (c->tags & 0xFFFF);
           48  +					if (tile_check(M, c)) {
           49  +						num++;
           50  +						/* set C->top */
           51  +						if (!winmarks[1]) winmarks[1] = c;
           52  +						if (c == winmarks[1]) {
           53  +							M->focus = C;
           54  +							C->top = c;
           55  +						}
           56  +						if (!t) t = c;
           57  +						if (c == C->top) t = c;
           58  +					}
           59  +				}
           60  +				if (num == 0) break;
           61  +				C->top = t;
           62  +			}
           63  +		}
           64  +		sbar_tags(M);
           65  +		/* tile each used container, hide others */
           66  +		c = clients;
           67  +		for (ord = 0, C = M->container; C && c; C = C->next, ord++) {
           68  +			cn = (M->mode == MONOCLE ? 1024 : (C->n > 0 ? C->n : 1024));
           69  +			for (num = 0, pc = c; c && num < cn; c = c->next)
           70  +				if (tile_check(M, c)) num++;
           71  +			if (!num) break;
           72  +			resize_container(M, C, numC, ord);
           73  +			tile_container(M, C, pc, num);
           74  +		}
           75  +		for (C; C; C = C->next) {
           76  +			purgatory(C->win);
           77  +			C->top = NULL;
           78  +		}
           79  +		/* show bar if no containers are visible */
           80  +		if (!numC && !(conf.bar_opts & BAR_HIDE)) {
           81  +			C = M->container;
           82  +			C->x = M->x + M->margin.left;
           83  +			C->y = M->y + (conf.bar_opts & BAR_BOTTOM ?
           84  +					M->h - C->bar->h - M->margin.bottom :
           85  +					M->margin.top);
           86  +			C->w = M->w - M->margin.left - M->margin.right;
           87  +			XMoveResizeWindow(dpy, C->win, C->x, C->y, C->w, C->bar->h);
           88  +			cairo_set_source_surface(C->bar->ctx, M->bg,
           89  +					M->x - C->x, M->y - C->y);
           90  +			cairo_paint(C->bar->ctx);
           91  +		}
           92  +		/* sort floating windows */
           93  +		for (c = clients ; c; c = c->next) {
           94  +			if (!(M->tags & c->tags)) continue;
           95  +			else if (c->flags & WIN_FULL_TEST) {
           96  +				if ( !winmarks[1] || !(winmarks[1]->flags & WIN_FLOAT))
           97  +					winmarks[1] = c;
           98  +				XMoveResizeWindow(dpy, c->win, M->x, M->y, M->w, M->h);
           99  +			}
          100  +			else if (c->flags & WIN_FLOAT) {
          101  +				XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
          102  +			}
          103  +		}
          104  +		if (!M->focus) M->focus = M->container;
          105  +	}
          106  +	for (c = clients; c; c = c->next) {
          107  +		if (!(c->tags & mview)) purgatory(c->win);
          108  +	}
          109  +	draw_bars(False);
          110  +	set_focus();
          111  +	return 0;
          112  +}
          113  +
          114  +
          115  +int resize_container(Monitor *M, Container *C, int numC, int ord) {
          116  +	/* get tileable region */
          117  +	int x = M->x + M->margin.left;
          118  +	int y = M->y + M->margin.top;
          119  +	int w = M->w - M->margin.left - M->margin.right;
          120  +	int h = M->h - M->margin.top - M->margin.bottom;
          121  +	int stack_size;
          122  +	/* pad for status bars */
          123  +	if (!ord) C->left_pad = sbar[0].w + sbar[1].w + M->tbar.w;
          124  +	C->right_pad = 0;
          125  +	if (ord == 1 || numC == 1) C->right_pad += sbar[2].w;
          126  +	if (ord == numC - 1 || numC == 1) C->right_pad += sbar[3].w;
          127  +	/* calculate for each tiling mode */
          128  +	if (numC == 1) { /* only one container */
          129  +		C->x = x + M->gap;
          130  +		C->y = y + M->gap;
          131  +		C->w = w - 2 * M->gap;
          132  +		C->h = h - 2 * M->gap;
          133  +	}
          134  +	else if (M->mode == RSTACK) {
          135  +		stack_size = (h - M->gap) / (numC - 1) - M->gap;
          136  +		C->x = x + M->gap + (ord ? (w -  M->gap) / 2 + M->split: 0);
          137  +		C->y = y + M->gap + (stack_size + M->gap) * (ord ? ord - 1 : 0);
          138  +		C->w = (ord ? x + w - M->gap - C->x :
          139  +				(w - M->gap) / 2 - M->gap + M->split);
          140  +		C->h = (ord ? stack_size : h - 2 * M->gap);
          141  +		if (ord == numC - 1) C->h = h - M->gap - C->y + y;
          142  +	}
          143  +	else if (M->mode == BSTACK) {
          144  +		stack_size = (w - M->gap) / (numC - 1) - M->gap;
          145  +		C->x = x + M->gap + (stack_size + M->gap) * (ord ? ord - 1 : 0);
          146  +		C->y = y + M->gap + (ord ? (h -  M->gap) / 2 + M->split: 0);
          147  +		C->w = (ord ? stack_size : w - 2 * M->gap);
          148  +		C->h = (ord ? y + h - M->gap - C->y :
          149  +				(h - M->gap) / 2 - M->gap + M->split);
          150  +		if (ord == numC - 1) C->w = w - M->gap - C->x + x;
          151  +	}
          152  +	/* adjust for bar space */
          153  +	if (!(C->bar->opts & BAR_HIDE)) {
          154  +		C->h -= C->bar->h;
          155  +		if (!(C->bar->opts & BAR_BOTTOM))
          156  +			C->y += C->bar->h;
          157  +	}
          158  +	/* hide/show the bar */
          159  +	if (C->bar->opts & BAR_HIDE) purgatory(C->win);
          160  +	else {
          161  +		int y = (C->bar->opts & BAR_BOTTOM ? C->y+C->h : C->y-C->bar->h);
          162  +		XMoveResizeWindow(dpy, C->win, C->x, y, C->w, C->bar->h);
          163  +		cairo_set_source_surface(C->bar->ctx, M->bg, M->x - C->x, M->y - y);
          164  +		cairo_paint(C->bar->ctx);
          165  +	}
          166  +}
          167  +
          168  +Bool tile_check(Monitor *M, Client *c) {
          169  +	return ((M->tags & c->tags) && !(c->flags & WIN_FLOAT));
          170  +}
          171  +
          172  +int tile_container(Monitor *M, Container *C, Client *pc, int num) {
          173  +	Client *c, *t = NULL;
          174  +	int n;
          175  +	for (c = pc, n = num; c && n; c = c->next) if (tile_check(M, c)) {
          176  +		XMoveResizeWindow(dpy, c->win, C->x, C->y, C->w, C->h);
          177  +		if (!(C->bar->opts & BAR_HIDE))
          178  +			draw_tab(C, c, num - n, num, C->bar->opts & BAR_BOTTOM);
          179  +		n--;
          180  +	}
          181  +}

Added src/xlib.c.

            1  +
            2  +#include "alopex.h"
            3  +#include "actions.h"
            4  +
            5  +#define SELECT_EVENTS	\
            6  +	ExposureMask | FocusChangeMask | ButtonReleaseMask | \
            7  +	SubstructureNotifyMask | SubstructureRedirectMask | \
            8  +	StructureNotifyMask | PropertyChangeMask | EnterWindowMask
            9  +
           10  +#define GRABMODE	GrabModeAsync, GrabModeAsync
           11  +#define GRABMODE2	ButtonPressMask, GrabModeAsync, GrabModeAsync, \
           12  +	None, None
           13  +
           14  +extern int config_init(const char *);
           15  +extern int config_free();
           16  +extern int draw_bars(Bool);
           17  +extern int sbar_parse(Bar *, const char *);
           18  +extern char *get_text(Client *, int);
           19  +
           20  +static int apply_rules(Client *);
           21  +static int get_hints(Client *);
           22  +static int get_icon(Client *);
           23  +static int get_name(Client *);
           24  +static int get_size(Client *);
           25  +
           26  +static void buttonpress(XEvent *);
           27  +static void configurerequest(XEvent *);
           28  +static void enternotify(XEvent *);
           29  +static void expose(XEvent *);
           30  +static void keypress(XEvent *);
           31  +static void propertynotify(XEvent *);
           32  +static void maprequest(XEvent *);
           33  +static void unmapnotify(XEvent *);
           34  +
           35  +static int purgX, purgY;
           36  +static void (*handler[LASTEvent]) (XEvent *) = {
           37  +	[ButtonPress]       = buttonpress,
           38  +	[ConfigureRequest]  = configurerequest,
           39  +	[EnterNotify]       = enternotify,
           40  +	[Expose]            = expose,
           41  +	[KeyPress]          = keypress,
           42  +	[MapRequest]        = maprequest,
           43  +	[PropertyNotify]    = propertynotify,
           44  +	[UnmapNotify]       = unmapnotify,
           45  +};
           46  +
           47  +int free_mons(const char *bg, const char *cont) {
           48  +	int i;
           49  +	Monitor *M;
           50  +	Container *C;
           51  +	for (M = mons; M; M = M->next) {
           52  +		for (C = M->container; C; C = C->next) {
           53  +			cairo_destroy(C->bar->ctx);
           54  +			cairo_surface_destroy(C->bar->buf);
           55  +			free(C->bar);
           56  +			cairo_destroy(C->ctx);
           57  +			XDestroyWindow(dpy, C->win);
           58  +		}
           59  +		cairo_destroy(M->tbar.ctx);
           60  +		cairo_surface_destroy(M->tbar.buf);
           61  +		free(M->container);
           62  +		cairo_surface_destroy(M->bg);
           63  +	}
           64  +	for (i = 0; i < MAX_STATUS; i++) {
           65  +		cairo_destroy(sbar[i].ctx);
           66  +		cairo_surface_destroy(sbar[i].buf);
           67  +	}
           68  +	free(mons);
           69  +	return 0;
           70  +}
           71  +
           72  +int get_mons(const char *bg, const char *cont) {
           73  +	/* get container counts */
           74  +	int i, j, n, *counts = NULL, ncounts;
           75  +	char *tok = NULL, *tmp = strdup(cont);
           76  +	tok = strtok(tmp," ");
           77  +	for (i = 0; tok; i++) {
           78  +		counts = realloc(counts, (i+1) * sizeof(int *));
           79  +		counts[i] = atoi(tok);
           80  +		tok = strtok(NULL," ");
           81  +	}
           82  +	free(tmp);
           83  +	counts = realloc(counts, (i+1) * sizeof(int *));
           84  +	counts[i] = -1;
           85  +	ncounts = i+1;
           86  +	/* get monitor geometries */
           87  +	mons = NULL;
           88  +	XineramaScreenInfo *geom = XineramaQueryScreens(dpy, &n);
           89  +	int minX = 0, minY = 0, maxX = 0, maxY = 0;
           90  +	for(i = 0; i < n; i++) {
           91  +		mons = realloc(mons, (i+1) * sizeof(Monitor));
           92  +		memset(&mons[i], 0, sizeof(Monitor));
           93  +		mons[i].x = geom[i].x_org;
           94  +		mons[i].y = geom[i].y_org;
           95  +		mons[i].w = geom[i].width;
           96  +		mons[i].h = geom[i].height;
           97  +		if (minX > mons[i].x) minX = mons[i].x;
           98  +		if (minY > mons[i].y) minY = mons[i].y;
           99  +		if (maxX < mons[i].x + mons[i].w) maxX = mons[i].x + mons[i].w;
          100  +		if (maxY < mons[i].y + mons[i].h) maxY = mons[i].y + mons[i].h;
          101  +	}
          102  +	/* create monitors and set background */
          103  +	cairo_surface_t *src, *dest;
          104  +	src = cairo_image_surface_create_from_png(bg);
          105  +	if (cairo_surface_status(src) != CAIRO_STATUS_SUCCESS) {
          106  +		src = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, maxX, maxY);
          107  +		cairo_t *blank = cairo_create(src);
          108  +		cairo_set_source_rgba(blank, 0, 0, 0, 1);
          109  +		cairo_paint(blank);
          110  +		cairo_destroy(blank);
          111  +	}
          112  +	int imgw = cairo_image_surface_get_width(src);
          113  +	int imgh = cairo_image_surface_get_height(src);
          114  +	Pixmap pix = XCreatePixmap(dpy, root, maxX-minX, maxY-minY,
          115  +			DefaultDepth(dpy,scr));
          116  +	dest = cairo_xlib_surface_create(dpy, pix, DefaultVisual(dpy,scr),
          117  +			maxX-minX, maxY-minY);
          118  +	cairo_t *ctx, *rctx;
          119  +	rctx = cairo_create(dest);
          120  +	Monitor *M;
          121  +	XWindowChanges wc;
          122  +	wc.stack_mode = Below;
          123  +	for(i = 0; i < n; i++) {
          124  +		M = &mons[i];
          125  +		if (i < n - 1) M->next = &mons[i+1];
          126  +		M->gap = conf.gap;
          127  +		M->split = conf.split;
          128  +		M->container = calloc(ncounts, sizeof(Container));
          129  +		M->focus = mons[i].container;
          130  +		M->mode = conf.mode;
          131  +		M->bg = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,M->w,M->h);
          132  +		M->margin = conf.margin;
          133  +		/* paint monitor bg */
          134  +		ctx = cairo_create(M->bg);
          135  +		cairo_scale(ctx, M->w / (float) imgw, M->h / (float) imgh);
          136  +		cairo_set_source_surface(ctx, src, 0, 0);
          137  +		cairo_paint(ctx);
          138  +		cairo_destroy(ctx);
          139  +		/* paint root pixmap */
          140  +		cairo_save(rctx);
          141  +		cairo_translate(rctx, M->x, M->y);
          142  +		cairo_scale(rctx, M->w / (float) imgw, M->h / (float) imgh);
          143  +		cairo_set_source_surface(rctx, src, 0, 0);
          144  +		cairo_paint(rctx);
          145  +		cairo_restore(rctx);
          146  +		Container *C;
          147  +		cairo_surface_t *t;
          148  +		for (j = 0; j < ncounts; j++) {
          149  +			C = &M->container[j];
          150  +			if (j < ncounts - 1) C->next = &M->container[j+1];
          151  +			C->n = counts[j];
          152  +			C->nn = C->n;
          153  +			C->bar = calloc(1, sizeof(Bar));
          154  +			C->bar->opts = conf.bar_opts;
          155  +			C->bar->w = M->w;
          156  +			C->bar->h = conf.bar_opts & BAR_HEIGHT;
          157  +			C->bar->buf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
          158  +					C->bar->w, C->bar->h);
          159  +			C->bar->ctx = cairo_create(C->bar->buf);
          160  +			cairo_set_font_face(C->bar->ctx, conf.font);
          161  +			cairo_set_font_size(C->bar->ctx, conf.font_size);
          162  +			C->win = XCreateSimpleWindow(dpy,root,0,0,M->w,C->bar->h,0,0,0);
          163  +			if (j == 0) wc.sibling = C->win;
          164  +			else XConfigureWindow(dpy, C->win, CWSibling | CWStackMode, &wc);
          165  +			XSelectInput(dpy, C->win, SELECT_EVENTS);
          166  +			t = cairo_xlib_surface_create(dpy, C->win,
          167  +					DefaultVisual(dpy,scr), M->w, C->bar->h);
          168  +			C->ctx = cairo_create(t);
          169  +			cairo_surface_destroy(t);
          170  +			XMapWindow(dpy, C->win);
          171  +		}
          172  +		M->tbar.buf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
          173  +				mons->w / 2, conf.bar_opts & BAR_HEIGHT);
          174  +		M->tbar.ctx = cairo_create(M->tbar.buf);
          175  +		M->tbar.h = conf.bar_opts & BAR_HEIGHT;
          176  +		cairo_set_font_face(M->tbar.ctx, conf.font);
          177  +		cairo_set_font_size(M->tbar.ctx, conf.font_size);
          178  +	}
          179  +	for (i = 0; i < MAX_STATUS; i++) {
          180  +		sbar[i].buf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
          181  +				mons->w / 2, conf.bar_opts & BAR_HEIGHT);
          182  +		sbar[i].ctx = cairo_create(sbar[i].buf);
          183  +		sbar[i].h = conf.bar_opts & BAR_HEIGHT;
          184  +		cairo_set_font_face(sbar[i].ctx, conf.font);
          185  +		cairo_set_font_size(sbar[i].ctx, conf.font_size);
          186  +	}
          187  +	cairo_surface_destroy(src);
          188  +	cairo_surface_destroy(dest);
          189  +	cairo_destroy(rctx);
          190  +	XSetWindowBackgroundPixmap(dpy, root, pix);
          191  +	XFreePixmap(dpy, pix);
          192  +	m = mons;
          193  +	free(counts);
          194  +	return 0;
          195  +}
          196  +
          197  +#define MAX_LINE	256
          198  +int main_loop() {
          199  +	char line[MAX_LINE], *c;
          200  +	fd_set fds;
          201  +	int n, redraw, ret;
          202  +	int xfd = ConnectionNumber(dpy);
          203  +	int nfd = (conf.statfd > xfd ? conf.statfd : xfd) + 1;
          204  +	XEvent ev;
          205  +	while (running) {
          206  +		FD_ZERO(&fds);
          207  +		FD_SET(xfd, &fds);
          208  +		FD_SET(conf.statfd, &fds);
          209  +		select(nfd, &fds, 0, 0, NULL);
          210  +		if (conf.statfd && FD_ISSET(conf.statfd, &fds)) {
          211  +			fgets(line, MAX_LINE, conf.stat);
          212  +			redraw = sbar_parse(&sbar[(n=0)], (c=line));
          213  +			while ( (c=strchr(c, '&')) && (++n) < MAX_STATUS)
          214  +				redraw += sbar_parse(&sbar[n], (++c));
          215  +			if (redraw) tile();
          216  +			else draw_bars(True);
          217  +			XFlush(dpy);
          218  +		}
          219  +		if (FD_ISSET(xfd, &fds)) while (XPending(dpy)) {
          220  +			XNextEvent(dpy, &ev);
          221  +			if (ev.type < LASTEvent && handler[ev.type])
          222  +				handler[ev.type](&ev);
          223  +		}
          224  +	}
          225  +	return 0;
          226  +}
          227  +
          228  +int purgatory(Window w) {
          229  +	XMoveWindow(dpy, w, purgX, purgY);
          230  +}
          231  +
          232  +int set_focus() {
          233  +	Client *cc, *c = winmarks[1];
          234  +	if (!c) return 1;
          235  +	Window win; int rev;
          236  +	/* raise window */
          237  +	if (c->flags & WIN_FLOAT) {
          238  +		XWindowChanges wc;
          239  +		wc.stack_mode = Above;
          240  +		wc.sibling = m->container->win;
          241  +		XConfigureWindow(dpy, c->win, CWSibling | CWStackMode, &wc);
          242  +		for (cc = clients; cc; cc = cc->next) {
          243  +			if (cc->tags & m->tags && (cc->flags & WIN_FLOAT)) {
          244  +				wc.sibling = cc->win;
          245  +				XConfigureWindow(dpy, c->win, CWSibling | CWStackMode, &wc);
          246  +			}
          247  +		}
          248  +		wc.sibling = c->win;
          249  +		for (cc = clients; cc; cc = cc->next) {
          250  +			if (cc->parent == c->win)
          251  +				XConfigureWindow(dpy, cc->win, CWSibling | CWStackMode, &wc);
          252  +		}
          253  +	}
          254  +	else {
          255  +		XWindowChanges wc;
          256  +		wc.sibling = m->container->win;
          257  +		wc.stack_mode = Below;
          258  +		XConfigureWindow(dpy, c->win, CWSibling | CWStackMode, &wc);
          259  +	}
          260  +	/* set input focus */
          261  +	if (c->flags & WIN_FOCUS) send_message(c, WM_PROTOCOLS, WM_TAKE_FOCUS);
          262  +	else XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
          263  +	c->flags &= ~WIN_URGENT;
          264  +	return 0;
          265  +}
          266  +
          267  +Client *wintoclient(Window w) {
          268  +	Client *c;
          269  +	for (c = clients; c; c = c->next)
          270  +		if (c->win == w) return c;
          271  +	return NULL;
          272  +}
          273  +
          274  +int xerror(Display *d, XErrorEvent *e) {
          275  +	char msg[1024];
          276  +	XGetErrorText(d, e->error_code, msg, sizeof(msg));
          277  +	fprintf(stderr,"[X11 %d:%d] %s\n",
          278  +			e->request_code, e->error_code, msg);
          279  +}
          280  +
          281  +int xlib_init(const char *theme_name) {
          282  +	/* INITS */
          283  +	if (!setlocale(LC_CTYPE,"")) die("unable to set locale");
          284  +	if (!XSupportsLocale()) die("unsupported locale");
          285  +	if (!XSetLocaleModifiers("")) die("unable to set locale modifiers");
          286  +	if (!(dpy=XOpenDisplay(0x0))) die("unable to open X display");
          287  +	if (FT_Init_FreeType(&ftlib)) die("unable to init freetype");
          288  +	/* GLOBALS */
          289  +	scr = DefaultScreen(dpy);
          290  +	root = DefaultRootWindow(dpy);
          291  +	XSetErrorHandler(xerror);
          292  +	XDefineCursor(dpy, root, XCreateFontCursor(dpy,68));
          293  +	gc = DefaultGC(dpy, scr);
          294  +	/* CONFIG */
          295  +	config_init(theme_name);
          296  +	Monitor *M;
          297  +	for (M = mons; M; M = M->next) {
          298  +		if (M->x + M->w > purgX) purgX = M->x + M->w + 10;
          299  +		if (M->y + M->h > purgY) purgY = M->y + M->h + 10;
          300  +	}
          301  +	XClearWindow(dpy,root);
          302  +	/* BINDING + GRABS */
          303  +	XSelectInput(dpy, root, SELECT_EVENTS);
          304  +	unsigned int mod[] = {0, LockMask, Mod2Mask, LockMask|Mod2Mask};
          305  +	KeyCode code;
          306  +	Key *key;
          307  +	XUngrabKey(dpy, AnyKey, AnyModifier, root);
          308  +	XSync(dpy,True);
          309  +	int i, j;
          310  +	for (i = 0; i < conf.nkeys; i++) {
          311  +		key = &conf.key[i];
          312  +		if ( (code=XKeysymToKeycode(dpy, key->keysym)) ) {
          313  +			for (j = 0; j < 4; j++)
          314  +				XGrabKey(dpy, code, key->mod|mod[j], root, True, GRABMODE);
          315  +		}
          316  +	}
          317  +	for (j = 0; j < 4; j++) {
          318  +		XGrabButton(dpy,1,Mod4Mask|mod[j],root,True,GRABMODE2);
          319  +		XGrabButton(dpy,2,Mod4Mask|mod[j],root,True,GRABMODE2);
          320  +		XGrabButton(dpy,3,Mod4Mask|mod[j],root,True,GRABMODE2);
          321  +	}
          322  +	memset(winmarks, 0, 10*sizeof(Client *));
          323  +	tile();
          324  +	XFlush(dpy);
          325  +	running = True;
          326  +	atoms_init();
          327  +	return 0;
          328  +}
          329  +
          330  +int xlib_free() {
          331  +	Client *c;
          332  +	for (c = clients; c; c = c->next) killclient(c, NULL);
          333  +	XUngrabKey(dpy, AnyKey, AnyModifier, root);
          334  +	XUngrabButton(dpy, AnyButton, AnyModifier, root);
          335  +	XFlush(dpy);
          336  +	config_free();
          337  +	FT_Done_FreeType(ftlib);
          338  +	XCloseDisplay(dpy);
          339  +	return 0;
          340  +}
          341  +
          342  +/**** LOCAL FUNCTIONS ****/
          343  +
          344  +int apply_rules(Client *c) {
          345  +	XClassHint *hint = XAllocClassHint();
          346  +	XGetClassHint(dpy, c->win, hint);
          347  +	int i, m;
          348  +	const char *rc, *rn, *hc = hint->res_class, *hn = hint->res_name;
          349  +	for (i = 0; i < conf.nrules; i++) {
          350  +		rc = conf.rule[i].class;
          351  +		rn = conf.rule[i].name;
          352  +		m = 0;
          353  +		if (rc && hc && !strncmp(rc, hc, strlen(rc))) m++;
          354  +		if (rn && hn && !strncmp(rn, hn, strlen(rn))) m++;
          355  +		if ( (m && !(rc && rn)) || (m == 2) ) {
          356  +			if (conf.rule[i].tags > 0) c->tags = conf.rule[i].tags;
          357  +			c->flags |= conf.rule[i].flags;
          358  +		}
          359  +	}
          360  +	XFree(hint);
          361  +	return 0;
          362  +}
          363  +
          364  +int get_hints(Client *c) {
          365  +	XWMHints *hint;
          366  +	if ( !(hint = XGetWMHints(dpy,c->win)) ) return;
          367  +	if (hint->flags & XUrgencyHint) c->flags |= WIN_URGENT;
          368  +	if (hint->flags & InputHint && !hint->input) c->flags |= WIN_FOCUS;
          369  +	if (hint->flags & (IconPixmapHint | IconMaskHint)) get_icon(c);
          370  +	XFree(hint);
          371  +	// TODO EWMH checks ??
          372  +	return 0;
          373  +}
          374  +
          375  +int get_icon(Client *c) {
          376  +	XWMHints *hint;
          377  +	if (!(hint=XGetWMHints(dpy,c->win))) return;
          378  +	if (!(hint->flags & (IconPixmapHint | IconMaskHint))) return;
          379  +	if (c->icon) { cairo_surface_destroy(c->icon); c->icon = NULL; }
          380  +	int w, h, ig, sz = conf.font_size;
          381  +	Window wig;
          382  +	XGetGeometry(dpy, hint->icon_pixmap, &wig, &ig, &ig, &w, &h, &ig, &ig);
          383  +	if (c->icon) cairo_surface_destroy(c->icon);
          384  +	cairo_surface_t *icon, *mask = NULL;
          385  +	icon = cairo_xlib_surface_create(dpy, hint->icon_pixmap,
          386  +			DefaultVisual(dpy,scr), w, h);
          387  +	if (hint->flags & IconMaskHint)
          388  +	mask = cairo_xlib_surface_create_for_bitmap(dpy,
          389  +			hint->icon_mask, DefaultScreenOfDisplay(dpy), w, h);
          390  +	c->icon = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, sz, sz);
          391  +	cairo_t *ctx = cairo_create(c->icon);
          392  +	cairo_scale(ctx, sz / (double) w, sz / (double) h);
          393  +	cairo_set_source_surface(ctx, icon, 0, 0);
          394  +	if (mask) cairo_mask_surface(ctx, mask, 0, 0);
          395  +	else cairo_paint(ctx);
          396  +	cairo_destroy(ctx);
          397  +	cairo_surface_destroy(icon);
          398  +	if (mask) cairo_surface_destroy(mask);
          399  +	return 0;
          400  +}
          401  +
          402  +int get_name(Client *c) {
          403  +	static const char *noname = "(no name)";
          404  +	Client *p;
          405  +	if (c->title && c->title != noname) XFree(c->title);
          406  +	if ( !(c->title=get_text(c,NET_WM_NAME)) )
          407  +		if ( !(c->title=get_text(c,WM_NAME)) )
          408  +			c->title = strdup(noname);
          409  +	return 0;
          410  +}
          411  +
          412  +int get_size(Client *c) {
          413  +	long ret = 0;
          414  +	XSizeHints hint;
          415  +	if (!(XGetWMNormalHints(dpy,c->win,&hint,&ret))) return 0;
          416  +	if (hint.flags & PSize) {
          417  +		c->w = hint.width; c->h = hint.height;
          418  +	}
          419  +	if (hint.flags & PBaseSize) {
          420  +		c->w = hint.base_width; c->h = hint.base_height;
          421  +	}
          422  +	if (hint.flags & PMinSize) {
          423  +		if (c->w < hint.min_width) c->w = hint.min_width;
          424  +		if (c->h < hint.min_height) c->h = hint.min_height;
          425  +	}
          426  +	return 0;
          427  +}
          428  +
          429  +/**** EVENT HANDLERS ****/
          430  +
          431  +void buttonpress(XEvent *ev) {
          432  +	XButtonEvent *e = &ev->xbutton;
          433  +	Client *c;
          434  +	if ( !(c=wintoclient(e->subwindow)) ) return;
          435  +	if (c->flags & WIN_FLOAT) XRaiseWindow(dpy, c->win);
          436  +	if (c != winmarks[1]) {
          437  +		winmarks[0] = winmarks[1];
          438  +		winmarks[1] = c;
          439  +		tile();
          440  +	}
          441  +	int b = e->button;
          442  +	if (b > 3) return;
          443  +	c->flags &= ~WIN_FULL;
          444  +	if (b == 2) {
          445  +		tile();
          446  +		return;
          447  +	}
          448  +	XGrabPointer(dpy, root, True, PointerMotionMask | ButtonReleaseMask,
          449  +			GRABMODE, None, None, CurrentTime);
          450  +	XEvent ee;
          451  +	int dx, dy;
          452  +	int xx = e->x_root, yy = e->y_root;
          453  +	while (True) {
          454  +		expose(ev);
          455  +		XMaskEvent(dpy, PointerMotionMask | ButtonReleaseMask, &ee);
          456  +		if (ee.type == ButtonRelease) break;
          457  +		if (!(c->flags & WIN_FLOAT)) {
          458  +			c->flags |= WIN_FLOAT;
          459  +			tile();
          460  +			if (xx < c->x) c->x = xx;
          461  +			if (xx > c->x + c->w) c->x = xx - c->w;
          462  +			if (yy < c->y) c->y = yy;
          463  +			if (yy > c->y + c->h) c->y = yy - c->h;
          464  +		}
          465  +		XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
          466  +		dx = ee.xbutton.x_root - xx; xx = ee.xbutton.x_root;
          467  +		dy = ee.xbutton.y_root - yy; yy = ee.xbutton.y_root;
          468  +		if (b == 1) { c->x += dx; c->y += dy; }
          469  +		else if (b == 3) { c->w += dx; c->h += dy; }
          470  +	}
          471  +	XUngrabPointer(dpy, CurrentTime);
          472  +}
          473  +
          474  +void configurerequest(XEvent *ev) {
          475  +	XConfigureRequestEvent *e = &ev->xconfigurerequest;
          476  +	Client *c;
          477  +	XWindowChanges wc;
          478  +	if ( (c=wintoclient(e->window)) ) {
          479  +		if (e->value_mask & CWX) c->x = e->x;
          480  +		if (e->value_mask & CWY) c->y = e->y;
          481  +		if (e->value_mask & CWWidth) c->w = e->width;
          482  +		if (e->value_mask & CWHeight) c->h = e->height;
          483  +		if (c->flags & WIN_FULL_TEST) {
          484  +			c->flags &= ~WIN_FULL;
          485  +			c->flags |= WIN_FLOAT;
          486  +		}
          487  +		if (c->w == m->w && c->h == m->h) c->flags |= WIN_FULL;
          488  +		/* Let gtk3 windows know we're listening: */
          489  +		XConfigureEvent cn;
          490  +		cn.type = ConfigureNotify; cn.display = dpy;
          491  +		cn.event = cn.window = c->win;
          492  +		cn.x = c->x; cn.y = c->y; cn.width = c->w; cn.height = c->h;
          493  +		cn.border_width = 0;
          494  +		cn.above = None;
          495  +		cn.override_redirect = False;
          496  +		XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&cn);
          497  +	}
          498  +	else {
          499  +		wc.x=e->x; wc.y=e->y; wc.width=e->width; wc.height=e->height;
          500  +		wc.sibling = e->above;
          501  +		wc.stack_mode = e->detail;
          502  +		wc.border_width = e->border_width;
          503  +		XConfigureWindow(dpy, e->window, e->value_mask, &wc);
          504  +	}
          505  +	tile();
          506  +}
          507  +
          508  +void enternotify(XEvent *ev) {
          509  +	if (mons->next) {
          510  +		int x = ev->xcrossing.x_root;
          511  +		int y = ev->xcrossing.y_root;
          512  +		Monitor *M;
          513  +		for (M = mons; M; M = M->next) {
          514  +			if (M->x < x && M->x + M->w > x && M->y < y && M->y + M->h > y)
          515  +				m = M;
          516  +		}
          517  +	}
          518  +	if (!conf.focus_follow) return;
          519  +	Client *c = wintoclient(ev->xcrossing.window);
          520  +	if (!c) return;
          521  +	Container *C;
          522  +	for (C = m->container; C; C = C->next)
          523  +		if (C->top && C->top == c) m->focus = C;
          524  +	tile();
          525  +}
          526  +
          527  +void expose(XEvent *ev) {
          528  +	Monitor *M; Container *C;
          529  +	for (M = mons; M; M = M->next) {
          530  +		for (C = M->container; C; C = C->next){
          531  +			cairo_set_source_surface(C->ctx, C->bar->buf, 0, 0);
          532  +			cairo_paint(C->ctx);
          533  +		}
          534  +	}
          535  +}
          536  +
          537  +void keypress(XEvent *ev) {
          538  +	int i;
          539  +	XKeyEvent *e = &ev->xkey;
          540  +	KeySym sym = XkbKeycodeToKeysym(dpy, e->keycode, 0, 0);
          541  +	for (i = 0; i < conf.nkeys; i++) {
          542  +		if ( (sym==conf.key[i].keysym) && (conf.key[i].arg) &&
          543  +				conf.key[i].mod == ((e->state&~Mod2Mask)&~LockMask) ) {
          544  +			command(conf.key[i].arg);
          545  +		}
          546  +	}
          547  +}
          548  +
          549  +void maprequest(XEvent *ev) {
          550  +	XMapRequestEvent *e = &ev->xmaprequest;
          551  +	XWindowAttributes wa;
          552  +	if (	!XGetWindowAttributes(dpy, e->window, &wa) ||
          553  +			wa.override_redirect ) return;
          554  +	Client *c;
          555  +	if ( (c=wintoclient(e->window)) ) return;
          556  +	c = calloc(1, sizeof(Client));
          557  +	c->win = e->window;
          558  +	get_hints(c);
          559  +	get_icon(c);
          560  +	get_name(c);
          561  +	apply_rules(c);
          562  +	if (!c->tags && !(c->tags=m->tags)) {
          563  +		Monitor *M;
          564  +		int i, tags = 0;
          565  +		for (M = mons; M; M = M->next) tags |= M->tags;
          566  +		for (i = 0; ((1<<i) & tags) && i < 9; i++);
          567  +		c->tags = m->tags = (1<<i);
          568  +	}
          569  +	if (XGetTransientForHint(dpy, c->win, &c->parent))
          570  +		c->flags |= WIN_TRANS;
          571  +	else
          572  +		c->parent = e->parent;
          573  +	c->x = wa.x; c->y = wa.y; c->w = wa.width; c->h = wa.height;
          574  +	if (c->w == m->w && c->h == m->h) c->flags |= WIN_FULL;
          575  +	XSelectInput(dpy, c->win, PropertyChangeMask | EnterWindowMask);
          576  +	Client *p;
          577  +	switch (conf.attach) {
          578  +		case ATTACH_TOP: c->next = clients; clients = c; break;
          579  +		case ATTACH_BOTTOM: push_client(c, NULL); break;
          580  +		case ATTACH_ABOVE: push_client(c, m->focus->top); break;
          581  +		case ATTACH_BELOW: push_client(c, m->focus->top->next); break;
          582  +	}
          583  +	winmarks[0] = winmarks[1];
          584  +	winmarks[1] = c;
          585  +	purgatory(c->win);
          586  +	XMapWindow(dpy, c->win);
          587  +	tile();
          588  +}
          589  +
          590  +void propertynotify(XEvent *ev) {
          591  +	XPropertyEvent *e = &ev->xproperty;
          592  +	Client *c;
          593  +	if (e->window == root) {
          594  +		char *cmd;
          595  +		if (!XFetchName(dpy, root, &cmd)) return;
          596  +		if (strncmp("ALOPEX: ", cmd, 8) == 0) {
          597  +			XStoreName(dpy, root, "");
          598  +			command(cmd + 8);
          599  +		}
          600  +		if (cmd) XFree(cmd);
          601  +		return;
          602  +	}
          603  +	if ( !(c=wintoclient(e->window)) ) return;
          604  +	if (e->atom == XA_WM_NAME) get_name(c);
          605  +	else if (e->atom == XA_WM_HINTS) get_hints(c);
          606  +	else if (e->atom == XA_WM_CLASS) apply_rules(c);
          607  +	else if (e->atom == XA_WM_NORMAL_HINTS) get_size(c);
          608  +	// TODO:
          609  +	// icon ?
          610  +	// netWM
          611  +	// XA_TRANSIENT_FOR
          612  +	else return;
          613  +	tile();
          614  +}
          615  +
          616  +void unmapnotify(XEvent *ev) {
          617  +	Client *c, *t;
          618  +	XUnmapEvent *e = &ev->xunmap;
          619  +	if (!(c=wintoclient(e->window))) return;
          620  +	winmarks[1] = winmarks[0];
          621  +	winmarks[0] = NULL;
          622  +	if (c == clients) clients = c->next;
          623  +	else {
          624  +		for (t = clients; t && t->next && t->next != c; t = t->next);
          625  +		t->next = c->next;
          626  +	}
          627  +	XFree(c->title);
          628  +	free(c); c = NULL;
          629  +	tile();
          630  +}
          631  +

Added stat.

            1  +#!/bin/bash
            2  +# ridiculously simple example status script
            3  +# for a better example written in C, see:
            4  +#   https://github.com/TrilbyWhite/junkdrawer/blob/master/lagopus.c
            5  +
            6  +echo
            7  +sleep 10
            8  +while :; do echo "&& {i 11} $(date +%H:%M) &"; sleep 10; done

Deleted theme.h.

     1         -/* copyright J.McClure 2012-2013, see alopex.c or COPYING for details */
     2         -
     3         -static const char colors[LASTColor][9] = {
     4         -
     5         -#ifdef SummerCoat
     6         -#define THEME_NAME "SummerCoat"
     7         -	[Background]	= "#201814",
     8         -	[Default]		= "#686858",
     9         -	[Occupied]		= "#DDBB88",
    10         -	[Selected]		= "#EE8844",
    11         -	[Urgent]		= "#FFDD0E",
    12         -	[Title]			= "#EECCAA",
    13         -	[TabFocused]	= "#D0B072",
    14         -	[TabFocusedBG]	= "#242424",
    15         -	[TabTop]		= "#BB8844",
    16         -	[TabTopBG]		= "#242424",
    17         -	[TabDefault]	= "#686858",
    18         -	[TabDefaultBG]	= "#181818",
    19         -	[TagLine]		= "#FF4400",
    20         -#endif
    21         -
    22         -#ifdef DayLight
    23         -#define THEME_NAME "DayLight"
    24         -	[Background]	= "#FAF0E6",
    25         -	[Default]		= "#121212",
    26         -	[Occupied]		= "#A04222",
    27         -	[Selected]		= "#CD6839",
    28         -	[Urgent]		= "#FF4222",
    29         -	[Title]			= "#B13E0F",
    30         -	[TabFocused]	= "#FF7216",
    31         -	[TabFocusedBG]	= "#EEE5DE",
    32         -	[TabTop]		= "#FF7216",
    33         -	[TabTopBG]		= "#EEE5DE",
    34         -	[TabDefault]	= "#A04222",
    35         -	[TabDefaultBG]	= "#CDC5BF",
    36         -	[TagLine]		= "#FF4400",
    37         -#endif
    38         -
    39         -#ifdef WinterCoat 
    40         -#define THEME_NAME "WinterCoat"
    41         -	[Background]	= "#101010",
    42         -	[Default]		= "#686868",
    43         -	[Occupied]		= "#68A0DD",
    44         -	[Selected]		= "#BBE0EE",
    45         -	[Urgent]		= "#FF8880",
    46         -	[Title]			= "#DDDDDD",
    47         -	[TabFocused]	= "#68B0E0",
    48         -	[TabFocusedBG]	= "#242424",
    49         -	[TabTop]		= "#486488",
    50         -	[TabTopBG]		= "#242424",
    51         -	[TabDefault]	= "#686868",
    52         -	[TabDefaultBG]	= "#181818",
    53         -	[TagLine]		= "#2436AA",
    54         -#endif
    55         -
    56         -};
    57         -