├── LICENSE ├── README.md ├── etc └── skel │ └── .config │ └── arco-dwm │ ├── LICENSE │ ├── Makefile │ ├── README │ ├── autostart.sh │ ├── cheatsheet.md │ ├── config.def.h │ ├── config.h │ ├── config.mk │ ├── drw.c │ ├── drw.h │ ├── dwm.1 │ ├── dwm.c │ ├── dwm.png │ ├── launcher │ ├── launcher.sh │ └── rofi │ │ ├── colors.rasi │ │ └── launcher.rasi │ ├── layouts.c │ ├── list-of-patches.readme │ ├── picom.conf │ ├── rebuild.sh │ ├── scripts │ └── picom-toggle.sh │ ├── selfrestart.c │ ├── shiftview.c │ ├── sxhkd │ └── sxhkdrc │ ├── system-overview │ ├── transient.c │ ├── util.c │ └── util.h ├── make-package.sh ├── setup-our-git-credentials.sh ├── up.sh └── usr └── share ├── doc └── dwm │ └── README ├── licenses └── dwm │ └── LICENSE ├── man └── man1 │ └── dwm.1.gz └── xsessions └── dwm.desktop /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 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 . 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 | {project} Copyright (C) {year} {fullname} 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 | . 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 | . 675 | 676 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ArcoLinux desktop settings dwm 2 | 3 | --- 4 | 5 | ## 💛 A Grateful Farewell from the ArcoLinux Team 6 | 7 | After many years of building, sharing, and learning together, the **ArcoLinux project is winding down**. 8 | 9 | Although no new updates or packages will be released, we are proud of the knowledge, tools, and community that have grown around ArcoLinux. 10 | 11 | ### What's Staying Online ✅ 12 | 13 | - 🌐 **Websites** will remain accessible for several years 14 | - 🎥 **YouTube videos** will stay online and continue to serve as tutorials 15 | - 📦 **GitHub repositories** like this one will remain available as long as GitHub's free hosting allows 16 | 17 | ### Keep Using and Updating Your System 🛠️ 18 | 19 | ArcoLinux was always built on **Arch Linux**, which is a **rolling release**. 20 | This means your system can still be installed and updated using standard Arch tools and knowledge. 21 | 22 | ### Read More 23 | 24 | 🔗 [A Farewell to the ArcoLinux University](https://www.arcolinux.info/a-farewell-to-the-arcolinux-university/) 25 | 26 | --- 27 | 28 | **Thank you for being part of this journey.** 29 | Your curiosity, passion, and support made ArcoLinux what it was. 30 | 31 | — *The ArcoLinux Team* 32 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/LICENSE: -------------------------------------------------------------------------------- 1 | MIT/X Consortium License 2 | 3 | © 2006-2019 Anselm R Garbe 4 | © 2006-2009 Jukka Salmi 5 | © 2006-2007 Sander van Dijk 6 | © 2007-2011 Peter Hartlich 7 | © 2007-2009 Szabolcs Nagy 8 | © 2007-2009 Christof Musik 9 | © 2007-2009 Premysl Hruby 10 | © 2007-2008 Enno Gottox Boland 11 | © 2008 Martin Hurton 12 | © 2008 Neale Pickett 13 | © 2009 Mate Nagy 14 | © 2010-2016 Hiltjo Posthuma 15 | © 2010-2012 Connor Lane Smith 16 | © 2011 Christoph Lohmann <20h@r-36.net> 17 | © 2015-2016 Quentin Rameau 18 | © 2015-2016 Eric Pruitt 19 | © 2016-2017 Markus Teich 20 | © 2020-2022 Chris Down 21 | 22 | Permission is hereby granted, free of charge, to any person obtaining a 23 | copy of this software and associated documentation files (the "Software"), 24 | to deal in the Software without restriction, including without limitation 25 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 26 | and/or sell copies of the Software, and to permit persons to whom the 27 | Software is furnished to do so, subject to the following conditions: 28 | 29 | The above copyright notice and this permission notice shall be included in 30 | all copies or substantial portions of the Software. 31 | 32 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 33 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 34 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 35 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 36 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 37 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 38 | DEALINGS IN THE SOFTWARE. 39 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/Makefile: -------------------------------------------------------------------------------- 1 | # dwm - dynamic window manager 2 | # See LICENSE file for copyright and license details. 3 | 4 | include config.mk 5 | 6 | SRC = drw.c dwm.c util.c 7 | OBJ = ${SRC:.c=.o} 8 | 9 | all: options dwm 10 | 11 | options: 12 | @echo dwm build options: 13 | @echo "CFLAGS = ${CFLAGS}" 14 | @echo "LDFLAGS = ${LDFLAGS}" 15 | @echo "CC = ${CC}" 16 | 17 | .c.o: 18 | ${CC} -c ${CFLAGS} $< 19 | 20 | ${OBJ}: config.h config.mk 21 | 22 | config.h: 23 | cp config.def.h $@ 24 | 25 | dwm: ${OBJ} 26 | ${CC} -o $@ ${OBJ} ${LDFLAGS} 27 | 28 | clean: 29 | rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz 30 | 31 | dist: clean 32 | mkdir -p dwm-${VERSION} 33 | cp -R LICENSE Makefile README config.def.h config.mk\ 34 | dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION} 35 | tar -cf dwm-${VERSION}.tar dwm-${VERSION} 36 | gzip dwm-${VERSION}.tar 37 | rm -rf dwm-${VERSION} 38 | 39 | install: all 40 | mkdir -p ${DESTDIR}${PREFIX}/bin 41 | cp -f dwm ${DESTDIR}${PREFIX}/bin 42 | chmod 755 ${DESTDIR}${PREFIX}/bin/dwm 43 | mkdir -p ${DESTDIR}${MANPREFIX}/man1 44 | sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1 45 | chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1 46 | 47 | uninstall: 48 | rm -f ${DESTDIR}${PREFIX}/bin/dwm\ 49 | ${DESTDIR}${MANPREFIX}/man1/dwm.1 50 | 51 | .PHONY: all options clean dist install uninstall 52 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/README: -------------------------------------------------------------------------------- 1 | dwm - dynamic window manager 2 | ============================ 3 | dwm is an extremely fast, small, and dynamic window manager for X. 4 | 5 | 6 | Requirements 7 | ------------ 8 | In order to build dwm you need the Xlib header files. 9 | 10 | 11 | Installation 12 | ------------ 13 | Edit config.mk to match your local setup (dwm is installed into 14 | the /usr/local namespace by default). 15 | 16 | Afterwards enter the following command to build and install dwm (if 17 | necessary as root): 18 | 19 | make clean install 20 | 21 | 22 | Running dwm 23 | ----------- 24 | Add the following line to your .xinitrc to start dwm using startx: 25 | 26 | exec dwm 27 | 28 | In order to connect dwm to a specific display, make sure that 29 | the DISPLAY environment variable is set correctly, e.g.: 30 | 31 | DISPLAY=foo.bar:1 exec dwm 32 | 33 | (This will start dwm on display :1 of the host foo.bar.) 34 | 35 | In order to display status info in the bar, you can do something 36 | like this in your .xinitrc: 37 | 38 | while xsetroot -name "`date` `uptime | sed 's/.*,//'`" 39 | do 40 | sleep 1 41 | done & 42 | exec dwm 43 | 44 | 45 | Configuration 46 | ------------- 47 | The configuration of dwm is done by creating a custom config.h 48 | and (re)compiling the source code. 49 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/autostart.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function run { 4 | if ! pgrep $1 ; 5 | then 6 | $@& 7 | fi 8 | } 9 | run "dex $HOME/.config/autostart/arcolinux-welcome-app.desktop" 10 | 11 | #for virtualbox 12 | #run xrandr --output Virtual-1 --primary --mode 1920x1080 --pos 0x0 --rotate normal 13 | 14 | #run xrandr --output VGA-1 --primary --mode 1360x768 --pos 0x0 --rotate normal 15 | #run xrandr --output HDMI2 --mode 1920x1080 --pos 1920x0 --rotate normal --output HDMI1 --primary --mode 1920x1080 --pos 0x0 --rotate normal --output VIRTUAL1 --off 16 | #run xrandr --output eDP-1 --primary --mode 1368x768 --pos 0x0 --rotate normal --output DP-1 --off --output HDMI-1 --off --output DP-2 --off --output HDMI-2 --off 17 | #run xrandr --output LVDS1 --mode 1366x768 --output DP3 --mode 1920x1080 --right-of LVDS1 18 | #run xrandr --output DVI-I-0 --right-of HDMI-0 --auto 19 | #run xrandr --output DVI-1 --right-of DVI-0 --auto 20 | #run xrandr --output DVI-D-1 --right-of DVI-I-1 --auto 21 | #run xrandr --output HDMI2 --right-of HDMI1 --auto 22 | #autorandr horizontal 23 | 24 | run "nm-applet" 25 | run "pamac-tray" 26 | run "variety" 27 | run "xfce4-power-manager" 28 | run "blueberry-tray" 29 | run "/usr/lib/xfce4/notifyd/xfce4-notifyd" 30 | run "/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1" 31 | picom -b --config ~/.config/arco-dwm/picom.conf & 32 | run "numlockx on" 33 | run "volumeicon" 34 | run slstatus & 35 | sxhkd -c ~/.config/arco-dwm/sxhkd/sxhkdrc & 36 | #run "nitrogen --restore" 37 | run "conky -c $HOME/.config/arco-dwm/system-overview" 38 | #you can set wallpapers in themes as well 39 | feh --bg-fill /usr/share/backgrounds/archlinux/arch-wallpaper.jpg & 40 | feh --bg-fill /usr/share/backgrounds/arco/arco-wallpaper.jpg & 41 | #wallpaper for other Arch based systems 42 | #feh --bg-fill /usr/share/archlinux-tweak-tool/data/wallpaper/wallpaper.png & 43 | #run applications from startup 44 | 45 | #run "insync start" 46 | #run "spotify" 47 | #run "ckb-next -b" 48 | #run "discord" 49 | #run "telegram-desktop" 50 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/cheatsheet.md: -------------------------------------------------------------------------------- 1 | # CheatSheet # 2 | 3 | Super = Windows Key 4 | 5 | # common operations 6 | Super Return *terminal* (`alacritty`) 7 | Super q *quit* (kill focused window) 8 | Super Shift q *quit* (kill focused window) 9 | Super d *show app menu* (`rofi`) 10 | Super Shift d *show app menu* (`dmenu`) 11 | Super x *show archlinux-logout* (lock/suspend/logout/reboot/shutdown) 12 | Super Shift r *reload config files* (`reload`) 13 | Super Escape *kill application* 14 | 15 | # screenshot 16 | PrintSrc *full screenshot* 17 | Ctrl PrintSrc *options + timer* 18 | 19 | # application shortcuts 20 | Ctrl Alt U *pavucontrol* 21 | Ctrl ALT P *pamac-manager* 22 | Super Shift Return *file manager* (`thunar`) 23 | Super F1 *browser* (`firefox`) 24 | 25 | # container layout 26 | 27 | Super Shift Space *toggle tiling/floating mode* 28 | Super left mouse button *move window* 29 | Super right mouse button *resize window* 30 | 31 | # workspaces 32 | Super 1 .. 0 *switch to workspace 1 .. 10* 33 | Super Shift 1 .. 0 *move container to workspace 1 .. 10* 34 | 35 | # notes 36 | - Follow the website - https://dwm.suckless.org 37 | 38 | # user githubs 39 | - ... 40 | 41 | # share your own files on github 42 | - so we can all learn 43 | - and you have a backup 44 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/config.def.h: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | 3 | /* appearance */ 4 | static const unsigned int borderpx = 1; /* border pixel of windows */ 5 | static const unsigned int gappx = 5; /* gaps between windows */ 6 | static const unsigned int snap = 32; /* snap pixel */ 7 | static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */ 8 | static const unsigned int systrayspacing = 2; /* systray spacing */ 9 | static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/ 10 | static const int showsystray = 1; /* 0 means no systray */ 11 | static const int showbar = 1; /* 0 means no bar */ 12 | static const int topbar = 1; /* 0 means bottom bar */ 13 | static const Bool viewontag = True; /* Switch view on tag switch */ 14 | static const char *fonts[] = { "Noto Sans Mono:size=11" }; 15 | static const char dmenufont[] = "monospace:size=10"; 16 | static const char col_gray1[] = "#222222"; 17 | static const char col_gray2[] = "#444444"; 18 | static const char col_gray3[] = "#bbbbbb"; 19 | static const char col_gray4[] = "#eeeeee"; 20 | static const char col_cyan[] = "#6790EB"; 21 | static const unsigned int baralpha = 0xd0; 22 | static const unsigned int borderalpha = OPAQUE; 23 | static const char *colors[][3] = { 24 | /* fg bg border */ 25 | [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, 26 | [SchemeSel] = { col_gray4, col_cyan, col_cyan }, 27 | }; 28 | static const unsigned int alphas[][3] = { 29 | /* fg bg border */ 30 | [SchemeNorm] = { OPAQUE, baralpha, borderalpha }, 31 | 32 | [SchemeSel] = { OPAQUE, baralpha, borderalpha }, 33 | }; 34 | 35 | /* tagging */ 36 | static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; 37 | /* static const char *tags[] = { "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX" }; */ 38 | /* static const char *tags[] = { "", "", "", "", "", "", "", "", "" }; */ 39 | /* static const char *tags[] = { "Web", "Chat", "Edit", "Meld", "Vb", "Mail", "Video", "Image", "Files" }; */ 40 | 41 | 42 | static const Rule rules[] = { 43 | /* xprop(1): 44 | * WM_CLASS(STRING) = instance, class 45 | * WM_NAME(STRING) = title 46 | * use tags mask to point an application to a specific workspace 47 | */ 48 | /* class instance title tags mask isfloating monitor */ 49 | { "Gimp", NULL, NULL, 0, 0, -1 }, 50 | { "Xfce4-terminal", NULL, NULL, 0, 1, -1 }, 51 | { "firefox", NULL, NULL, 0, 0, -1 }, 52 | { "Arcolinux-welcome-app.py", NULL, NULL, 0, 1, -1 }, 53 | { "Arcolinux-calamares-tool.py", NULL, NULL, 0, 1, -1 }, 54 | { "Nlogout", NULL, NULL, 0, 1, -1 }, 55 | }; 56 | 57 | /* layout(s) */ 58 | static const float mfact = 0.50; /* factor of master area size [0.05..0.95] */ 59 | static const int nmaster = 1; /* number of clients in master area */ 60 | static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ 61 | 62 | #include "layouts.c" 63 | 64 | static const Layout layouts[] = { 65 | /* symbol arrange function */ 66 | { "[]=", tile }, /* first entry is default */ 67 | { "HHH", grid }, 68 | { "[M]", monocle }, 69 | { "><>", NULL }, /* no layout function means floating behavior */ 70 | { NULL, NULL }, 71 | }; 72 | 73 | /* key definitions */ 74 | #define MODKEY Mod4Mask 75 | #define TAGKEYS(KEY,TAG) \ 76 | { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ 77 | { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ 78 | { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ 79 | { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, 80 | 81 | /* helper for spawning shell commands in the pre dwm-5.0 fashion */ 82 | #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } 83 | 84 | /* commands */ 85 | static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ 86 | static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; 87 | static const char *filecmd[] = { "thunar", NULL }; 88 | static const char *calendar[] = { "gsimplecal", NULL }; 89 | static const char *taskmanager[] = { "xfce4-taskmanager", NULL }; 90 | 91 | #include "selfrestart.c" 92 | #include "shiftview.c" 93 | 94 | 95 | static Key keys[] = { 96 | /* modifier key function argument */ 97 | { MODKEY, XK_p, spawn, {.v = dmenucmd } }, 98 | { MODKEY|ShiftMask, XK_Return, spawn, {.v = filecmd } }, 99 | { MODKEY, XK_b, togglebar, {0} }, 100 | { MODKEY, XK_j, focusstack, {.i = +1 } }, 101 | { MODKEY, XK_k, focusstack, {.i = -1 } }, 102 | { MODKEY, XK_Right, focusstack, {.i = +1 } }, 103 | { MODKEY, XK_Left, focusstack, {.i = -1 } }, 104 | { MODKEY, XK_i, incnmaster, {.i = +1 } }, 105 | /*{ MODKEY, XK_d, incnmaster, {.i = -1 } },*/ 106 | { MODKEY, XK_h, setmfact, {.f = -0.05} }, 107 | { MODKEY, XK_l, setmfact, {.f = +0.05} }, 108 | { MODKEY, XK_minus, setgaps, {.i = -1 } }, 109 | { MODKEY, XK_equal, setgaps, {.i = +1 } }, 110 | { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } }, 111 | /*{ MODKEY, XK_Return, zoom, {0} },*/ 112 | /*{ MODKEY, XK_Tab, view, {0} },*/ 113 | { MODKEY|ShiftMask, XK_q, killclient, {0} }, 114 | { MODKEY, XK_q, killclient, {0} }, 115 | { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, 116 | { MODKEY, XK_g, setlayout, {.v = &layouts[1]} }, 117 | { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, 118 | { MODKEY, XK_f, setlayout, {.v = &layouts[2]} }, 119 | { MODKEY|ControlMask, XK_comma, cyclelayout, {.i = -1 } }, 120 | { MODKEY|ControlMask, XK_period, cyclelayout, {.i = +1 } }, 121 | { MODKEY, XK_space, cyclelayout, {.i = +1 } }, 122 | { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, 123 | { MODKEY, XK_0, view, {.ui = ~0 } }, 124 | { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, 125 | { MODKEY, XK_comma, focusmon, {.i = -1 } }, 126 | { MODKEY, XK_period, focusmon, {.i = +1 } }, 127 | { MODKEY|ShiftMask, XK_Left, tagmon, {.i = -1 } }, 128 | { MODKEY|ShiftMask, XK_Right, tagmon, {.i = +1 } }, 129 | { MODKEY|ShiftMask, XK_r, self_restart, {0} }, 130 | { Mod1Mask|ControlMask, XK_Right, shiftview, {.i = 1 } }, 131 | { Mod1Mask|ControlMask, XK_Left, shiftview, {.i = -1 } }, 132 | { Mod1Mask|ControlMask, XK_Up, shiftview, {.i = 1 } }, 133 | { Mod1Mask|ControlMask, XK_Down, shiftview, {.i = -1 } }, 134 | { Mod1Mask, XK_Tab, shiftview, {.i = 1 } }, 135 | { Mod1Mask|ShiftMask, XK_Tab, shiftview, {.i = -1 } }, 136 | { MODKEY, XK_Tab, shiftview, {.i = 1 } }, 137 | { MODKEY|ShiftMask, XK_Tab, shiftview, {.i = -1 } }, 138 | 139 | 140 | TAGKEYS( XK_1, 0) 141 | TAGKEYS( XK_2, 1) 142 | TAGKEYS( XK_3, 2) 143 | TAGKEYS( XK_4, 3) 144 | TAGKEYS( XK_5, 4) 145 | TAGKEYS( XK_6, 5) 146 | TAGKEYS( XK_7, 6) 147 | TAGKEYS( XK_8, 7) 148 | TAGKEYS( XK_9, 8) 149 | }; 150 | 151 | /* IF YOU HAVE A AZERTY KEYBOARD USE THESE CODES 152 | TAGKEYS( XK_ampersand, 0) 153 | TAGKEYS( XK_eacute, 1) 154 | TAGKEYS( XK_quotedbl, 2) 155 | TAGKEYS( XK_apostrophe, 3) 156 | TAGKEYS( XK_parenleft, 4) 157 | TAGKEYS( XK_section, 5) 158 | TAGKEYS( XK_egrave, 6) 159 | TAGKEYS( XK_exclam, 7) 160 | TAGKEYS( XK_ccedilla, 8) 161 | */ 162 | 163 | /* THESE ARE THE ORIGINAL QWERTY KEYBOARD CODES 164 | TAGKEYS( XK_1, 0) 165 | TAGKEYS( XK_2, 1) 166 | TAGKEYS( XK_3, 2) 167 | TAGKEYS( XK_4, 3) 168 | TAGKEYS( XK_5, 4) 169 | TAGKEYS( XK_6, 5) 170 | TAGKEYS( XK_7, 6) 171 | TAGKEYS( XK_8, 7) 172 | TAGKEYS( XK_9, 8) 173 | */ 174 | 175 | /* button definitions */ 176 | /* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ 177 | static Button buttons[] = { 178 | /* click event mask button function argument */ 179 | { ClkLtSymbol, 0, Button1, setlayout, {0} }, 180 | { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, 181 | { ClkWinTitle, 0, Button2, zoom, {0} }, 182 | { ClkStatusText, 0, Button1, spawn, {.v = taskmanager } }, 183 | { ClkStatusText, 0, Button2, spawn, {.v = filecmd } }, 184 | { ClkStatusText, 0, Button3, spawn, {.v = calendar } }, 185 | { ClkClientWin, MODKEY, Button1, movemouse, {0} }, 186 | { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, 187 | { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, 188 | { ClkTagBar, 0, Button1, view, {0} }, 189 | { ClkTagBar, 0, Button3, toggleview, {0} }, 190 | { ClkTagBar, MODKEY, Button1, tag, {0} }, 191 | { ClkTagBar, MODKEY, Button3, toggletag, {0} }, 192 | }; 193 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/config.h: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | 3 | /* appearance */ 4 | static const unsigned int borderpx = 1; /* border pixel of windows */ 5 | static const unsigned int gappx = 5; /* gaps between windows */ 6 | static const unsigned int snap = 32; /* snap pixel */ 7 | static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */ 8 | static const unsigned int systrayspacing = 2; /* systray spacing */ 9 | static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/ 10 | static const int showsystray = 1; /* 0 means no systray */ 11 | static const int showbar = 1; /* 0 means no bar */ 12 | static const int topbar = 1; /* 0 means bottom bar */ 13 | static const Bool viewontag = True; /* Switch view on tag switch */ 14 | static const char *fonts[] = { "Noto Sans Mono:size=11" }; 15 | static const char dmenufont[] = "monospace:size=10"; 16 | static const char col_gray1[] = "#222222"; 17 | static const char col_gray2[] = "#444444"; 18 | static const char col_gray3[] = "#bbbbbb"; 19 | static const char col_gray4[] = "#eeeeee"; 20 | static const char col_cyan[] = "#6790EB"; 21 | static const unsigned int baralpha = 0xd0; 22 | static const unsigned int borderalpha = OPAQUE; 23 | static const char *colors[][3] = { 24 | /* fg bg border */ 25 | [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, 26 | [SchemeSel] = { col_gray4, col_cyan, col_cyan }, 27 | }; 28 | static const unsigned int alphas[][3] = { 29 | /* fg bg border */ 30 | [SchemeNorm] = { OPAQUE, baralpha, borderalpha }, 31 | 32 | [SchemeSel] = { OPAQUE, baralpha, borderalpha }, 33 | }; 34 | 35 | /* tagging */ 36 | static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; 37 | /* static const char *tags[] = { "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX" }; */ 38 | /* static const char *tags[] = { "", "", "", "", "", "", "", "", "" }; */ 39 | /* static const char *tags[] = { "Web", "Chat", "Edit", "Meld", "Vb", "Mail", "Video", "Image", "Files" }; */ 40 | 41 | 42 | static const Rule rules[] = { 43 | /* xprop(1): 44 | * WM_CLASS(STRING) = instance, class 45 | * WM_NAME(STRING) = title 46 | * use tags mask to point an application to a specific workspace 47 | */ 48 | /* class instance title tags mask isfloating monitor */ 49 | { "Gimp", NULL, NULL, 0, 0, -1 }, 50 | { "Xfce4-terminal", NULL, NULL, 0, 1, -1 }, 51 | { "firefox", NULL, NULL, 0, 0, -1 }, 52 | { "Arcolinux-welcome-app.py", NULL, NULL, 0, 1, -1 }, 53 | { "Arcolinux-calamares-tool.py", NULL, NULL, 0, 1, -1 }, 54 | { "Nlogout", NULL, NULL, 0, 1, -1 }, 55 | }; 56 | 57 | /* layout(s) */ 58 | static const float mfact = 0.50; /* factor of master area size [0.05..0.95] */ 59 | static const int nmaster = 1; /* number of clients in master area */ 60 | static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ 61 | 62 | #include "layouts.c" 63 | 64 | static const Layout layouts[] = { 65 | /* symbol arrange function */ 66 | { "[]=", tile }, /* first entry is default */ 67 | { "HHH", grid }, 68 | { "[M]", monocle }, 69 | { "><>", NULL }, /* no layout function means floating behavior */ 70 | { NULL, NULL }, 71 | }; 72 | 73 | /* key definitions */ 74 | #define MODKEY Mod4Mask 75 | #define TAGKEYS(KEY,TAG) \ 76 | { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ 77 | { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ 78 | { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ 79 | { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, 80 | 81 | /* helper for spawning shell commands in the pre dwm-5.0 fashion */ 82 | #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } 83 | 84 | /* commands */ 85 | static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ 86 | static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; 87 | static const char *filecmd[] = { "thunar", NULL }; 88 | static const char *calendar[] = { "gsimplecal", NULL }; 89 | static const char *taskmanager[] = { "xfce4-taskmanager", NULL }; 90 | 91 | #include "selfrestart.c" 92 | #include "shiftview.c" 93 | 94 | 95 | static Key keys[] = { 96 | /* modifier key function argument */ 97 | { MODKEY, XK_p, spawn, {.v = dmenucmd } }, 98 | { MODKEY|ShiftMask, XK_Return, spawn, {.v = filecmd } }, 99 | { MODKEY, XK_b, togglebar, {0} }, 100 | { MODKEY, XK_j, focusstack, {.i = +1 } }, 101 | { MODKEY, XK_k, focusstack, {.i = -1 } }, 102 | { MODKEY, XK_Right, focusstack, {.i = +1 } }, 103 | { MODKEY, XK_Left, focusstack, {.i = -1 } }, 104 | { MODKEY, XK_i, incnmaster, {.i = +1 } }, 105 | /*{ MODKEY, XK_d, incnmaster, {.i = -1 } },*/ 106 | { MODKEY, XK_h, setmfact, {.f = -0.05} }, 107 | { MODKEY, XK_l, setmfact, {.f = +0.05} }, 108 | { MODKEY, XK_minus, setgaps, {.i = -1 } }, 109 | { MODKEY, XK_equal, setgaps, {.i = +1 } }, 110 | { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } }, 111 | /*{ MODKEY, XK_Return, zoom, {0} },*/ 112 | /*{ MODKEY, XK_Tab, view, {0} },*/ 113 | { MODKEY|ShiftMask, XK_q, killclient, {0} }, 114 | { MODKEY, XK_q, killclient, {0} }, 115 | { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, 116 | { MODKEY, XK_g, setlayout, {.v = &layouts[1]} }, 117 | { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, 118 | { MODKEY, XK_f, setlayout, {.v = &layouts[2]} }, 119 | { MODKEY|ControlMask, XK_comma, cyclelayout, {.i = -1 } }, 120 | { MODKEY|ControlMask, XK_period, cyclelayout, {.i = +1 } }, 121 | { MODKEY, XK_space, cyclelayout, {.i = +1 } }, 122 | { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, 123 | { MODKEY, XK_0, view, {.ui = ~0 } }, 124 | { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, 125 | { MODKEY, XK_comma, focusmon, {.i = -1 } }, 126 | { MODKEY, XK_period, focusmon, {.i = +1 } }, 127 | { MODKEY|ShiftMask, XK_Left, tagmon, {.i = -1 } }, 128 | { MODKEY|ShiftMask, XK_Right, tagmon, {.i = +1 } }, 129 | { MODKEY|ShiftMask, XK_r, self_restart, {0} }, 130 | { Mod1Mask|ControlMask, XK_Right, shiftview, {.i = 1 } }, 131 | { Mod1Mask|ControlMask, XK_Left, shiftview, {.i = -1 } }, 132 | { Mod1Mask|ControlMask, XK_Up, shiftview, {.i = 1 } }, 133 | { Mod1Mask|ControlMask, XK_Down, shiftview, {.i = -1 } }, 134 | { Mod1Mask, XK_Tab, shiftview, {.i = 1 } }, 135 | { Mod1Mask|ShiftMask, XK_Tab, shiftview, {.i = -1 } }, 136 | { MODKEY, XK_Tab, shiftview, {.i = 1 } }, 137 | { MODKEY|ShiftMask, XK_Tab, shiftview, {.i = -1 } }, 138 | 139 | 140 | TAGKEYS( XK_1, 0) 141 | TAGKEYS( XK_2, 1) 142 | TAGKEYS( XK_3, 2) 143 | TAGKEYS( XK_4, 3) 144 | TAGKEYS( XK_5, 4) 145 | TAGKEYS( XK_6, 5) 146 | TAGKEYS( XK_7, 6) 147 | TAGKEYS( XK_8, 7) 148 | TAGKEYS( XK_9, 8) 149 | }; 150 | 151 | /* IF YOU HAVE A AZERTY KEYBOARD USE THESE CODES 152 | TAGKEYS( XK_ampersand, 0) 153 | TAGKEYS( XK_eacute, 1) 154 | TAGKEYS( XK_quotedbl, 2) 155 | TAGKEYS( XK_apostrophe, 3) 156 | TAGKEYS( XK_parenleft, 4) 157 | TAGKEYS( XK_section, 5) 158 | TAGKEYS( XK_egrave, 6) 159 | TAGKEYS( XK_exclam, 7) 160 | TAGKEYS( XK_ccedilla, 8) 161 | */ 162 | 163 | /* THESE ARE THE ORIGINAL QWERTY KEYBOARD CODES 164 | TAGKEYS( XK_1, 0) 165 | TAGKEYS( XK_2, 1) 166 | TAGKEYS( XK_3, 2) 167 | TAGKEYS( XK_4, 3) 168 | TAGKEYS( XK_5, 4) 169 | TAGKEYS( XK_6, 5) 170 | TAGKEYS( XK_7, 6) 171 | TAGKEYS( XK_8, 7) 172 | TAGKEYS( XK_9, 8) 173 | */ 174 | 175 | /* button definitions */ 176 | /* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ 177 | static Button buttons[] = { 178 | /* click event mask button function argument */ 179 | { ClkLtSymbol, 0, Button1, setlayout, {0} }, 180 | { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, 181 | { ClkWinTitle, 0, Button2, zoom, {0} }, 182 | { ClkStatusText, 0, Button1, spawn, {.v = taskmanager } }, 183 | { ClkStatusText, 0, Button2, spawn, {.v = filecmd } }, 184 | { ClkStatusText, 0, Button3, spawn, {.v = calendar } }, 185 | { ClkClientWin, MODKEY, Button1, movemouse, {0} }, 186 | { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, 187 | { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, 188 | { ClkTagBar, 0, Button1, view, {0} }, 189 | { ClkTagBar, 0, Button3, toggleview, {0} }, 190 | { ClkTagBar, MODKEY, Button1, tag, {0} }, 191 | { ClkTagBar, MODKEY, Button3, toggletag, {0} }, 192 | }; 193 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/config.mk: -------------------------------------------------------------------------------- 1 | # dwm version 2 | VERSION = 6.2 3 | 4 | # Customize below to fit your system 5 | 6 | # paths 7 | PREFIX = /usr/local 8 | MANPREFIX = ${PREFIX}/share/man 9 | 10 | X11INC = /usr/X11R6/include 11 | X11LIB = /usr/X11R6/lib 12 | 13 | # Xinerama, comment if you don't want it 14 | XINERAMALIBS = -lXinerama 15 | XINERAMAFLAGS = -DXINERAMA 16 | 17 | # freetype 18 | FREETYPELIBS = -lfontconfig -lXft 19 | FREETYPEINC = /usr/include/freetype2 20 | # OpenBSD (uncomment) 21 | #FREETYPEINC = ${X11INC}/freetype2 22 | #MANPREFIX = ${PREFIX}/man 23 | 24 | # includes and libs 25 | INCS = -I${X11INC} -I${FREETYPEINC} 26 | LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lXrender 27 | 28 | # flags 29 | CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} 30 | #CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} 31 | CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} 32 | LDFLAGS = ${LIBS} 33 | 34 | # Solaris 35 | #CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" 36 | #LDFLAGS = ${LIBS} 37 | 38 | # compiler and linker 39 | CC = cc 40 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/drw.c: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "drw.h" 9 | #include "util.h" 10 | 11 | #define UTF_INVALID 0xFFFD 12 | #define UTF_SIZ 4 13 | 14 | static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; 15 | static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; 16 | static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; 17 | static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; 18 | 19 | static long 20 | utf8decodebyte(const char c, size_t *i) 21 | { 22 | for (*i = 0; *i < (UTF_SIZ + 1); ++(*i)) 23 | if (((unsigned char)c & utfmask[*i]) == utfbyte[*i]) 24 | return (unsigned char)c & ~utfmask[*i]; 25 | return 0; 26 | } 27 | 28 | static size_t 29 | utf8validate(long *u, size_t i) 30 | { 31 | if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) 32 | *u = UTF_INVALID; 33 | for (i = 1; *u > utfmax[i]; ++i) 34 | ; 35 | return i; 36 | } 37 | 38 | static size_t 39 | utf8decode(const char *c, long *u, size_t clen) 40 | { 41 | size_t i, j, len, type; 42 | long udecoded; 43 | 44 | *u = UTF_INVALID; 45 | if (!clen) 46 | return 0; 47 | udecoded = utf8decodebyte(c[0], &len); 48 | if (!BETWEEN(len, 1, UTF_SIZ)) 49 | return 1; 50 | for (i = 1, j = 1; i < clen && j < len; ++i, ++j) { 51 | udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); 52 | if (type) 53 | return j; 54 | } 55 | if (j < len) 56 | return 0; 57 | *u = udecoded; 58 | utf8validate(u, len); 59 | 60 | return len; 61 | } 62 | 63 | Drw * 64 | drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap) 65 | { 66 | Drw *drw = ecalloc(1, sizeof(Drw)); 67 | 68 | drw->dpy = dpy; 69 | drw->screen = screen; 70 | drw->root = root; 71 | drw->w = w; 72 | drw->h = h; 73 | drw->visual = visual; 74 | drw->depth = depth; 75 | drw->cmap = cmap; 76 | drw->drawable = XCreatePixmap(dpy, root, w, h, depth); 77 | drw->gc = XCreateGC(dpy, drw->drawable, 0, NULL); 78 | XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); 79 | 80 | return drw; 81 | } 82 | 83 | void 84 | drw_resize(Drw *drw, unsigned int w, unsigned int h) 85 | { 86 | if (!drw) 87 | return; 88 | 89 | drw->w = w; 90 | drw->h = h; 91 | if (drw->drawable) 92 | XFreePixmap(drw->dpy, drw->drawable); 93 | drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth); 94 | } 95 | 96 | void 97 | drw_free(Drw *drw) 98 | { 99 | XFreePixmap(drw->dpy, drw->drawable); 100 | XFreeGC(drw->dpy, drw->gc); 101 | free(drw); 102 | } 103 | 104 | /* This function is an implementation detail. Library users should use 105 | * drw_fontset_create instead. 106 | */ 107 | static Fnt * 108 | xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) 109 | { 110 | Fnt *font; 111 | XftFont *xfont = NULL; 112 | FcPattern *pattern = NULL; 113 | 114 | if (fontname) { 115 | /* Using the pattern found at font->xfont->pattern does not yield the 116 | * same substitution results as using the pattern returned by 117 | * FcNameParse; using the latter results in the desired fallback 118 | * behaviour whereas the former just results in missing-character 119 | * rectangles being drawn, at least with some fonts. */ 120 | if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) { 121 | fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname); 122 | return NULL; 123 | } 124 | if (!(pattern = FcNameParse((FcChar8 *) fontname))) { 125 | fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname); 126 | XftFontClose(drw->dpy, xfont); 127 | return NULL; 128 | } 129 | } else if (fontpattern) { 130 | if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { 131 | fprintf(stderr, "error, cannot load font from pattern.\n"); 132 | return NULL; 133 | } 134 | } else { 135 | die("no font specified."); 136 | } 137 | 138 | /* Do not allow using color fonts. This is a workaround for a BadLength 139 | * error from Xft with color glyphs. Modelled on the Xterm workaround. See 140 | * https://bugzilla.redhat.com/show_bug.cgi?id=1498269 141 | * https://lists.suckless.org/dev/1701/30932.html 142 | * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349 143 | * and lots more all over the internet. 144 | */ 145 | FcBool iscol; 146 | if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) { 147 | XftFontClose(drw->dpy, xfont); 148 | return NULL; 149 | } 150 | 151 | font = ecalloc(1, sizeof(Fnt)); 152 | font->xfont = xfont; 153 | font->pattern = pattern; 154 | font->h = xfont->ascent + xfont->descent; 155 | font->dpy = drw->dpy; 156 | 157 | return font; 158 | } 159 | 160 | static void 161 | xfont_free(Fnt *font) 162 | { 163 | if (!font) 164 | return; 165 | if (font->pattern) 166 | FcPatternDestroy(font->pattern); 167 | XftFontClose(font->dpy, font->xfont); 168 | free(font); 169 | } 170 | 171 | Fnt* 172 | drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount) 173 | { 174 | Fnt *cur, *ret = NULL; 175 | size_t i; 176 | 177 | if (!drw || !fonts) 178 | return NULL; 179 | 180 | for (i = 1; i <= fontcount; i++) { 181 | if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) { 182 | cur->next = ret; 183 | ret = cur; 184 | } 185 | } 186 | return (drw->fonts = ret); 187 | } 188 | 189 | void 190 | drw_fontset_free(Fnt *font) 191 | { 192 | if (font) { 193 | drw_fontset_free(font->next); 194 | xfont_free(font); 195 | } 196 | } 197 | 198 | void 199 | drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha) 200 | { 201 | if (!drw || !dest || !clrname) 202 | return; 203 | 204 | if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap, 205 | clrname, dest)) 206 | die("error, cannot allocate color '%s'", clrname); 207 | 208 | dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 24); 209 | } 210 | 211 | /* Wrapper to create color schemes. The caller has to call free(3) on the 212 | * returned color scheme when done using it. */ 213 | Clr * 214 | drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount) 215 | { 216 | size_t i; 217 | Clr *ret; 218 | 219 | /* need at least two colors for a scheme */ 220 | if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor)))) 221 | return NULL; 222 | 223 | for (i = 0; i < clrcount; i++) 224 | drw_clr_create(drw, &ret[i], clrnames[i], alphas[i]); 225 | return ret; 226 | } 227 | 228 | void 229 | drw_setfontset(Drw *drw, Fnt *set) 230 | { 231 | if (drw) 232 | drw->fonts = set; 233 | } 234 | 235 | void 236 | drw_setscheme(Drw *drw, Clr *scm) 237 | { 238 | if (drw) 239 | drw->scheme = scm; 240 | } 241 | 242 | void 243 | drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert) 244 | { 245 | if (!drw || !drw->scheme) 246 | return; 247 | XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel); 248 | if (filled) 249 | XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); 250 | else 251 | XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1); 252 | } 253 | 254 | int 255 | drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) 256 | { 257 | char buf[1024]; 258 | int ty; 259 | unsigned int ew; 260 | XftDraw *d = NULL; 261 | Fnt *usedfont, *curfont, *nextfont; 262 | size_t i, len; 263 | int utf8strlen, utf8charlen, render = x || y || w || h; 264 | long utf8codepoint = 0; 265 | const char *utf8str; 266 | FcCharSet *fccharset; 267 | FcPattern *fcpattern; 268 | FcPattern *match; 269 | XftResult result; 270 | int charexists = 0; 271 | 272 | if (!drw || (render && !drw->scheme) || !text || !drw->fonts) 273 | return 0; 274 | 275 | if (!render) { 276 | w = ~w; 277 | } else { 278 | XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); 279 | XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); 280 | d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap); 281 | x += lpad; 282 | w -= lpad; 283 | } 284 | 285 | usedfont = drw->fonts; 286 | while (1) { 287 | utf8strlen = 0; 288 | utf8str = text; 289 | nextfont = NULL; 290 | while (*text) { 291 | utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ); 292 | for (curfont = drw->fonts; curfont; curfont = curfont->next) { 293 | charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); 294 | if (charexists) { 295 | if (curfont == usedfont) { 296 | utf8strlen += utf8charlen; 297 | text += utf8charlen; 298 | } else { 299 | nextfont = curfont; 300 | } 301 | break; 302 | } 303 | } 304 | 305 | if (!charexists || nextfont) 306 | break; 307 | else 308 | charexists = 0; 309 | } 310 | 311 | if (utf8strlen) { 312 | drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL); 313 | /* shorten text if necessary */ 314 | for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--) 315 | drw_font_getexts(usedfont, utf8str, len, &ew, NULL); 316 | 317 | if (len) { 318 | memcpy(buf, utf8str, len); 319 | buf[len] = '\0'; 320 | if (len < utf8strlen) 321 | for (i = len; i && i > len - 3; buf[--i] = '.') 322 | ; /* NOP */ 323 | 324 | if (render) { 325 | ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; 326 | XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], 327 | usedfont->xfont, x, ty, (XftChar8 *)buf, len); 328 | } 329 | x += ew; 330 | w -= ew; 331 | } 332 | } 333 | 334 | if (!*text) { 335 | break; 336 | } else if (nextfont) { 337 | charexists = 0; 338 | usedfont = nextfont; 339 | } else { 340 | /* Regardless of whether or not a fallback font is found, the 341 | * character must be drawn. */ 342 | charexists = 1; 343 | 344 | fccharset = FcCharSetCreate(); 345 | FcCharSetAddChar(fccharset, utf8codepoint); 346 | 347 | if (!drw->fonts->pattern) { 348 | /* Refer to the comment in xfont_create for more information. */ 349 | die("the first font in the cache must be loaded from a font string."); 350 | } 351 | 352 | fcpattern = FcPatternDuplicate(drw->fonts->pattern); 353 | FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); 354 | FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); 355 | FcPatternAddBool(fcpattern, FC_COLOR, FcFalse); 356 | 357 | FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); 358 | FcDefaultSubstitute(fcpattern); 359 | match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result); 360 | 361 | FcCharSetDestroy(fccharset); 362 | FcPatternDestroy(fcpattern); 363 | 364 | if (match) { 365 | usedfont = xfont_create(drw, NULL, match); 366 | if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) { 367 | for (curfont = drw->fonts; curfont->next; curfont = curfont->next) 368 | ; /* NOP */ 369 | curfont->next = usedfont; 370 | } else { 371 | xfont_free(usedfont); 372 | usedfont = drw->fonts; 373 | } 374 | } 375 | } 376 | } 377 | if (d) 378 | XftDrawDestroy(d); 379 | 380 | return x + (render ? w : 0); 381 | } 382 | 383 | void 384 | drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) 385 | { 386 | if (!drw) 387 | return; 388 | 389 | XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); 390 | XSync(drw->dpy, False); 391 | } 392 | 393 | unsigned int 394 | drw_fontset_getwidth(Drw *drw, const char *text) 395 | { 396 | if (!drw || !drw->fonts || !text) 397 | return 0; 398 | return drw_text(drw, 0, 0, 0, 0, 0, text, 0); 399 | } 400 | 401 | void 402 | drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h) 403 | { 404 | XGlyphInfo ext; 405 | 406 | if (!font || !text) 407 | return; 408 | 409 | XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext); 410 | if (w) 411 | *w = ext.xOff; 412 | if (h) 413 | *h = font->h; 414 | } 415 | 416 | Cur * 417 | drw_cur_create(Drw *drw, int shape) 418 | { 419 | Cur *cur; 420 | 421 | if (!drw || !(cur = ecalloc(1, sizeof(Cur)))) 422 | return NULL; 423 | 424 | cur->cursor = XCreateFontCursor(drw->dpy, shape); 425 | 426 | return cur; 427 | } 428 | 429 | void 430 | drw_cur_free(Drw *drw, Cur *cursor) 431 | { 432 | if (!cursor) 433 | return; 434 | 435 | XFreeCursor(drw->dpy, cursor->cursor); 436 | free(cursor); 437 | } 438 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/drw.h: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | 3 | typedef struct { 4 | Cursor cursor; 5 | } Cur; 6 | 7 | typedef struct Fnt { 8 | Display *dpy; 9 | unsigned int h; 10 | XftFont *xfont; 11 | FcPattern *pattern; 12 | struct Fnt *next; 13 | } Fnt; 14 | 15 | enum { ColFg, ColBg, ColBorder }; /* Clr scheme index */ 16 | typedef XftColor Clr; 17 | 18 | typedef struct { 19 | unsigned int w, h; 20 | Display *dpy; 21 | int screen; 22 | Window root; 23 | Visual *visual; 24 | unsigned int depth; 25 | Colormap cmap; 26 | Drawable drawable; 27 | GC gc; 28 | Clr *scheme; 29 | Fnt *fonts; 30 | } Drw; 31 | 32 | /* Drawable abstraction */ 33 | Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap); 34 | void drw_resize(Drw *drw, unsigned int w, unsigned int h); 35 | void drw_free(Drw *drw); 36 | 37 | /* Fnt abstraction */ 38 | Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount); 39 | void drw_fontset_free(Fnt* set); 40 | unsigned int drw_fontset_getwidth(Drw *drw, const char *text); 41 | void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); 42 | 43 | /* Colorscheme abstraction */ 44 | void drw_clr_create(Drw *drw, Clr *dest, const char *clrname, unsigned int alpha); 45 | Clr *drw_scm_create(Drw *drw, const char *clrnames[], const unsigned int alphas[], size_t clrcount); 46 | 47 | /* Cursor abstraction */ 48 | Cur *drw_cur_create(Drw *drw, int shape); 49 | void drw_cur_free(Drw *drw, Cur *cursor); 50 | 51 | /* Drawing context manipulation */ 52 | void drw_setfontset(Drw *drw, Fnt *set); 53 | void drw_setscheme(Drw *drw, Clr *scm); 54 | 55 | /* Drawing functions */ 56 | void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert); 57 | int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert); 58 | 59 | /* Map functions */ 60 | void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); 61 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/dwm.1: -------------------------------------------------------------------------------- 1 | .TH DWM 1 dwm\-VERSION 2 | .SH NAME 3 | dwm \- dynamic window manager 4 | .SH SYNOPSIS 5 | .B dwm 6 | .RB [ \-v ] 7 | .SH DESCRIPTION 8 | dwm is a dynamic window manager for X. It manages windows in tiled, monocle 9 | and floating layouts. Either layout can be applied dynamically, optimising the 10 | environment for the application in use and the task performed. 11 | .P 12 | In tiled layouts windows are managed in a master and stacking area. The master 13 | area on the left contains one window by default, and the stacking area on the 14 | right contains all other windows. The number of master area windows can be 15 | adjusted from zero to an arbitrary number. In monocle layout all windows are 16 | maximised to the screen size. In floating layout windows can be resized and 17 | moved freely. Dialog windows are always managed floating, regardless of the 18 | layout applied. 19 | .P 20 | Windows are grouped by tags. Each window can be tagged with one or multiple 21 | tags. Selecting certain tags displays all windows with these tags. 22 | .P 23 | Each screen contains a small status bar which displays all available tags, the 24 | layout, the title of the focused window, and the text read from the root window 25 | name property, if the screen is focused. A floating window is indicated with an 26 | empty square and a maximised floating window is indicated with a filled square 27 | before the windows title. The selected tags are indicated with a different 28 | color. The tags of the focused window are indicated with a filled square in the 29 | top left corner. The tags which are applied to one or more windows are 30 | indicated with an empty square in the top left corner. 31 | .P 32 | dwm draws a small border around windows to indicate the focus state. 33 | .SH OPTIONS 34 | .TP 35 | .B \-v 36 | prints version information to stderr, then exits. 37 | .SH USAGE 38 | .SS Status bar 39 | .TP 40 | .B X root window name 41 | is read and displayed in the status text area. It can be set with the 42 | .BR xsetroot (1) 43 | command. 44 | .TP 45 | .B Button1 46 | click on a tag label to display all windows with that tag, click on the layout 47 | label toggles between tiled and floating layout. 48 | .TP 49 | .B Button3 50 | click on a tag label adds/removes all windows with that tag to/from the view. 51 | .TP 52 | .B Mod1\-Button1 53 | click on a tag label applies that tag to the focused window. 54 | .TP 55 | .B Mod1\-Button3 56 | click on a tag label adds/removes that tag to/from the focused window. 57 | .SS Keyboard commands 58 | .TP 59 | .B Mod1\-Shift\-Return 60 | Start 61 | .BR st(1). 62 | .TP 63 | .B Mod1\-p 64 | Spawn 65 | .BR dmenu(1) 66 | for launching other programs. 67 | .TP 68 | .B Mod1\-, 69 | Focus previous screen, if any. 70 | .TP 71 | .B Mod1\-. 72 | Focus next screen, if any. 73 | .TP 74 | .B Mod1\-Shift\-, 75 | Send focused window to previous screen, if any. 76 | .TP 77 | .B Mod1\-Shift\-. 78 | Send focused window to next screen, if any. 79 | .TP 80 | .B Mod1\-b 81 | Toggles bar on and off. 82 | .TP 83 | .B Mod1\-t 84 | Sets tiled layout. 85 | .TP 86 | .B Mod1\-f 87 | Sets floating layout. 88 | .TP 89 | .B Mod1\-m 90 | Sets monocle layout. 91 | .TP 92 | .B Mod1\-space 93 | Toggles between current and previous layout. 94 | .TP 95 | .B Mod1\-Control\-, 96 | Cycles backwards in layout list. 97 | .TP 98 | .B Mod1\-Control\-. 99 | Cycles forwards in layout list. 100 | .TP 101 | .B Mod1\-j 102 | Focus next window. 103 | .TP 104 | .B Mod1\-k 105 | Focus previous window. 106 | .TP 107 | .B Mod1\-i 108 | Increase number of windows in master area. 109 | .TP 110 | .B Mod1\-d 111 | Decrease number of windows in master area. 112 | .TP 113 | .B Mod1\-l 114 | Increase master area size. 115 | .TP 116 | .B Mod1\-h 117 | Decrease master area size. 118 | .TP 119 | .B Mod1\-Return 120 | Zooms/cycles focused window to/from master area (tiled layouts only). 121 | .TP 122 | .B Mod1\-Shift\-c 123 | Close focused window. 124 | .TP 125 | .B Mod1\-Shift\-space 126 | Toggle focused window between tiled and floating state. 127 | .TP 128 | .B Mod1\-Tab 129 | Toggles to the previously selected tags. 130 | .TP 131 | .B Mod1\-Shift\-[1..n] 132 | Apply nth tag to focused window. 133 | .TP 134 | .B Mod1\-Shift\-0 135 | Apply all tags to focused window. 136 | .TP 137 | .B Mod1\-Control\-Shift\-[1..n] 138 | Add/remove nth tag to/from focused window. 139 | .TP 140 | .B Mod1\-[1..n] 141 | View all windows with nth tag. 142 | .TP 143 | .B Mod1\-0 144 | View all windows with any tag. 145 | .TP 146 | .B Mod1\-Control\-[1..n] 147 | Add/remove all windows with nth tag to/from the view. 148 | .TP 149 | .B Mod1\-Shift\-q 150 | Quit dwm. 151 | .SS Mouse commands 152 | .TP 153 | .B Mod1\-Button1 154 | Move focused window while dragging. Tiled windows will be toggled to the floating state. 155 | .TP 156 | .B Mod1\-Button2 157 | Toggles focused window between floating and tiled state. 158 | .TP 159 | .B Mod1\-Button3 160 | Resize focused window while dragging. Tiled windows will be toggled to the floating state. 161 | .SH CUSTOMIZATION 162 | dwm is customized by creating a custom config.h and (re)compiling the source 163 | code. This keeps it fast, secure and simple. 164 | .SH SEE ALSO 165 | .BR dmenu (1), 166 | .BR st (1) 167 | .SH ISSUES 168 | Java applications which use the XToolkit/XAWT backend may draw grey windows 169 | only. The XToolkit/XAWT backend breaks ICCCM-compliance in recent JDK 1.5 and early 170 | JDK 1.6 versions, because it assumes a reparenting window manager. Possible workarounds 171 | are using JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or setting the 172 | environment variable 173 | .BR AWT_TOOLKIT=MToolkit 174 | (to use the older Motif backend instead) or running 175 | .B xprop -root -f _NET_WM_NAME 32a -set _NET_WM_NAME LG3D 176 | or 177 | .B wmname LG3D 178 | (to pretend that a non-reparenting window manager is running that the 179 | XToolkit/XAWT backend can recognize) or when using OpenJDK setting the environment variable 180 | .BR _JAVA_AWT_WM_NONREPARENTING=1 . 181 | .SH BUGS 182 | Send all bug reports with a patch to hackers@suckless.org. 183 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/dwm.c: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. 2 | * 3 | * dynamic window manager is designed like any other X client as well. It is 4 | * driven through handling X events. In contrast to other X clients, a window 5 | * manager selects for SubstructureRedirectMask on the root window, to receive 6 | * events about window (dis-)appearance. Only one X connection at a time is 7 | * allowed to select for this event mask. 8 | * 9 | * The event handlers of dwm are organized in an array which is accessed 10 | * whenever a new event has been fetched. This allows event dispatching 11 | * in O(1) time. 12 | * 13 | * Each child of the root window is called a client, except windows which have 14 | * set the override_redirect flag. Clients are organized in a linked client 15 | * list on each monitor, the focus history is remembered through a stack list 16 | * on each monitor. Each client contains a bit array to indicate the tags of a 17 | * client. 18 | * 19 | * Keys and tagging rules are organized as arrays and defined in config.h. 20 | * 21 | * To understand everything else, start reading main(). 22 | */ 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #ifdef XINERAMA 41 | #include 42 | #endif /* XINERAMA */ 43 | #include 44 | 45 | #include "drw.h" 46 | #include "util.h" 47 | 48 | /* macros */ 49 | #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) 50 | #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) 51 | #define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \ 52 | * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy))) 53 | #define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) 54 | #define LENGTH(X) (sizeof X / sizeof X[0]) 55 | #define MOUSEMASK (BUTTONMASK|PointerMotionMask) 56 | #define WIDTH(X) ((X)->w + 2 * (X)->bw) 57 | #define HEIGHT(X) ((X)->h + 2 * (X)->bw) 58 | #define TAGMASK ((1 << LENGTH(tags)) - 1) 59 | #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) 60 | 61 | #define SYSTEM_TRAY_REQUEST_DOCK 0 62 | 63 | /* XEMBED messages */ 64 | #define XEMBED_EMBEDDED_NOTIFY 0 65 | #define XEMBED_WINDOW_ACTIVATE 1 66 | #define XEMBED_FOCUS_IN 4 67 | #define XEMBED_MODALITY_ON 10 68 | 69 | #define XEMBED_MAPPED (1 << 0) 70 | #define XEMBED_WINDOW_ACTIVATE 1 71 | #define XEMBED_WINDOW_DEACTIVATE 2 72 | 73 | #define VERSION_MAJOR 0 74 | #define VERSION_MINOR 0 75 | #define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR 76 | 77 | #define OPAQUE 0xffU 78 | 79 | /* enums */ 80 | enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ 81 | enum { SchemeNorm, SchemeSel }; /* color schemes */ 82 | enum { NetSupported, NetWMName, NetWMState, NetWMCheck, 83 | NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz, 84 | NetWMFullscreen, NetActiveWindow, NetWMWindowType, 85 | NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ 86 | enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */ 87 | enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ 88 | enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, 89 | ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ 90 | 91 | typedef union { 92 | int i; 93 | unsigned int ui; 94 | float f; 95 | const void *v; 96 | } Arg; 97 | 98 | typedef struct { 99 | unsigned int click; 100 | unsigned int mask; 101 | unsigned int button; 102 | void (*func)(const Arg *arg); 103 | const Arg arg; 104 | } Button; 105 | 106 | typedef struct Monitor Monitor; 107 | typedef struct Client Client; 108 | struct Client { 109 | char name[256]; 110 | float mina, maxa; 111 | int x, y, w, h; 112 | int oldx, oldy, oldw, oldh; 113 | int basew, baseh, incw, inch, maxw, maxh, minw, minh; 114 | int bw, oldbw; 115 | unsigned int tags; 116 | int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; 117 | Client *next; 118 | Client *snext; 119 | Monitor *mon; 120 | Window win; 121 | }; 122 | 123 | typedef struct { 124 | unsigned int mod; 125 | KeySym keysym; 126 | void (*func)(const Arg *); 127 | const Arg arg; 128 | } Key; 129 | 130 | typedef struct { 131 | const char *symbol; 132 | void (*arrange)(Monitor *); 133 | } Layout; 134 | 135 | struct Monitor { 136 | char ltsymbol[16]; 137 | float mfact; 138 | int nmaster; 139 | int num; 140 | int by; /* bar geometry */ 141 | int mx, my, mw, mh; /* screen size */ 142 | int wx, wy, ww, wh; /* window area */ 143 | int gappx; /* gaps between windows */ 144 | unsigned int seltags; 145 | unsigned int sellt; 146 | unsigned int tagset[2]; 147 | int showbar; 148 | int topbar; 149 | Client *clients; 150 | Client *sel; 151 | Client *stack; 152 | Monitor *next; 153 | Window barwin; 154 | const Layout *lt[2]; 155 | }; 156 | 157 | typedef struct { 158 | const char *class; 159 | const char *instance; 160 | const char *title; 161 | unsigned int tags; 162 | int isfloating; 163 | int monitor; 164 | } Rule; 165 | 166 | typedef struct Systray Systray; 167 | struct Systray { 168 | Window win; 169 | Client *icons; 170 | }; 171 | 172 | /* function declarations */ 173 | static void applyrules(Client *c); 174 | static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); 175 | static void arrange(Monitor *m); 176 | static void arrangemon(Monitor *m); 177 | static void attach(Client *c); 178 | static void attachstack(Client *c); 179 | static void buttonpress(XEvent *e); 180 | static void checkotherwm(void); 181 | static void cleanup(void); 182 | static void cleanupmon(Monitor *mon); 183 | static void clientmessage(XEvent *e); 184 | static void configure(Client *c); 185 | static void configurenotify(XEvent *e); 186 | static void configurerequest(XEvent *e); 187 | static Monitor *createmon(void); 188 | static void cyclelayout(const Arg *arg); 189 | static void destroynotify(XEvent *e); 190 | static void detach(Client *c); 191 | static void detachstack(Client *c); 192 | static Monitor *dirtomon(int dir); 193 | static void drawbar(Monitor *m); 194 | static void drawbars(void); 195 | static void enternotify(XEvent *e); 196 | static void expose(XEvent *e); 197 | static void focus(Client *c); 198 | static void focusin(XEvent *e); 199 | static void focusmon(const Arg *arg); 200 | static void focusstack(const Arg *arg); 201 | static Atom getatomprop(Client *c, Atom prop); 202 | static int getrootptr(int *x, int *y); 203 | static long getstate(Window w); 204 | static unsigned int getsystraywidth(); 205 | static int gettextprop(Window w, Atom atom, char *text, unsigned int size); 206 | static void grabbuttons(Client *c, int focused); 207 | static void grabkeys(void); 208 | static void incnmaster(const Arg *arg); 209 | static void keypress(XEvent *e); 210 | static void killclient(const Arg *arg); 211 | static void manage(Window w, XWindowAttributes *wa); 212 | static void mappingnotify(XEvent *e); 213 | static void maprequest(XEvent *e); 214 | static void monocle(Monitor *m); 215 | static void motionnotify(XEvent *e); 216 | static void movemouse(const Arg *arg); 217 | static Client *nexttiled(Client *c); 218 | static void pop(Client *); 219 | static void propertynotify(XEvent *e); 220 | /*static void quit(const Arg *arg);*/ 221 | static Monitor *recttomon(int x, int y, int w, int h); 222 | static void removesystrayicon(Client *i); 223 | static void resize(Client *c, int x, int y, int w, int h, int interact); 224 | static void resizebarwin(Monitor *m); 225 | static void resizeclient(Client *c, int x, int y, int w, int h); 226 | static void resizemouse(const Arg *arg); 227 | static void resizerequest(XEvent *e); 228 | static void restack(Monitor *m); 229 | static void run(void); 230 | static void runautostart(void); 231 | static void scan(void); 232 | static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4); 233 | static void sendmon(Client *c, Monitor *m); 234 | static void setclientstate(Client *c, long state); 235 | static void setfocus(Client *c); 236 | static void setfullscreen(Client *c, int fullscreen); 237 | static void setgaps(const Arg *arg); 238 | static void setlayout(const Arg *arg); 239 | static void setmfact(const Arg *arg); 240 | static void setup(void); 241 | static void seturgent(Client *c, int urg); 242 | static void showhide(Client *c); 243 | static void sigchld(int unused); 244 | static void spawn(const Arg *arg); 245 | static Monitor *systraytomon(Monitor *m); 246 | static void tag(const Arg *arg); 247 | static void tagmon(const Arg *arg); 248 | static void tile(Monitor *); 249 | static void togglebar(const Arg *arg); 250 | static void togglefloating(const Arg *arg); 251 | static void toggletag(const Arg *arg); 252 | static void toggleview(const Arg *arg); 253 | static void unfocus(Client *c, int setfocus); 254 | static void unmanage(Client *c, int destroyed); 255 | static void unmapnotify(XEvent *e); 256 | static void updatebarpos(Monitor *m); 257 | static void updatebars(void); 258 | static void updateclientlist(void); 259 | static int updategeom(void); 260 | static void updatenumlockmask(void); 261 | static void updatesizehints(Client *c); 262 | static void updatestatus(void); 263 | static void updatesystray(void); 264 | static void updatesystrayicongeom(Client *i, int w, int h); 265 | static void updatesystrayiconstate(Client *i, XPropertyEvent *ev); 266 | static void updatetitle(Client *c); 267 | static void updatewindowtype(Client *c); 268 | static void updatewmhints(Client *c); 269 | static void view(const Arg *arg); 270 | static Client *wintoclient(Window w); 271 | static Monitor *wintomon(Window w); 272 | static Client *wintosystrayicon(Window w); 273 | static int xerror(Display *dpy, XErrorEvent *ee); 274 | static int xerrordummy(Display *dpy, XErrorEvent *ee); 275 | static int xerrorstart(Display *dpy, XErrorEvent *ee); 276 | static void xinitvisual(); 277 | static void zoom(const Arg *arg); 278 | 279 | /* variables */ 280 | static Systray *systray = NULL; 281 | static const char autostartblocksh[] = "autostart_blocking.sh"; 282 | static const char autostartsh[] = "autostart.sh"; 283 | static const char broken[] = "broken"; 284 | static const char dwmdir[] = "arco-dwm"; 285 | static const char localshare[] = ".config"; 286 | static char stext[256]; 287 | static int screen; 288 | static int sw, sh; /* X display screen geometry width, height */ 289 | static int bh, blw = 0; /* bar geometry */ 290 | static int lrpad; /* sum of left and right padding for text */ 291 | static int (*xerrorxlib)(Display *, XErrorEvent *); 292 | static unsigned int numlockmask = 0; 293 | static void (*handler[LASTEvent]) (XEvent *) = { 294 | [ButtonPress] = buttonpress, 295 | [ClientMessage] = clientmessage, 296 | [ConfigureRequest] = configurerequest, 297 | [ConfigureNotify] = configurenotify, 298 | [DestroyNotify] = destroynotify, 299 | [EnterNotify] = enternotify, 300 | [Expose] = expose, 301 | [FocusIn] = focusin, 302 | [KeyPress] = keypress, 303 | [MappingNotify] = mappingnotify, 304 | [MapRequest] = maprequest, 305 | [MotionNotify] = motionnotify, 306 | [PropertyNotify] = propertynotify, 307 | [ResizeRequest] = resizerequest, 308 | [UnmapNotify] = unmapnotify 309 | }; 310 | static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast]; 311 | static int running = 1; 312 | static Cur *cursor[CurLast]; 313 | static Clr **scheme; 314 | static Display *dpy; 315 | static Drw *drw; 316 | static Monitor *mons, *selmon; 317 | static Window root, wmcheckwin; 318 | 319 | static int useargb = 0; 320 | static Visual *visual; 321 | static int depth; 322 | static Colormap cmap; 323 | 324 | /* configuration, allows nested code to access above variables */ 325 | #include "config.h" 326 | 327 | /* compile-time check if all tags fit into an unsigned int bit array. */ 328 | struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; 329 | 330 | /* function implementations */ 331 | void 332 | applyrules(Client *c) 333 | { 334 | const char *class, *instance; 335 | unsigned int i; 336 | const Rule *r; 337 | Monitor *m; 338 | XClassHint ch = { NULL, NULL }; 339 | 340 | /* rule matching */ 341 | c->isfloating = 0; 342 | c->tags = 0; 343 | XGetClassHint(dpy, c->win, &ch); 344 | class = ch.res_class ? ch.res_class : broken; 345 | instance = ch.res_name ? ch.res_name : broken; 346 | 347 | for (i = 0; i < LENGTH(rules); i++) { 348 | r = &rules[i]; 349 | if ((!r->title || strstr(c->name, r->title)) 350 | && (!r->class || strstr(class, r->class)) 351 | && (!r->instance || strstr(instance, r->instance))) 352 | { 353 | c->isfloating = r->isfloating; 354 | c->tags |= r->tags; 355 | for (m = mons; m && m->num != r->monitor; m = m->next); 356 | if (m) 357 | c->mon = m; 358 | } 359 | } 360 | if (ch.res_class) 361 | XFree(ch.res_class); 362 | if (ch.res_name) 363 | XFree(ch.res_name); 364 | c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags]; 365 | } 366 | 367 | int 368 | applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact) 369 | { 370 | int baseismin; 371 | Monitor *m = c->mon; 372 | 373 | /* set minimum possible */ 374 | *w = MAX(1, *w); 375 | *h = MAX(1, *h); 376 | if (interact) { 377 | if (*x > sw) 378 | *x = sw - WIDTH(c); 379 | if (*y > sh) 380 | *y = sh - HEIGHT(c); 381 | if (*x + *w + 2 * c->bw < 0) 382 | *x = 0; 383 | if (*y + *h + 2 * c->bw < 0) 384 | *y = 0; 385 | } else { 386 | if (*x >= m->wx + m->ww) 387 | *x = m->wx + m->ww - WIDTH(c); 388 | if (*y >= m->wy + m->wh) 389 | *y = m->wy + m->wh - HEIGHT(c); 390 | if (*x + *w + 2 * c->bw <= m->wx) 391 | *x = m->wx; 392 | if (*y + *h + 2 * c->bw <= m->wy) 393 | *y = m->wy; 394 | } 395 | if (*h < bh) 396 | *h = bh; 397 | if (*w < bh) 398 | *w = bh; 399 | if (resizehints || c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) { 400 | /* see last two sentences in ICCCM 4.1.2.3 */ 401 | baseismin = c->basew == c->minw && c->baseh == c->minh; 402 | if (!baseismin) { /* temporarily remove base dimensions */ 403 | *w -= c->basew; 404 | *h -= c->baseh; 405 | } 406 | /* adjust for aspect limits */ 407 | if (c->mina > 0 && c->maxa > 0) { 408 | if (c->maxa < (float)*w / *h) 409 | *w = *h * c->maxa + 0.5; 410 | else if (c->mina < (float)*h / *w) 411 | *h = *w * c->mina + 0.5; 412 | } 413 | if (baseismin) { /* increment calculation requires this */ 414 | *w -= c->basew; 415 | *h -= c->baseh; 416 | } 417 | /* adjust for increment value */ 418 | if (c->incw) 419 | *w -= *w % c->incw; 420 | if (c->inch) 421 | *h -= *h % c->inch; 422 | /* restore base dimensions */ 423 | *w = MAX(*w + c->basew, c->minw); 424 | *h = MAX(*h + c->baseh, c->minh); 425 | if (c->maxw) 426 | *w = MIN(*w, c->maxw); 427 | if (c->maxh) 428 | *h = MIN(*h, c->maxh); 429 | } 430 | return *x != c->x || *y != c->y || *w != c->w || *h != c->h; 431 | } 432 | 433 | void 434 | arrange(Monitor *m) 435 | { 436 | if (m) 437 | showhide(m->stack); 438 | else for (m = mons; m; m = m->next) 439 | showhide(m->stack); 440 | if (m) { 441 | arrangemon(m); 442 | restack(m); 443 | } else for (m = mons; m; m = m->next) 444 | arrangemon(m); 445 | } 446 | 447 | void 448 | arrangemon(Monitor *m) 449 | { 450 | strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); 451 | if (m->lt[m->sellt]->arrange) 452 | m->lt[m->sellt]->arrange(m); 453 | } 454 | 455 | void 456 | attach(Client *c) 457 | { 458 | c->next = c->mon->clients; 459 | c->mon->clients = c; 460 | } 461 | 462 | void 463 | attachstack(Client *c) 464 | { 465 | c->snext = c->mon->stack; 466 | c->mon->stack = c; 467 | } 468 | 469 | void 470 | buttonpress(XEvent *e) 471 | { 472 | unsigned int i, x, click; 473 | Arg arg = {0}; 474 | Client *c; 475 | Monitor *m; 476 | XButtonPressedEvent *ev = &e->xbutton; 477 | 478 | click = ClkRootWin; 479 | /* focus monitor if necessary */ 480 | if ((m = wintomon(ev->window)) && m != selmon) { 481 | unfocus(selmon->sel, 1); 482 | selmon = m; 483 | focus(NULL); 484 | } 485 | if (ev->window == selmon->barwin) { 486 | i = x = 0; 487 | do 488 | x += TEXTW(tags[i]); 489 | while (ev->x >= x && ++i < LENGTH(tags)); 490 | if (i < LENGTH(tags)) { 491 | click = ClkTagBar; 492 | arg.ui = 1 << i; 493 | } else if (ev->x < x + blw) 494 | click = ClkLtSymbol; 495 | else if (ev->x > selmon->ww - TEXTW(stext) - getsystraywidth()) 496 | click = ClkStatusText; 497 | else 498 | click = ClkWinTitle; 499 | } else if ((c = wintoclient(ev->window))) { 500 | focus(c); 501 | restack(selmon); 502 | XAllowEvents(dpy, ReplayPointer, CurrentTime); 503 | click = ClkClientWin; 504 | } 505 | for (i = 0; i < LENGTH(buttons); i++) 506 | if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button 507 | && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) 508 | buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); 509 | } 510 | 511 | void 512 | checkotherwm(void) 513 | { 514 | xerrorxlib = XSetErrorHandler(xerrorstart); 515 | /* this causes an error if some other window manager is running */ 516 | XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask); 517 | XSync(dpy, False); 518 | XSetErrorHandler(xerror); 519 | XSync(dpy, False); 520 | } 521 | 522 | void 523 | cleanup(void) 524 | { 525 | Arg a = {.ui = ~0}; 526 | Layout foo = { "", NULL }; 527 | Monitor *m; 528 | size_t i; 529 | 530 | view(&a); 531 | selmon->lt[selmon->sellt] = &foo; 532 | for (m = mons; m; m = m->next) 533 | while (m->stack) 534 | unmanage(m->stack, 0); 535 | XUngrabKey(dpy, AnyKey, AnyModifier, root); 536 | while (mons) 537 | cleanupmon(mons); 538 | if (showsystray) { 539 | XUnmapWindow(dpy, systray->win); 540 | XDestroyWindow(dpy, systray->win); 541 | free(systray); 542 | } 543 | for (i = 0; i < CurLast; i++) 544 | drw_cur_free(drw, cursor[i]); 545 | for (i = 0; i < LENGTH(colors); i++) 546 | free(scheme[i]); 547 | XDestroyWindow(dpy, wmcheckwin); 548 | drw_free(drw); 549 | XSync(dpy, False); 550 | XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); 551 | XDeleteProperty(dpy, root, netatom[NetActiveWindow]); 552 | } 553 | 554 | void 555 | cleanupmon(Monitor *mon) 556 | { 557 | Monitor *m; 558 | 559 | if (mon == mons) 560 | mons = mons->next; 561 | else { 562 | for (m = mons; m && m->next != mon; m = m->next); 563 | m->next = mon->next; 564 | } 565 | XUnmapWindow(dpy, mon->barwin); 566 | XDestroyWindow(dpy, mon->barwin); 567 | free(mon); 568 | } 569 | 570 | void 571 | clientmessage(XEvent *e) 572 | { 573 | XWindowAttributes wa; 574 | XSetWindowAttributes swa; 575 | XClientMessageEvent *cme = &e->xclient; 576 | Client *c = wintoclient(cme->window); 577 | 578 | if (showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) { 579 | /* add systray icons */ 580 | if (cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) { 581 | if (!(c = (Client *)calloc(1, sizeof(Client)))) 582 | die("fatal: could not malloc() %u bytes\n", sizeof(Client)); 583 | if (!(c->win = cme->data.l[2])) { 584 | free(c); 585 | return; 586 | } 587 | c->mon = selmon; 588 | c->next = systray->icons; 589 | systray->icons = c; 590 | XGetWindowAttributes(dpy, c->win, &wa); 591 | c->x = c->oldx = c->y = c->oldy = 0; 592 | c->w = c->oldw = wa.width; 593 | c->h = c->oldh = wa.height; 594 | c->oldbw = wa.border_width; 595 | c->bw = 0; 596 | c->isfloating = True; 597 | /* reuse tags field as mapped status */ 598 | c->tags = 1; 599 | updatesizehints(c); 600 | updatesystrayicongeom(c, wa.width, wa.height); 601 | XAddToSaveSet(dpy, c->win); 602 | XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask); 603 | XReparentWindow(dpy, c->win, systray->win, 0, 0); 604 | /* use parents background color */ 605 | swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; 606 | XChangeWindowAttributes(dpy, c->win, CWBackPixel, &swa); 607 | sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION); 608 | /* FIXME not sure if I have to send these events, too */ 609 | sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_FOCUS_IN, 0 , systray->win, XEMBED_EMBEDDED_VERSION); 610 | sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0 , systray->win, XEMBED_EMBEDDED_VERSION); 611 | sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_MODALITY_ON, 0 , systray->win, XEMBED_EMBEDDED_VERSION); 612 | XSync(dpy, False); 613 | resizebarwin(selmon); 614 | updatesystray(); 615 | setclientstate(c, NormalState); 616 | } 617 | return; 618 | } 619 | if (!c) 620 | return; 621 | if (cme->message_type == netatom[NetWMState]) { 622 | if (cme->data.l[1] == netatom[NetWMFullscreen] 623 | || cme->data.l[2] == netatom[NetWMFullscreen]) 624 | setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */ 625 | || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); 626 | } else if (cme->message_type == netatom[NetActiveWindow]) { 627 | if (c != selmon->sel && !c->isurgent) 628 | seturgent(c, 1); 629 | } 630 | } 631 | 632 | void 633 | configure(Client *c) 634 | { 635 | XConfigureEvent ce; 636 | 637 | ce.type = ConfigureNotify; 638 | ce.display = dpy; 639 | ce.event = c->win; 640 | ce.window = c->win; 641 | ce.x = c->x; 642 | ce.y = c->y; 643 | ce.width = c->w; 644 | ce.height = c->h; 645 | ce.border_width = c->bw; 646 | ce.above = None; 647 | ce.override_redirect = False; 648 | XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce); 649 | } 650 | 651 | void 652 | configurenotify(XEvent *e) 653 | { 654 | Monitor *m; 655 | Client *c; 656 | XConfigureEvent *ev = &e->xconfigure; 657 | int dirty; 658 | 659 | /* TODO: updategeom handling sucks, needs to be simplified */ 660 | if (ev->window == root) { 661 | dirty = (sw != ev->width || sh != ev->height); 662 | sw = ev->width; 663 | sh = ev->height; 664 | if (updategeom() || dirty) { 665 | drw_resize(drw, sw, bh); 666 | updatebars(); 667 | for (m = mons; m; m = m->next) { 668 | for (c = m->clients; c; c = c->next) 669 | if (c->isfullscreen) 670 | resizeclient(c, m->mx, m->my, m->mw, m->mh); 671 | resizebarwin(m); 672 | } 673 | focus(NULL); 674 | arrange(NULL); 675 | } 676 | } 677 | } 678 | 679 | void 680 | configurerequest(XEvent *e) 681 | { 682 | Client *c; 683 | Monitor *m; 684 | XConfigureRequestEvent *ev = &e->xconfigurerequest; 685 | XWindowChanges wc; 686 | 687 | if ((c = wintoclient(ev->window))) { 688 | if (ev->value_mask & CWBorderWidth) 689 | c->bw = ev->border_width; 690 | else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) { 691 | m = c->mon; 692 | if (ev->value_mask & CWX) { 693 | c->oldx = c->x; 694 | c->x = m->mx + ev->x; 695 | } 696 | if (ev->value_mask & CWY) { 697 | c->oldy = c->y; 698 | c->y = m->my + ev->y; 699 | } 700 | if (ev->value_mask & CWWidth) { 701 | c->oldw = c->w; 702 | c->w = ev->width; 703 | } 704 | if (ev->value_mask & CWHeight) { 705 | c->oldh = c->h; 706 | c->h = ev->height; 707 | } 708 | if ((c->x + c->w) > m->mx + m->mw && c->isfloating) 709 | c->x = m->mx + (m->mw / 2 - WIDTH(c) / 2); /* center in x direction */ 710 | if ((c->y + c->h) > m->my + m->mh && c->isfloating) 711 | c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */ 712 | if ((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight))) 713 | configure(c); 714 | if (ISVISIBLE(c)) 715 | XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); 716 | } else 717 | configure(c); 718 | } else { 719 | wc.x = ev->x; 720 | wc.y = ev->y; 721 | wc.width = ev->width; 722 | wc.height = ev->height; 723 | wc.border_width = ev->border_width; 724 | wc.sibling = ev->above; 725 | wc.stack_mode = ev->detail; 726 | XConfigureWindow(dpy, ev->window, ev->value_mask, &wc); 727 | } 728 | XSync(dpy, False); 729 | } 730 | 731 | Monitor * 732 | createmon(void) 733 | { 734 | Monitor *m; 735 | 736 | m = ecalloc(1, sizeof(Monitor)); 737 | m->tagset[0] = m->tagset[1] = 1; 738 | m->mfact = mfact; 739 | m->nmaster = nmaster; 740 | m->showbar = showbar; 741 | m->topbar = topbar; 742 | m->gappx = gappx; 743 | m->lt[0] = &layouts[0]; 744 | m->lt[1] = &layouts[1 % LENGTH(layouts)]; 745 | strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); 746 | return m; 747 | } 748 | 749 | void 750 | cyclelayout(const Arg *arg) { 751 | Layout *l; 752 | for(l = (Layout *)layouts; l != selmon->lt[selmon->sellt]; l++); 753 | if(arg->i > 0) { 754 | if(l->symbol && (l + 1)->symbol) 755 | setlayout(&((Arg) { .v = (l + 1) })); 756 | else 757 | setlayout(&((Arg) { .v = layouts })); 758 | } else { 759 | if(l != layouts && (l - 1)->symbol) 760 | setlayout(&((Arg) { .v = (l - 1) })); 761 | else 762 | setlayout(&((Arg) { .v = &layouts[LENGTH(layouts) - 2] })); 763 | } 764 | } 765 | 766 | void 767 | destroynotify(XEvent *e) 768 | { 769 | Client *c; 770 | XDestroyWindowEvent *ev = &e->xdestroywindow; 771 | 772 | if ((c = wintoclient(ev->window))) 773 | unmanage(c, 1); 774 | else if ((c = wintosystrayicon(ev->window))) { 775 | removesystrayicon(c); 776 | resizebarwin(selmon); 777 | updatesystray(); 778 | } 779 | } 780 | 781 | void 782 | detach(Client *c) 783 | { 784 | Client **tc; 785 | 786 | for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next); 787 | *tc = c->next; 788 | } 789 | 790 | void 791 | detachstack(Client *c) 792 | { 793 | Client **tc, *t; 794 | 795 | for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext); 796 | *tc = c->snext; 797 | 798 | if (c == c->mon->sel) { 799 | for (t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext); 800 | c->mon->sel = t; 801 | } 802 | } 803 | 804 | Monitor * 805 | dirtomon(int dir) 806 | { 807 | Monitor *m = NULL; 808 | 809 | if (dir > 0) { 810 | if (!(m = selmon->next)) 811 | m = mons; 812 | } else if (selmon == mons) 813 | for (m = mons; m->next; m = m->next); 814 | else 815 | for (m = mons; m->next != selmon; m = m->next); 816 | return m; 817 | } 818 | 819 | void 820 | drawbar(Monitor *m) 821 | { 822 | int x, w, sw = 0, stw = 0; 823 | int boxs = drw->fonts->h / 9; 824 | int boxw = drw->fonts->h / 6 + 2; 825 | unsigned int i, occ = 0, urg = 0; 826 | Client *c; 827 | 828 | if(showsystray && m == systraytomon(m)) 829 | stw = getsystraywidth(); 830 | 831 | /* draw status first so it can be overdrawn by tags later */ 832 | if (m == selmon) { /* status is only drawn on selected monitor */ 833 | drw_setscheme(drw, scheme[SchemeNorm]); 834 | sw = TEXTW(stext) - lrpad / 2 + 2; /* 2px right padding */ 835 | drw_text(drw, m->ww - sw - stw, 0, sw, bh, lrpad / 2 - 2, stext, 0); 836 | } 837 | 838 | resizebarwin(m); 839 | for (c = m->clients; c; c = c->next) { 840 | occ |= c->tags; 841 | if (c->isurgent) 842 | urg |= c->tags; 843 | } 844 | x = 0; 845 | for (i = 0; i < LENGTH(tags); i++) { 846 | w = TEXTW(tags[i]); 847 | drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); 848 | drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); 849 | if (occ & 1 << i) 850 | drw_rect(drw, x + boxs, boxs, boxw, boxw, 851 | m == selmon && selmon->sel && selmon->sel->tags & 1 << i, 852 | urg & 1 << i); 853 | x += w; 854 | } 855 | w = blw = TEXTW(m->ltsymbol); 856 | drw_setscheme(drw, scheme[SchemeNorm]); 857 | x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); 858 | 859 | if ((w = m->ww - sw - stw - x) > bh) { 860 | if (m->sel) { 861 | drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); 862 | drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); 863 | if (m->sel->isfloating) 864 | drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); 865 | } else { 866 | drw_setscheme(drw, scheme[SchemeNorm]); 867 | drw_rect(drw, x, 0, w, bh, 1, 1); 868 | } 869 | } 870 | drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh); 871 | } 872 | 873 | void 874 | drawbars(void) 875 | { 876 | Monitor *m; 877 | 878 | for (m = mons; m; m = m->next) 879 | drawbar(m); 880 | } 881 | 882 | void 883 | enternotify(XEvent *e) 884 | { 885 | Client *c; 886 | Monitor *m; 887 | XCrossingEvent *ev = &e->xcrossing; 888 | 889 | if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root) 890 | return; 891 | c = wintoclient(ev->window); 892 | m = c ? c->mon : wintomon(ev->window); 893 | if (m != selmon) { 894 | unfocus(selmon->sel, 1); 895 | selmon = m; 896 | } else if (!c || c == selmon->sel) 897 | return; 898 | focus(c); 899 | } 900 | 901 | void 902 | expose(XEvent *e) 903 | { 904 | Monitor *m; 905 | XExposeEvent *ev = &e->xexpose; 906 | 907 | if (ev->count == 0 && (m = wintomon(ev->window))) { 908 | drawbar(m); 909 | if (m == selmon) 910 | updatesystray(); 911 | } 912 | } 913 | 914 | void 915 | focus(Client *c) 916 | { 917 | if (!c || !ISVISIBLE(c)) 918 | for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); 919 | if (selmon->sel && selmon->sel != c) 920 | unfocus(selmon->sel, 0); 921 | if (c) { 922 | if (c->mon != selmon) 923 | selmon = c->mon; 924 | if (c->isurgent) 925 | seturgent(c, 0); 926 | detachstack(c); 927 | attachstack(c); 928 | grabbuttons(c, 1); 929 | XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel); 930 | setfocus(c); 931 | } else { 932 | XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); 933 | XDeleteProperty(dpy, root, netatom[NetActiveWindow]); 934 | } 935 | selmon->sel = c; 936 | drawbars(); 937 | } 938 | 939 | /* there are some broken focus acquiring clients needing extra handling */ 940 | void 941 | focusin(XEvent *e) 942 | { 943 | XFocusChangeEvent *ev = &e->xfocus; 944 | 945 | if (selmon->sel && ev->window != selmon->sel->win) 946 | setfocus(selmon->sel); 947 | } 948 | 949 | void 950 | focusmon(const Arg *arg) 951 | { 952 | Monitor *m; 953 | 954 | if (!mons->next) 955 | return; 956 | if ((m = dirtomon(arg->i)) == selmon) 957 | return; 958 | unfocus(selmon->sel, 0); 959 | selmon = m; 960 | focus(NULL); 961 | } 962 | 963 | void 964 | focusstack(const Arg *arg) 965 | { 966 | Client *c = NULL, *i; 967 | 968 | if (!selmon->sel) 969 | return; 970 | if (arg->i > 0) { 971 | for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); 972 | if (!c) 973 | for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next); 974 | } else { 975 | for (i = selmon->clients; i != selmon->sel; i = i->next) 976 | if (ISVISIBLE(i)) 977 | c = i; 978 | if (!c) 979 | for (; i; i = i->next) 980 | if (ISVISIBLE(i)) 981 | c = i; 982 | } 983 | if (c) { 984 | focus(c); 985 | restack(selmon); 986 | } 987 | } 988 | 989 | Atom 990 | getatomprop(Client *c, Atom prop) 991 | { 992 | int di; 993 | unsigned long dl; 994 | unsigned char *p = NULL; 995 | Atom da, atom = None; 996 | /* FIXME getatomprop should return the number of items and a pointer to 997 | * the stored data instead of this workaround */ 998 | Atom req = XA_ATOM; 999 | if (prop == xatom[XembedInfo]) 1000 | req = xatom[XembedInfo]; 1001 | 1002 | if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req, 1003 | &da, &di, &dl, &dl, &p) == Success && p) { 1004 | atom = *(Atom *)p; 1005 | if (da == xatom[XembedInfo] && dl == 2) 1006 | atom = ((Atom *)p)[1]; 1007 | XFree(p); 1008 | } 1009 | return atom; 1010 | } 1011 | 1012 | int 1013 | getrootptr(int *x, int *y) 1014 | { 1015 | int di; 1016 | unsigned int dui; 1017 | Window dummy; 1018 | 1019 | return XQueryPointer(dpy, root, &dummy, &dummy, x, y, &di, &di, &dui); 1020 | } 1021 | 1022 | long 1023 | getstate(Window w) 1024 | { 1025 | int format; 1026 | long result = -1; 1027 | unsigned char *p = NULL; 1028 | unsigned long n, extra; 1029 | Atom real; 1030 | 1031 | if (XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState], 1032 | &real, &format, &n, &extra, (unsigned char **)&p) != Success) 1033 | return -1; 1034 | if (n != 0) 1035 | result = *p; 1036 | XFree(p); 1037 | return result; 1038 | } 1039 | 1040 | unsigned int 1041 | getsystraywidth() 1042 | { 1043 | unsigned int w = 0; 1044 | Client *i; 1045 | if(showsystray) 1046 | for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ; 1047 | return w ? w + systrayspacing : 1; 1048 | } 1049 | 1050 | int 1051 | gettextprop(Window w, Atom atom, char *text, unsigned int size) 1052 | { 1053 | char **list = NULL; 1054 | int n; 1055 | XTextProperty name; 1056 | 1057 | if (!text || size == 0) 1058 | return 0; 1059 | text[0] = '\0'; 1060 | if (!XGetTextProperty(dpy, w, &name, atom) || !name.nitems) 1061 | return 0; 1062 | if (name.encoding == XA_STRING) 1063 | strncpy(text, (char *)name.value, size - 1); 1064 | else { 1065 | if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) { 1066 | strncpy(text, *list, size - 1); 1067 | XFreeStringList(list); 1068 | } 1069 | } 1070 | text[size - 1] = '\0'; 1071 | XFree(name.value); 1072 | return 1; 1073 | } 1074 | 1075 | void 1076 | grabbuttons(Client *c, int focused) 1077 | { 1078 | updatenumlockmask(); 1079 | { 1080 | unsigned int i, j; 1081 | unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; 1082 | XUngrabButton(dpy, AnyButton, AnyModifier, c->win); 1083 | if (!focused) 1084 | XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, 1085 | BUTTONMASK, GrabModeSync, GrabModeSync, None, None); 1086 | for (i = 0; i < LENGTH(buttons); i++) 1087 | if (buttons[i].click == ClkClientWin) 1088 | for (j = 0; j < LENGTH(modifiers); j++) 1089 | XGrabButton(dpy, buttons[i].button, 1090 | buttons[i].mask | modifiers[j], 1091 | c->win, False, BUTTONMASK, 1092 | GrabModeAsync, GrabModeSync, None, None); 1093 | } 1094 | } 1095 | 1096 | void 1097 | grabkeys(void) 1098 | { 1099 | updatenumlockmask(); 1100 | { 1101 | unsigned int i, j; 1102 | unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; 1103 | KeyCode code; 1104 | 1105 | XUngrabKey(dpy, AnyKey, AnyModifier, root); 1106 | for (i = 0; i < LENGTH(keys); i++) 1107 | if ((code = XKeysymToKeycode(dpy, keys[i].keysym))) 1108 | for (j = 0; j < LENGTH(modifiers); j++) 1109 | XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, 1110 | True, GrabModeAsync, GrabModeAsync); 1111 | } 1112 | } 1113 | 1114 | void 1115 | incnmaster(const Arg *arg) 1116 | { 1117 | selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); 1118 | arrange(selmon); 1119 | } 1120 | 1121 | #ifdef XINERAMA 1122 | static int 1123 | isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) 1124 | { 1125 | while (n--) 1126 | if (unique[n].x_org == info->x_org && unique[n].y_org == info->y_org 1127 | && unique[n].width == info->width && unique[n].height == info->height) 1128 | return 0; 1129 | return 1; 1130 | } 1131 | #endif /* XINERAMA */ 1132 | 1133 | void 1134 | keypress(XEvent *e) 1135 | { 1136 | unsigned int i; 1137 | KeySym keysym; 1138 | XKeyEvent *ev; 1139 | 1140 | ev = &e->xkey; 1141 | keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); 1142 | for (i = 0; i < LENGTH(keys); i++) 1143 | if (keysym == keys[i].keysym 1144 | && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) 1145 | && keys[i].func) 1146 | keys[i].func(&(keys[i].arg)); 1147 | } 1148 | 1149 | void 1150 | killclient(const Arg *arg) 1151 | { 1152 | if (!selmon->sel) 1153 | return; 1154 | if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) { 1155 | XGrabServer(dpy); 1156 | XSetErrorHandler(xerrordummy); 1157 | XSetCloseDownMode(dpy, DestroyAll); 1158 | XKillClient(dpy, selmon->sel->win); 1159 | XSync(dpy, False); 1160 | XSetErrorHandler(xerror); 1161 | XUngrabServer(dpy); 1162 | } 1163 | } 1164 | 1165 | void 1166 | manage(Window w, XWindowAttributes *wa) 1167 | { 1168 | Client *c, *t = NULL; 1169 | Window trans = None; 1170 | XWindowChanges wc; 1171 | 1172 | c = ecalloc(1, sizeof(Client)); 1173 | c->win = w; 1174 | /* geometry */ 1175 | c->x = c->oldx = wa->x; 1176 | c->y = c->oldy = wa->y; 1177 | c->w = c->oldw = wa->width; 1178 | c->h = c->oldh = wa->height; 1179 | c->oldbw = wa->border_width; 1180 | 1181 | updatetitle(c); 1182 | if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) { 1183 | c->mon = t->mon; 1184 | c->tags = t->tags; 1185 | } else { 1186 | c->mon = selmon; 1187 | applyrules(c); 1188 | } 1189 | 1190 | if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw) 1191 | c->x = c->mon->mx + c->mon->mw - WIDTH(c); 1192 | if (c->y + HEIGHT(c) > c->mon->my + c->mon->mh) 1193 | c->y = c->mon->my + c->mon->mh - HEIGHT(c); 1194 | c->x = MAX(c->x, c->mon->mx); 1195 | /* only fix client y-offset, if the client center might cover the bar */ 1196 | c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx) 1197 | && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); 1198 | c->bw = borderpx; 1199 | 1200 | wc.border_width = c->bw; 1201 | XConfigureWindow(dpy, w, CWBorderWidth, &wc); 1202 | XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel); 1203 | configure(c); /* propagates border_width, if size doesn't change */ 1204 | updatewindowtype(c); 1205 | updatesizehints(c); 1206 | updatewmhints(c); 1207 | XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); 1208 | grabbuttons(c, 0); 1209 | if (!c->isfloating) 1210 | c->isfloating = c->oldstate = trans != None || c->isfixed; 1211 | if (c->isfloating) 1212 | XRaiseWindow(dpy, c->win); 1213 | attach(c); 1214 | attachstack(c); 1215 | XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, 1216 | (unsigned char *) &(c->win), 1); 1217 | XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ 1218 | setclientstate(c, NormalState); 1219 | if (c->mon == selmon) 1220 | unfocus(selmon->sel, 0); 1221 | c->mon->sel = c; 1222 | arrange(c->mon); 1223 | XMapWindow(dpy, c->win); 1224 | focus(NULL); 1225 | } 1226 | 1227 | void 1228 | mappingnotify(XEvent *e) 1229 | { 1230 | XMappingEvent *ev = &e->xmapping; 1231 | 1232 | XRefreshKeyboardMapping(ev); 1233 | if (ev->request == MappingKeyboard) 1234 | grabkeys(); 1235 | } 1236 | 1237 | void 1238 | maprequest(XEvent *e) 1239 | { 1240 | static XWindowAttributes wa; 1241 | XMapRequestEvent *ev = &e->xmaprequest; 1242 | Client *i; 1243 | if ((i = wintosystrayicon(ev->window))) { 1244 | sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION); 1245 | resizebarwin(selmon); 1246 | updatesystray(); 1247 | } 1248 | 1249 | if (!XGetWindowAttributes(dpy, ev->window, &wa)) 1250 | return; 1251 | if (wa.override_redirect) 1252 | return; 1253 | if (!wintoclient(ev->window)) 1254 | manage(ev->window, &wa); 1255 | } 1256 | 1257 | void 1258 | monocle(Monitor *m) 1259 | { 1260 | unsigned int n = 0; 1261 | Client *c; 1262 | 1263 | for (c = m->clients; c; c = c->next) 1264 | if (ISVISIBLE(c)) 1265 | n++; 1266 | if (n > 0) /* override layout symbol */ 1267 | snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); 1268 | for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) 1269 | resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); 1270 | } 1271 | 1272 | void 1273 | motionnotify(XEvent *e) 1274 | { 1275 | static Monitor *mon = NULL; 1276 | Monitor *m; 1277 | XMotionEvent *ev = &e->xmotion; 1278 | 1279 | if (ev->window != root) 1280 | return; 1281 | if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) { 1282 | unfocus(selmon->sel, 1); 1283 | selmon = m; 1284 | focus(NULL); 1285 | } 1286 | mon = m; 1287 | } 1288 | 1289 | void 1290 | movemouse(const Arg *arg) 1291 | { 1292 | int x, y, ocx, ocy, nx, ny; 1293 | Client *c; 1294 | Monitor *m; 1295 | XEvent ev; 1296 | Time lasttime = 0; 1297 | 1298 | if (!(c = selmon->sel)) 1299 | return; 1300 | if (c->isfullscreen) /* no support moving fullscreen windows by mouse */ 1301 | return; 1302 | restack(selmon); 1303 | ocx = c->x; 1304 | ocy = c->y; 1305 | if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, 1306 | None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess) 1307 | return; 1308 | if (!getrootptr(&x, &y)) 1309 | return; 1310 | do { 1311 | XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); 1312 | switch(ev.type) { 1313 | case ConfigureRequest: 1314 | case Expose: 1315 | case MapRequest: 1316 | handler[ev.type](&ev); 1317 | break; 1318 | case MotionNotify: 1319 | if ((ev.xmotion.time - lasttime) <= (1000 / 60)) 1320 | continue; 1321 | lasttime = ev.xmotion.time; 1322 | 1323 | nx = ocx + (ev.xmotion.x - x); 1324 | ny = ocy + (ev.xmotion.y - y); 1325 | if (abs(selmon->wx - nx) < snap) 1326 | nx = selmon->wx; 1327 | else if (abs((selmon->wx + selmon->ww) - (nx + WIDTH(c))) < snap) 1328 | nx = selmon->wx + selmon->ww - WIDTH(c); 1329 | if (abs(selmon->wy - ny) < snap) 1330 | ny = selmon->wy; 1331 | else if (abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap) 1332 | ny = selmon->wy + selmon->wh - HEIGHT(c); 1333 | if (!c->isfloating && selmon->lt[selmon->sellt]->arrange 1334 | && (abs(nx - c->x) > snap || abs(ny - c->y) > snap)) 1335 | togglefloating(NULL); 1336 | if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) 1337 | resize(c, nx, ny, c->w, c->h, 1); 1338 | break; 1339 | } 1340 | } while (ev.type != ButtonRelease); 1341 | XUngrabPointer(dpy, CurrentTime); 1342 | if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { 1343 | sendmon(c, m); 1344 | selmon = m; 1345 | focus(NULL); 1346 | } 1347 | } 1348 | 1349 | Client * 1350 | nexttiled(Client *c) 1351 | { 1352 | for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); 1353 | return c; 1354 | } 1355 | 1356 | void 1357 | pop(Client *c) 1358 | { 1359 | detach(c); 1360 | attach(c); 1361 | focus(c); 1362 | arrange(c->mon); 1363 | } 1364 | 1365 | void 1366 | propertynotify(XEvent *e) 1367 | { 1368 | Client *c; 1369 | Window trans; 1370 | XPropertyEvent *ev = &e->xproperty; 1371 | 1372 | if ((c = wintosystrayicon(ev->window))) { 1373 | if (ev->atom == XA_WM_NORMAL_HINTS) { 1374 | updatesizehints(c); 1375 | updatesystrayicongeom(c, c->w, c->h); 1376 | } 1377 | else 1378 | updatesystrayiconstate(c, ev); 1379 | resizebarwin(selmon); 1380 | updatesystray(); 1381 | } 1382 | if ((ev->window == root) && (ev->atom == XA_WM_NAME)) 1383 | updatestatus(); 1384 | else if (ev->state == PropertyDelete) 1385 | return; /* ignore */ 1386 | else if ((c = wintoclient(ev->window))) { 1387 | switch(ev->atom) { 1388 | default: break; 1389 | case XA_WM_TRANSIENT_FOR: 1390 | if (!c->isfloating && (XGetTransientForHint(dpy, c->win, &trans)) && 1391 | (c->isfloating = (wintoclient(trans)) != NULL)) 1392 | arrange(c->mon); 1393 | break; 1394 | case XA_WM_NORMAL_HINTS: 1395 | updatesizehints(c); 1396 | break; 1397 | case XA_WM_HINTS: 1398 | updatewmhints(c); 1399 | drawbars(); 1400 | break; 1401 | } 1402 | if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { 1403 | updatetitle(c); 1404 | if (c == c->mon->sel) 1405 | drawbar(c->mon); 1406 | } 1407 | if (ev->atom == netatom[NetWMWindowType]) 1408 | updatewindowtype(c); 1409 | } 1410 | } 1411 | /* 1412 | void 1413 | quit(const Arg *arg) 1414 | { 1415 | running = 0; 1416 | } 1417 | */ 1418 | 1419 | Monitor * 1420 | recttomon(int x, int y, int w, int h) 1421 | { 1422 | Monitor *m, *r = selmon; 1423 | int a, area = 0; 1424 | 1425 | for (m = mons; m; m = m->next) 1426 | if ((a = INTERSECT(x, y, w, h, m)) > area) { 1427 | area = a; 1428 | r = m; 1429 | } 1430 | return r; 1431 | } 1432 | 1433 | void 1434 | removesystrayicon(Client *i) 1435 | { 1436 | Client **ii; 1437 | 1438 | if (!showsystray || !i) 1439 | return; 1440 | for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next); 1441 | if (ii) 1442 | *ii = i->next; 1443 | free(i); 1444 | } 1445 | 1446 | 1447 | void 1448 | resize(Client *c, int x, int y, int w, int h, int interact) 1449 | { 1450 | if (applysizehints(c, &x, &y, &w, &h, interact)) 1451 | resizeclient(c, x, y, w, h); 1452 | } 1453 | 1454 | void 1455 | resizebarwin(Monitor *m) { 1456 | unsigned int w = m->ww; 1457 | if (showsystray && m == systraytomon(m)) 1458 | w -= getsystraywidth(); 1459 | XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh); 1460 | } 1461 | 1462 | void 1463 | resizeclient(Client *c, int x, int y, int w, int h) 1464 | { 1465 | XWindowChanges wc; 1466 | 1467 | c->oldx = c->x; c->x = wc.x = x; 1468 | c->oldy = c->y; c->y = wc.y = y; 1469 | c->oldw = c->w; c->w = wc.width = w; 1470 | c->oldh = c->h; c->h = wc.height = h; 1471 | wc.border_width = c->bw; 1472 | XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); 1473 | configure(c); 1474 | XSync(dpy, False); 1475 | } 1476 | 1477 | void 1478 | resizemouse(const Arg *arg) 1479 | { 1480 | int ocx, ocy, nw, nh; 1481 | Client *c; 1482 | Monitor *m; 1483 | XEvent ev; 1484 | Time lasttime = 0; 1485 | 1486 | if (!(c = selmon->sel)) 1487 | return; 1488 | if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */ 1489 | return; 1490 | restack(selmon); 1491 | ocx = c->x; 1492 | ocy = c->y; 1493 | if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, 1494 | None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess) 1495 | return; 1496 | XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); 1497 | do { 1498 | XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); 1499 | switch(ev.type) { 1500 | case ConfigureRequest: 1501 | case Expose: 1502 | case MapRequest: 1503 | handler[ev.type](&ev); 1504 | break; 1505 | case MotionNotify: 1506 | if ((ev.xmotion.time - lasttime) <= (1000 / 60)) 1507 | continue; 1508 | lasttime = ev.xmotion.time; 1509 | 1510 | nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1); 1511 | nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1); 1512 | if (c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww 1513 | && c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh) 1514 | { 1515 | if (!c->isfloating && selmon->lt[selmon->sellt]->arrange 1516 | && (abs(nw - c->w) > snap || abs(nh - c->h) > snap)) 1517 | togglefloating(NULL); 1518 | } 1519 | if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) 1520 | resize(c, c->x, c->y, nw, nh, 1); 1521 | break; 1522 | } 1523 | } while (ev.type != ButtonRelease); 1524 | XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); 1525 | XUngrabPointer(dpy, CurrentTime); 1526 | while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); 1527 | if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { 1528 | sendmon(c, m); 1529 | selmon = m; 1530 | focus(NULL); 1531 | } 1532 | } 1533 | 1534 | void 1535 | resizerequest(XEvent *e) 1536 | { 1537 | XResizeRequestEvent *ev = &e->xresizerequest; 1538 | Client *i; 1539 | 1540 | if ((i = wintosystrayicon(ev->window))) { 1541 | updatesystrayicongeom(i, ev->width, ev->height); 1542 | resizebarwin(selmon); 1543 | updatesystray(); 1544 | } 1545 | } 1546 | 1547 | void 1548 | restack(Monitor *m) 1549 | { 1550 | Client *c; 1551 | XEvent ev; 1552 | XWindowChanges wc; 1553 | 1554 | drawbar(m); 1555 | if (!m->sel) 1556 | return; 1557 | if (m->sel->isfloating || !m->lt[m->sellt]->arrange) 1558 | XRaiseWindow(dpy, m->sel->win); 1559 | if (m->lt[m->sellt]->arrange) { 1560 | wc.stack_mode = Below; 1561 | wc.sibling = m->barwin; 1562 | for (c = m->stack; c; c = c->snext) 1563 | if (!c->isfloating && ISVISIBLE(c)) { 1564 | XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc); 1565 | wc.sibling = c->win; 1566 | } 1567 | } 1568 | XSync(dpy, False); 1569 | while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); 1570 | } 1571 | 1572 | void 1573 | run(void) 1574 | { 1575 | XEvent ev; 1576 | /* main event loop */ 1577 | XSync(dpy, False); 1578 | while (running && !XNextEvent(dpy, &ev)) 1579 | if (handler[ev.type]) 1580 | handler[ev.type](&ev); /* call handler */ 1581 | } 1582 | 1583 | void 1584 | runautostart(void) 1585 | { 1586 | char *pathpfx; 1587 | char *path; 1588 | char *xdgdatahome; 1589 | char *home; 1590 | struct stat sb; 1591 | 1592 | if ((home = getenv("HOME")) == NULL) 1593 | /* this is almost impossible */ 1594 | return; 1595 | 1596 | /* if $XDG_DATA_HOME is set and not empty, use $XDG_DATA_HOME/dwm, 1597 | * otherwise use ~/.local/share/dwm as autostart script directory 1598 | */ 1599 | xdgdatahome = getenv("XDG_DATA_HOME"); 1600 | if (xdgdatahome != NULL && *xdgdatahome != '\0') { 1601 | /* space for path segments, separators and nul */ 1602 | pathpfx = ecalloc(1, strlen(xdgdatahome) + strlen(dwmdir) + 2); 1603 | 1604 | if (sprintf(pathpfx, "%s/%s", xdgdatahome, dwmdir) <= 0) { 1605 | free(pathpfx); 1606 | return; 1607 | } 1608 | } else { 1609 | /* space for path segments, separators and nul */ 1610 | pathpfx = ecalloc(1, strlen(home) + strlen(localshare) 1611 | + strlen(dwmdir) + 3); 1612 | 1613 | if (sprintf(pathpfx, "%s/%s/%s", home, localshare, dwmdir) < 0) { 1614 | free(pathpfx); 1615 | return; 1616 | } 1617 | } 1618 | 1619 | /* check if the autostart script directory exists */ 1620 | if (! (stat(pathpfx, &sb) == 0 && S_ISDIR(sb.st_mode))) { 1621 | /* the XDG conformant path does not exist or is no directory 1622 | * so we try ~/.dwm instead 1623 | */ 1624 | char *pathpfx_new = realloc(pathpfx, strlen(home) + strlen(dwmdir) + 3); 1625 | if(pathpfx_new == NULL) { 1626 | free(pathpfx); 1627 | return; 1628 | } 1629 | pathpfx = pathpfx_new; 1630 | 1631 | if (sprintf(pathpfx, "%s/.%s", home, dwmdir) <= 0) { 1632 | free(pathpfx); 1633 | return; 1634 | } 1635 | } 1636 | 1637 | /* try the blocking script first */ 1638 | path = ecalloc(1, strlen(pathpfx) + strlen(autostartblocksh) + 2); 1639 | if (sprintf(path, "%s/%s", pathpfx, autostartblocksh) <= 0) { 1640 | free(path); 1641 | free(pathpfx); 1642 | } 1643 | 1644 | if (access(path, X_OK) == 0) 1645 | system(path); 1646 | 1647 | /* now the non-blocking script */ 1648 | if (sprintf(path, "%s/%s", pathpfx, autostartsh) <= 0) { 1649 | free(path); 1650 | free(pathpfx); 1651 | } 1652 | 1653 | if (access(path, X_OK) == 0) 1654 | system(strcat(path, " &")); 1655 | 1656 | free(pathpfx); 1657 | free(path); 1658 | } 1659 | 1660 | void 1661 | scan(void) 1662 | { 1663 | unsigned int i, num; 1664 | Window d1, d2, *wins = NULL; 1665 | XWindowAttributes wa; 1666 | 1667 | if (XQueryTree(dpy, root, &d1, &d2, &wins, &num)) { 1668 | for (i = 0; i < num; i++) { 1669 | if (!XGetWindowAttributes(dpy, wins[i], &wa) 1670 | || wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) 1671 | continue; 1672 | if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState) 1673 | manage(wins[i], &wa); 1674 | } 1675 | for (i = 0; i < num; i++) { /* now the transients */ 1676 | if (!XGetWindowAttributes(dpy, wins[i], &wa)) 1677 | continue; 1678 | if (XGetTransientForHint(dpy, wins[i], &d1) 1679 | && (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)) 1680 | manage(wins[i], &wa); 1681 | } 1682 | if (wins) 1683 | XFree(wins); 1684 | } 1685 | } 1686 | 1687 | void 1688 | sendmon(Client *c, Monitor *m) 1689 | { 1690 | if (c->mon == m) 1691 | return; 1692 | unfocus(c, 1); 1693 | detach(c); 1694 | detachstack(c); 1695 | c->mon = m; 1696 | c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ 1697 | attach(c); 1698 | attachstack(c); 1699 | focus(NULL); 1700 | arrange(NULL); 1701 | } 1702 | 1703 | void 1704 | setclientstate(Client *c, long state) 1705 | { 1706 | long data[] = { state, None }; 1707 | 1708 | XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32, 1709 | PropModeReplace, (unsigned char *)data, 2); 1710 | } 1711 | 1712 | int 1713 | sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, long d4) 1714 | { 1715 | int n; 1716 | Atom *protocols, mt; 1717 | int exists = 0; 1718 | XEvent ev; 1719 | 1720 | if (proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) { 1721 | mt = wmatom[WMProtocols]; 1722 | if (XGetWMProtocols(dpy, w, &protocols, &n)) { 1723 | while (!exists && n--) 1724 | exists = protocols[n] == proto; 1725 | XFree(protocols); 1726 | } 1727 | } 1728 | else { 1729 | exists = True; 1730 | mt = proto; 1731 | } 1732 | if (exists) { 1733 | ev.type = ClientMessage; 1734 | ev.xclient.window = w; 1735 | ev.xclient.message_type = mt; 1736 | ev.xclient.format = 32; 1737 | ev.xclient.data.l[0] = d0; 1738 | ev.xclient.data.l[1] = d1; 1739 | ev.xclient.data.l[2] = d2; 1740 | ev.xclient.data.l[3] = d3; 1741 | ev.xclient.data.l[4] = d4; 1742 | XSendEvent(dpy, w, False, mask, &ev); 1743 | } 1744 | return exists; 1745 | } 1746 | 1747 | void 1748 | setfocus(Client *c) 1749 | { 1750 | if (!c->neverfocus) { 1751 | XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); 1752 | XChangeProperty(dpy, root, netatom[NetActiveWindow], 1753 | XA_WINDOW, 32, PropModeReplace, 1754 | (unsigned char *) &(c->win), 1); 1755 | } 1756 | sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0); 1757 | } 1758 | 1759 | void 1760 | setfullscreen(Client *c, int fullscreen) 1761 | { 1762 | if (fullscreen && !c->isfullscreen) { 1763 | XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, 1764 | PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1); 1765 | c->isfullscreen = 1; 1766 | c->oldstate = c->isfloating; 1767 | c->oldbw = c->bw; 1768 | c->bw = 0; 1769 | c->isfloating = 1; 1770 | resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh); 1771 | XRaiseWindow(dpy, c->win); 1772 | } else if (!fullscreen && c->isfullscreen){ 1773 | XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, 1774 | PropModeReplace, (unsigned char*)0, 0); 1775 | c->isfullscreen = 0; 1776 | c->isfloating = c->oldstate; 1777 | c->bw = c->oldbw; 1778 | c->x = c->oldx; 1779 | c->y = c->oldy; 1780 | c->w = c->oldw; 1781 | c->h = c->oldh; 1782 | resizeclient(c, c->x, c->y, c->w, c->h); 1783 | arrange(c->mon); 1784 | } 1785 | } 1786 | 1787 | void 1788 | setgaps(const Arg *arg) 1789 | { 1790 | if ((arg->i == 0) || (selmon->gappx + arg->i < 0)) 1791 | selmon->gappx = 0; 1792 | else 1793 | selmon->gappx += arg->i; 1794 | arrange(selmon); 1795 | } 1796 | 1797 | void 1798 | setlayout(const Arg *arg) 1799 | { 1800 | if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) 1801 | selmon->sellt ^= 1; 1802 | if (arg && arg->v) 1803 | selmon->lt[selmon->sellt] = (Layout *)arg->v; 1804 | strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); 1805 | if (selmon->sel) 1806 | arrange(selmon); 1807 | else 1808 | drawbar(selmon); 1809 | } 1810 | 1811 | /* arg > 1.0 will set mfact absolutely */ 1812 | void 1813 | setmfact(const Arg *arg) 1814 | { 1815 | float f; 1816 | 1817 | if (!arg || !selmon->lt[selmon->sellt]->arrange) 1818 | return; 1819 | f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; 1820 | if (f < 0.1 || f > 0.9) 1821 | return; 1822 | selmon->mfact = f; 1823 | arrange(selmon); 1824 | } 1825 | 1826 | void 1827 | setup(void) 1828 | { 1829 | int i; 1830 | XSetWindowAttributes wa; 1831 | Atom utf8string; 1832 | 1833 | /* clean up any zombies immediately */ 1834 | sigchld(0); 1835 | 1836 | /* init screen */ 1837 | screen = DefaultScreen(dpy); 1838 | sw = DisplayWidth(dpy, screen); 1839 | sh = DisplayHeight(dpy, screen); 1840 | root = RootWindow(dpy, screen); 1841 | xinitvisual(); 1842 | drw = drw_create(dpy, screen, root, sw, sh, visual, depth, cmap); 1843 | if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) 1844 | die("no fonts could be loaded."); 1845 | lrpad = drw->fonts->h; 1846 | bh = drw->fonts->h + 2; 1847 | updategeom(); 1848 | /* init atoms */ 1849 | utf8string = XInternAtom(dpy, "UTF8_STRING", False); 1850 | wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); 1851 | wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); 1852 | wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False); 1853 | wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); 1854 | netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); 1855 | netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); 1856 | netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False); 1857 | netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False); 1858 | netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False); 1859 | netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION_HORZ", False); 1860 | netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); 1861 | netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); 1862 | netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False); 1863 | netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); 1864 | netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); 1865 | netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); 1866 | netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); 1867 | xatom[Manager] = XInternAtom(dpy, "MANAGER", False); 1868 | xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False); 1869 | xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False); 1870 | /* init cursors */ 1871 | cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); 1872 | cursor[CurResize] = drw_cur_create(drw, XC_sizing); 1873 | cursor[CurMove] = drw_cur_create(drw, XC_fleur); 1874 | /* init appearance */ 1875 | scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); 1876 | for (i = 0; i < LENGTH(colors); i++) 1877 | scheme[i] = drw_scm_create(drw, colors[i], alphas[i], 3); 1878 | /* init system tray */ 1879 | updatesystray(); 1880 | /* init bars */ 1881 | updatebars(); 1882 | updatestatus(); 1883 | /* supporting window for NetWMCheck */ 1884 | wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0); 1885 | XChangeProperty(dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32, 1886 | PropModeReplace, (unsigned char *) &wmcheckwin, 1); 1887 | XChangeProperty(dpy, wmcheckwin, netatom[NetWMName], utf8string, 8, 1888 | PropModeReplace, (unsigned char *) "dwm", 3); 1889 | XChangeProperty(dpy, root, netatom[NetWMCheck], XA_WINDOW, 32, 1890 | PropModeReplace, (unsigned char *) &wmcheckwin, 1); 1891 | /* EWMH support per view */ 1892 | XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32, 1893 | PropModeReplace, (unsigned char *) netatom, NetLast); 1894 | XDeleteProperty(dpy, root, netatom[NetClientList]); 1895 | /* select events */ 1896 | wa.cursor = cursor[CurNormal]->cursor; 1897 | wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask 1898 | |ButtonPressMask|PointerMotionMask|EnterWindowMask 1899 | |LeaveWindowMask|StructureNotifyMask|PropertyChangeMask; 1900 | XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa); 1901 | XSelectInput(dpy, root, wa.event_mask); 1902 | grabkeys(); 1903 | focus(NULL); 1904 | } 1905 | 1906 | 1907 | void 1908 | seturgent(Client *c, int urg) 1909 | { 1910 | XWMHints *wmh; 1911 | 1912 | c->isurgent = urg; 1913 | if (!(wmh = XGetWMHints(dpy, c->win))) 1914 | return; 1915 | wmh->flags = urg ? (wmh->flags | XUrgencyHint) : (wmh->flags & ~XUrgencyHint); 1916 | XSetWMHints(dpy, c->win, wmh); 1917 | XFree(wmh); 1918 | } 1919 | 1920 | void 1921 | showhide(Client *c) 1922 | { 1923 | if (!c) 1924 | return; 1925 | if (ISVISIBLE(c)) { 1926 | /* show clients top down */ 1927 | XMoveWindow(dpy, c->win, c->x, c->y); 1928 | if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) 1929 | resize(c, c->x, c->y, c->w, c->h, 0); 1930 | showhide(c->snext); 1931 | } else { 1932 | /* hide clients bottom up */ 1933 | showhide(c->snext); 1934 | XMoveWindow(dpy, c->win, WIDTH(c) * -2, c->y); 1935 | } 1936 | } 1937 | 1938 | void 1939 | sigchld(int unused) 1940 | { 1941 | if (signal(SIGCHLD, sigchld) == SIG_ERR) 1942 | die("can't install SIGCHLD handler:"); 1943 | while (0 < waitpid(-1, NULL, WNOHANG)); 1944 | } 1945 | 1946 | void 1947 | spawn(const Arg *arg) 1948 | { 1949 | if (arg->v == dmenucmd) 1950 | dmenumon[0] = '0' + selmon->num; 1951 | if (fork() == 0) { 1952 | if (dpy) 1953 | close(ConnectionNumber(dpy)); 1954 | setsid(); 1955 | execvp(((char **)arg->v)[0], (char **)arg->v); 1956 | fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]); 1957 | perror(" failed"); 1958 | exit(EXIT_SUCCESS); 1959 | } 1960 | } 1961 | 1962 | void 1963 | tag(const Arg *arg) 1964 | { 1965 | if (selmon->sel && arg->ui & TAGMASK) { 1966 | selmon->sel->tags = arg->ui & TAGMASK; 1967 | focus(NULL); 1968 | arrange(selmon); 1969 | if(viewontag) 1970 | view(arg); 1971 | } 1972 | } 1973 | 1974 | void 1975 | tagmon(const Arg *arg) 1976 | { 1977 | if (!selmon->sel || !mons->next) 1978 | return; 1979 | sendmon(selmon->sel, dirtomon(arg->i)); 1980 | } 1981 | 1982 | void 1983 | tile(Monitor *m) 1984 | { 1985 | unsigned int i, n, h, mw, my, ty; 1986 | Client *c; 1987 | 1988 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); 1989 | if (n == 0) 1990 | return; 1991 | 1992 | if (n > m->nmaster) 1993 | mw = m->nmaster ? m->ww * m->mfact : 0; 1994 | else 1995 | mw = m->ww - m->gappx; 1996 | for (i = 0, my = ty = m->gappx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 1997 | if (i < m->nmaster) { 1998 | h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx; 1999 | resize(c, m->wx + m->gappx, m->wy + my, mw - (2*c->bw) - m->gappx, h - (2*c->bw), 0); 2000 | my += HEIGHT(c) + m->gappx; 2001 | } else { 2002 | h = (m->wh - ty) / (n - i) - m->gappx; 2003 | resize(c, m->wx + mw + m->gappx, m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->gappx, h - (2*c->bw), 0); 2004 | ty += HEIGHT(c) + m->gappx; 2005 | } 2006 | } 2007 | 2008 | void 2009 | togglebar(const Arg *arg) 2010 | { 2011 | selmon->showbar = !selmon->showbar; 2012 | updatebarpos(selmon); 2013 | resizebarwin(selmon); 2014 | if (showsystray) { 2015 | XWindowChanges wc; 2016 | if (!selmon->showbar) 2017 | wc.y = -bh; 2018 | else if (selmon->showbar) { 2019 | wc.y = 0; 2020 | if (!selmon->topbar) 2021 | wc.y = selmon->mh - bh; 2022 | } 2023 | XConfigureWindow(dpy, systray->win, CWY, &wc); 2024 | } 2025 | arrange(selmon); 2026 | } 2027 | 2028 | void 2029 | togglefloating(const Arg *arg) 2030 | { 2031 | if (!selmon->sel) 2032 | return; 2033 | if (selmon->sel->isfullscreen) /* no support for fullscreen windows */ 2034 | return; 2035 | selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; 2036 | if (selmon->sel->isfloating) 2037 | resize(selmon->sel, selmon->sel->x, selmon->sel->y, 2038 | selmon->sel->w, selmon->sel->h, 0); 2039 | arrange(selmon); 2040 | } 2041 | 2042 | void 2043 | toggletag(const Arg *arg) 2044 | { 2045 | unsigned int newtags; 2046 | 2047 | if (!selmon->sel) 2048 | return; 2049 | newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); 2050 | if (newtags) { 2051 | selmon->sel->tags = newtags; 2052 | focus(NULL); 2053 | arrange(selmon); 2054 | } 2055 | } 2056 | 2057 | void 2058 | toggleview(const Arg *arg) 2059 | { 2060 | unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); 2061 | 2062 | if (newtagset) { 2063 | selmon->tagset[selmon->seltags] = newtagset; 2064 | focus(NULL); 2065 | arrange(selmon); 2066 | } 2067 | } 2068 | 2069 | void 2070 | unfocus(Client *c, int setfocus) 2071 | { 2072 | if (!c) 2073 | return; 2074 | grabbuttons(c, 0); 2075 | XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel); 2076 | if (setfocus) { 2077 | XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); 2078 | XDeleteProperty(dpy, root, netatom[NetActiveWindow]); 2079 | } 2080 | } 2081 | 2082 | void 2083 | unmanage(Client *c, int destroyed) 2084 | { 2085 | Monitor *m = c->mon; 2086 | XWindowChanges wc; 2087 | 2088 | detach(c); 2089 | detachstack(c); 2090 | if (!destroyed) { 2091 | wc.border_width = c->oldbw; 2092 | XGrabServer(dpy); /* avoid race conditions */ 2093 | XSetErrorHandler(xerrordummy); 2094 | XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */ 2095 | XUngrabButton(dpy, AnyButton, AnyModifier, c->win); 2096 | setclientstate(c, WithdrawnState); 2097 | XSync(dpy, False); 2098 | XSetErrorHandler(xerror); 2099 | XUngrabServer(dpy); 2100 | } 2101 | free(c); 2102 | focus(NULL); 2103 | updateclientlist(); 2104 | arrange(m); 2105 | } 2106 | 2107 | void 2108 | unmapnotify(XEvent *e) 2109 | { 2110 | Client *c; 2111 | XUnmapEvent *ev = &e->xunmap; 2112 | 2113 | if ((c = wintoclient(ev->window))) { 2114 | if (ev->send_event) 2115 | setclientstate(c, WithdrawnState); 2116 | else 2117 | unmanage(c, 0); 2118 | } 2119 | else if ((c = wintosystrayicon(ev->window))) { 2120 | /* KLUDGE! sometimes icons occasionally unmap their windows, but do 2121 | * _not_ destroy them. We map those windows back */ 2122 | XMapRaised(dpy, c->win); 2123 | updatesystray(); 2124 | } 2125 | } 2126 | 2127 | void 2128 | updatebars(void) 2129 | { 2130 | unsigned int w; 2131 | Monitor *m; 2132 | XSetWindowAttributes wa = { 2133 | .override_redirect = True, 2134 | .background_pixel = 0, 2135 | .border_pixel = 0, 2136 | .colormap = cmap, 2137 | .event_mask = ButtonPressMask|ExposureMask 2138 | }; 2139 | XClassHint ch = {"dwm", "dwm"}; 2140 | for (m = mons; m; m = m->next) { 2141 | if (m->barwin) 2142 | continue; 2143 | w = m->ww; 2144 | if (showsystray && m == systraytomon(m)) 2145 | w -= getsystraywidth(); 2146 | m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, depth, 2147 | InputOutput, visual, 2148 | CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa); 2149 | XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); 2150 | if (showsystray && m == systraytomon(m)) 2151 | XMapRaised(dpy, systray->win); 2152 | XMapRaised(dpy, m->barwin); 2153 | XSetClassHint(dpy, m->barwin, &ch); 2154 | } 2155 | } 2156 | 2157 | void 2158 | updatebarpos(Monitor *m) 2159 | { 2160 | m->wy = m->my; 2161 | m->wh = m->mh; 2162 | if (m->showbar) { 2163 | m->wh -= bh; 2164 | m->by = m->topbar ? m->wy : m->wy + m->wh; 2165 | m->wy = m->topbar ? m->wy + bh : m->wy; 2166 | } else 2167 | m->by = -bh; 2168 | } 2169 | 2170 | void 2171 | updateclientlist() 2172 | { 2173 | Client *c; 2174 | Monitor *m; 2175 | 2176 | XDeleteProperty(dpy, root, netatom[NetClientList]); 2177 | for (m = mons; m; m = m->next) 2178 | for (c = m->clients; c; c = c->next) 2179 | XChangeProperty(dpy, root, netatom[NetClientList], 2180 | XA_WINDOW, 32, PropModeAppend, 2181 | (unsigned char *) &(c->win), 1); 2182 | } 2183 | 2184 | int 2185 | updategeom(void) 2186 | { 2187 | int dirty = 0; 2188 | 2189 | #ifdef XINERAMA 2190 | if (XineramaIsActive(dpy)) { 2191 | int i, j, n, nn; 2192 | Client *c; 2193 | Monitor *m; 2194 | XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn); 2195 | XineramaScreenInfo *unique = NULL; 2196 | 2197 | for (n = 0, m = mons; m; m = m->next, n++); 2198 | /* only consider unique geometries as separate screens */ 2199 | unique = ecalloc(nn, sizeof(XineramaScreenInfo)); 2200 | for (i = 0, j = 0; i < nn; i++) 2201 | if (isuniquegeom(unique, j, &info[i])) 2202 | memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo)); 2203 | XFree(info); 2204 | nn = j; 2205 | if (n <= nn) { /* new monitors available */ 2206 | for (i = 0; i < (nn - n); i++) { 2207 | for (m = mons; m && m->next; m = m->next); 2208 | if (m) 2209 | m->next = createmon(); 2210 | else 2211 | mons = createmon(); 2212 | } 2213 | for (i = 0, m = mons; i < nn && m; m = m->next, i++) 2214 | if (i >= n 2215 | || unique[i].x_org != m->mx || unique[i].y_org != m->my 2216 | || unique[i].width != m->mw || unique[i].height != m->mh) 2217 | { 2218 | dirty = 1; 2219 | m->num = i; 2220 | m->mx = m->wx = unique[i].x_org; 2221 | m->my = m->wy = unique[i].y_org; 2222 | m->mw = m->ww = unique[i].width; 2223 | m->mh = m->wh = unique[i].height; 2224 | updatebarpos(m); 2225 | } 2226 | } else { /* less monitors available nn < n */ 2227 | for (i = nn; i < n; i++) { 2228 | for (m = mons; m && m->next; m = m->next); 2229 | while ((c = m->clients)) { 2230 | dirty = 1; 2231 | m->clients = c->next; 2232 | detachstack(c); 2233 | c->mon = mons; 2234 | attach(c); 2235 | attachstack(c); 2236 | } 2237 | if (m == selmon) 2238 | selmon = mons; 2239 | cleanupmon(m); 2240 | } 2241 | } 2242 | free(unique); 2243 | } else 2244 | #endif /* XINERAMA */ 2245 | { /* default monitor setup */ 2246 | if (!mons) 2247 | mons = createmon(); 2248 | if (mons->mw != sw || mons->mh != sh) { 2249 | dirty = 1; 2250 | mons->mw = mons->ww = sw; 2251 | mons->mh = mons->wh = sh; 2252 | updatebarpos(mons); 2253 | } 2254 | } 2255 | if (dirty) { 2256 | selmon = mons; 2257 | selmon = wintomon(root); 2258 | } 2259 | return dirty; 2260 | } 2261 | 2262 | void 2263 | updatenumlockmask(void) 2264 | { 2265 | unsigned int i, j; 2266 | XModifierKeymap *modmap; 2267 | 2268 | numlockmask = 0; 2269 | modmap = XGetModifierMapping(dpy); 2270 | for (i = 0; i < 8; i++) 2271 | for (j = 0; j < modmap->max_keypermod; j++) 2272 | if (modmap->modifiermap[i * modmap->max_keypermod + j] 2273 | == XKeysymToKeycode(dpy, XK_Num_Lock)) 2274 | numlockmask = (1 << i); 2275 | XFreeModifiermap(modmap); 2276 | } 2277 | 2278 | void 2279 | updatesizehints(Client *c) 2280 | { 2281 | long msize; 2282 | XSizeHints size; 2283 | 2284 | if (!XGetWMNormalHints(dpy, c->win, &size, &msize)) 2285 | /* size is uninitialized, ensure that size.flags aren't used */ 2286 | size.flags = PSize; 2287 | if (size.flags & PBaseSize) { 2288 | c->basew = size.base_width; 2289 | c->baseh = size.base_height; 2290 | } else if (size.flags & PMinSize) { 2291 | c->basew = size.min_width; 2292 | c->baseh = size.min_height; 2293 | } else 2294 | c->basew = c->baseh = 0; 2295 | if (size.flags & PResizeInc) { 2296 | c->incw = size.width_inc; 2297 | c->inch = size.height_inc; 2298 | } else 2299 | c->incw = c->inch = 0; 2300 | if (size.flags & PMaxSize) { 2301 | c->maxw = size.max_width; 2302 | c->maxh = size.max_height; 2303 | } else 2304 | c->maxw = c->maxh = 0; 2305 | if (size.flags & PMinSize) { 2306 | c->minw = size.min_width; 2307 | c->minh = size.min_height; 2308 | } else if (size.flags & PBaseSize) { 2309 | c->minw = size.base_width; 2310 | c->minh = size.base_height; 2311 | } else 2312 | c->minw = c->minh = 0; 2313 | if (size.flags & PAspect) { 2314 | c->mina = (float)size.min_aspect.y / size.min_aspect.x; 2315 | c->maxa = (float)size.max_aspect.x / size.max_aspect.y; 2316 | } else 2317 | c->maxa = c->mina = 0.0; 2318 | c->isfixed = (c->maxw && c->maxh && c->maxw == c->minw && c->maxh == c->minh); 2319 | } 2320 | 2321 | void 2322 | updatestatus(void) 2323 | { 2324 | if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) 2325 | strcpy(stext, "dwm-"VERSION); 2326 | drawbar(selmon); 2327 | updatesystray(); 2328 | } 2329 | 2330 | void 2331 | updatesystrayicongeom(Client *i, int w, int h) 2332 | { 2333 | if (i) { 2334 | i->h = bh; 2335 | if (w == h) 2336 | i->w = bh; 2337 | else if (h == bh) 2338 | i->w = w; 2339 | else 2340 | i->w = (int) ((float)bh * ((float)w / (float)h)); 2341 | applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False); 2342 | /* force icons into the systray dimenons if they don't want to */ 2343 | if (i->h > bh) { 2344 | if (i->w == i->h) 2345 | i->w = bh; 2346 | else 2347 | i->w = (int) ((float)bh * ((float)i->w / (float)i->h)); 2348 | i->h = bh; 2349 | } 2350 | } 2351 | } 2352 | 2353 | void 2354 | updatesystrayiconstate(Client *i, XPropertyEvent *ev) 2355 | { 2356 | long flags; 2357 | int code = 0; 2358 | 2359 | if (!showsystray || !i || ev->atom != xatom[XembedInfo] || 2360 | !(flags = getatomprop(i, xatom[XembedInfo]))) 2361 | return; 2362 | 2363 | if (flags & XEMBED_MAPPED && !i->tags) { 2364 | i->tags = 1; 2365 | code = XEMBED_WINDOW_ACTIVATE; 2366 | XMapRaised(dpy, i->win); 2367 | setclientstate(i, NormalState); 2368 | } 2369 | else if (!(flags & XEMBED_MAPPED) && i->tags) { 2370 | i->tags = 0; 2371 | code = XEMBED_WINDOW_DEACTIVATE; 2372 | XUnmapWindow(dpy, i->win); 2373 | setclientstate(i, WithdrawnState); 2374 | } 2375 | else 2376 | return; 2377 | sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0, 2378 | systray->win, XEMBED_EMBEDDED_VERSION); 2379 | } 2380 | 2381 | void 2382 | updatesystray(void) 2383 | { 2384 | XSetWindowAttributes wa; 2385 | XWindowChanges wc; 2386 | Client *i; 2387 | Monitor *m = systraytomon(NULL); 2388 | unsigned int x = m->mx + m->mw; 2389 | unsigned int w = 1; 2390 | 2391 | if (!showsystray) 2392 | return; 2393 | if (!systray) { 2394 | /* init systray */ 2395 | if (!(systray = (Systray *)calloc(1, sizeof(Systray)))) 2396 | die("fatal: could not malloc() %u bytes\n", sizeof(Systray)); 2397 | systray->win = XCreateSimpleWindow(dpy, root, x, m->by, w, bh, 0, 0, scheme[SchemeSel][ColBg].pixel); 2398 | wa.event_mask = ButtonPressMask | ExposureMask; 2399 | wa.override_redirect = True; 2400 | wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; 2401 | XSelectInput(dpy, systray->win, SubstructureNotifyMask); 2402 | XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32, 2403 | PropModeReplace, (unsigned char *)&netatom[NetSystemTrayOrientationHorz], 1); 2404 | XChangeWindowAttributes(dpy, systray->win, CWEventMask|CWOverrideRedirect|CWBackPixel, &wa); 2405 | XMapRaised(dpy, systray->win); 2406 | XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime); 2407 | if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) { 2408 | sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0); 2409 | XSync(dpy, False); 2410 | } 2411 | else { 2412 | fprintf(stderr, "dwm: unable to obtain system tray.\n"); 2413 | free(systray); 2414 | systray = NULL; 2415 | return; 2416 | } 2417 | } 2418 | for (w = 0, i = systray->icons; i; i = i->next) { 2419 | /* make sure the background color stays the same */ 2420 | wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; 2421 | XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa); 2422 | XMapRaised(dpy, i->win); 2423 | w += systrayspacing; 2424 | i->x = w; 2425 | XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h); 2426 | w += i->w; 2427 | if (i->mon != m) 2428 | i->mon = m; 2429 | } 2430 | w = w ? w + systrayspacing : 1; 2431 | x -= w; 2432 | XMoveResizeWindow(dpy, systray->win, x, m->by, w, bh); 2433 | wc.x = x; wc.y = m->by; wc.width = w; wc.height = bh; 2434 | wc.stack_mode = Above; wc.sibling = m->barwin; 2435 | XConfigureWindow(dpy, systray->win, CWX|CWY|CWWidth|CWHeight|CWSibling|CWStackMode, &wc); 2436 | XMapWindow(dpy, systray->win); 2437 | XMapSubwindows(dpy, systray->win); 2438 | /* redraw background */ 2439 | XSetForeground(dpy, drw->gc, scheme[SchemeNorm][ColBg].pixel); 2440 | XFillRectangle(dpy, systray->win, XCreateGC(dpy, root, 0 , NULL), 0, 0, w, bh); 2441 | XSync(dpy, False); 2442 | } 2443 | 2444 | void 2445 | updatetitle(Client *c) 2446 | { 2447 | if (!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name)) 2448 | gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name); 2449 | if (c->name[0] == '\0') /* hack to mark broken clients */ 2450 | strcpy(c->name, broken); 2451 | } 2452 | 2453 | void 2454 | updatewindowtype(Client *c) 2455 | { 2456 | Atom state = getatomprop(c, netatom[NetWMState]); 2457 | Atom wtype = getatomprop(c, netatom[NetWMWindowType]); 2458 | 2459 | if (state == netatom[NetWMFullscreen]) 2460 | setfullscreen(c, 1); 2461 | if (wtype == netatom[NetWMWindowTypeDialog]) 2462 | c->isfloating = 1; 2463 | } 2464 | 2465 | void 2466 | updatewmhints(Client *c) 2467 | { 2468 | XWMHints *wmh; 2469 | 2470 | if ((wmh = XGetWMHints(dpy, c->win))) { 2471 | if (c == selmon->sel && wmh->flags & XUrgencyHint) { 2472 | wmh->flags &= ~XUrgencyHint; 2473 | XSetWMHints(dpy, c->win, wmh); 2474 | } else 2475 | c->isurgent = (wmh->flags & XUrgencyHint) ? 1 : 0; 2476 | if (wmh->flags & InputHint) 2477 | c->neverfocus = !wmh->input; 2478 | else 2479 | c->neverfocus = 0; 2480 | XFree(wmh); 2481 | } 2482 | } 2483 | 2484 | void 2485 | view(const Arg *arg) 2486 | { 2487 | if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) 2488 | return; 2489 | selmon->seltags ^= 1; /* toggle sel tagset */ 2490 | if (arg->ui & TAGMASK) 2491 | selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; 2492 | focus(NULL); 2493 | arrange(selmon); 2494 | } 2495 | 2496 | Client * 2497 | wintoclient(Window w) 2498 | { 2499 | Client *c; 2500 | Monitor *m; 2501 | 2502 | for (m = mons; m; m = m->next) 2503 | for (c = m->clients; c; c = c->next) 2504 | if (c->win == w) 2505 | return c; 2506 | return NULL; 2507 | } 2508 | 2509 | Client * 2510 | wintosystrayicon(Window w) { 2511 | Client *i = NULL; 2512 | 2513 | if (!showsystray || !w) 2514 | return i; 2515 | for (i = systray->icons; i && i->win != w; i = i->next) ; 2516 | return i; 2517 | } 2518 | 2519 | Monitor * 2520 | wintomon(Window w) 2521 | { 2522 | int x, y; 2523 | Client *c; 2524 | Monitor *m; 2525 | 2526 | if (w == root && getrootptr(&x, &y)) 2527 | return recttomon(x, y, 1, 1); 2528 | for (m = mons; m; m = m->next) 2529 | if (w == m->barwin) 2530 | return m; 2531 | if ((c = wintoclient(w))) 2532 | return c->mon; 2533 | return selmon; 2534 | } 2535 | 2536 | /* There's no way to check accesses to destroyed windows, thus those cases are 2537 | * ignored (especially on UnmapNotify's). Other types of errors call Xlibs 2538 | * default error handler, which may call exit. */ 2539 | int 2540 | xerror(Display *dpy, XErrorEvent *ee) 2541 | { 2542 | if (ee->error_code == BadWindow 2543 | || (ee->request_code == X_SetInputFocus && ee->error_code == BadMatch) 2544 | || (ee->request_code == X_PolyText8 && ee->error_code == BadDrawable) 2545 | || (ee->request_code == X_PolyFillRectangle && ee->error_code == BadDrawable) 2546 | || (ee->request_code == X_PolySegment && ee->error_code == BadDrawable) 2547 | || (ee->request_code == X_ConfigureWindow && ee->error_code == BadMatch) 2548 | || (ee->request_code == X_GrabButton && ee->error_code == BadAccess) 2549 | || (ee->request_code == X_GrabKey && ee->error_code == BadAccess) 2550 | || (ee->request_code == X_CopyArea && ee->error_code == BadDrawable)) 2551 | return 0; 2552 | fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n", 2553 | ee->request_code, ee->error_code); 2554 | return xerrorxlib(dpy, ee); /* may call exit */ 2555 | } 2556 | 2557 | int 2558 | xerrordummy(Display *dpy, XErrorEvent *ee) 2559 | { 2560 | return 0; 2561 | } 2562 | 2563 | /* Startup Error handler to check if another window manager 2564 | * is already running. */ 2565 | int 2566 | xerrorstart(Display *dpy, XErrorEvent *ee) 2567 | { 2568 | die("dwm: another window manager is already running"); 2569 | return -1; 2570 | } 2571 | 2572 | Monitor * 2573 | systraytomon(Monitor *m) { 2574 | Monitor *t; 2575 | int i, n; 2576 | if(!systraypinning) { 2577 | if(!m) 2578 | return selmon; 2579 | return m == selmon ? m : NULL; 2580 | } 2581 | for(n = 1, t = mons; t && t->next; n++, t = t->next) ; 2582 | for(i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next) ; 2583 | if(systraypinningfailfirst && n < systraypinning) 2584 | return mons; 2585 | return t; 2586 | } 2587 | 2588 | void 2589 | xinitvisual() 2590 | { 2591 | XVisualInfo *infos; 2592 | XRenderPictFormat *fmt; 2593 | int nitems; 2594 | int i; 2595 | 2596 | XVisualInfo tpl = { 2597 | .screen = screen, 2598 | .depth = 32, 2599 | .class = TrueColor 2600 | }; 2601 | long masks = VisualScreenMask | VisualDepthMask | VisualClassMask; 2602 | 2603 | infos = XGetVisualInfo(dpy, masks, &tpl, &nitems); 2604 | visual = NULL; 2605 | for(i = 0; i < nitems; i ++) { 2606 | fmt = XRenderFindVisualFormat(dpy, infos[i].visual); 2607 | if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) { 2608 | visual = infos[i].visual; 2609 | depth = infos[i].depth; 2610 | cmap = XCreateColormap(dpy, root, visual, AllocNone); 2611 | useargb = 1; 2612 | break; 2613 | } 2614 | } 2615 | 2616 | XFree(infos); 2617 | 2618 | if (! visual) { 2619 | visual = DefaultVisual(dpy, screen); 2620 | depth = DefaultDepth(dpy, screen); 2621 | cmap = DefaultColormap(dpy, screen); 2622 | } 2623 | } 2624 | 2625 | void 2626 | zoom(const Arg *arg) 2627 | { 2628 | Client *c = selmon->sel; 2629 | 2630 | if (!selmon->lt[selmon->sellt]->arrange 2631 | || (selmon->sel && selmon->sel->isfloating)) 2632 | return; 2633 | if (c == nexttiled(selmon->clients)) 2634 | if (!c || !(c = nexttiled(c->next))) 2635 | return; 2636 | pop(c); 2637 | } 2638 | 2639 | int 2640 | main(int argc, char *argv[]) 2641 | { 2642 | if (argc == 2 && !strcmp("-v", argv[1])) 2643 | die("dwm-"VERSION); 2644 | else if (argc != 1) 2645 | die("usage: dwm [-v]"); 2646 | if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) 2647 | fputs("warning: no locale support\n", stderr); 2648 | if (!(dpy = XOpenDisplay(NULL))) 2649 | die("dwm: cannot open display"); 2650 | checkotherwm(); 2651 | setup(); 2652 | #ifdef __OpenBSD__ 2653 | if (pledge("stdio rpath proc exec", NULL) == -1) 2654 | die("pledge"); 2655 | #endif /* __OpenBSD__ */ 2656 | scan(); 2657 | runautostart(); 2658 | run(); 2659 | cleanup(); 2660 | XCloseDisplay(dpy); 2661 | return EXIT_SUCCESS; 2662 | } 2663 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/dwm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcolinux/arcolinux-dwm/6a16a89d2eee143c0e661611fa9b96a358b7addd/etc/skel/.config/arco-dwm/dwm.png -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/launcher/launcher.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## Author : Aditya Shakya 4 | ## Mail : adi1090x@gmail.com 5 | ## Github : @adi1090x 6 | ## Twitter : @adi1090x 7 | 8 | rofi -no-config -no-lazy-grab -show drun -modi drun -theme ~/.config/arco-dwm/launcher/rofi/launcher.rasi 9 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/launcher/rofi/colors.rasi: -------------------------------------------------------------------------------- 1 | /* colors */ 2 | 3 | * { 4 | al: #00000000; 5 | bg: #1F1F1FFF; 6 | sa: #1F1F1FFF; 7 | bga: #ffb30033; 8 | bar: #1F1F1FFF; 9 | fg: #FFFFFFFF; 10 | ac: #f15495ff; 11 | } 12 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/launcher/rofi/launcher.rasi: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Original Author : Aditya Shakya 4 | * Author : DN-debug 5 | * 6 | */ 7 | 8 | configuration { 9 | font: "Noto sans 12"; 10 | show-icons: true; 11 | icon-theme: ""; 12 | display-drun: ""; 13 | drun-display-format: "{name}"; 14 | disable-history: true; 15 | fullscreen: false; 16 | hide-scrollbar: true; 17 | sidebar-mode: false; 18 | } 19 | 20 | @import "colors.rasi" 21 | 22 | * { 23 | background-color: @al; 24 | text-color: #eeeeee; 25 | } 26 | 27 | 28 | window { 29 | transparency: "real"; 30 | background-color: #101010A9; 31 | text-color: #eeeeee; 32 | border: 0px; 33 | border-color: @ac; 34 | border-radius: 5px; 35 | height: 90%; 36 | width: 96%; 37 | location: northwest; 38 | x-offset: 2%; 39 | y-offset: 5%; 40 | } 41 | 42 | 43 | entry { 44 | background-color: #000000; 45 | text-color: white; 46 | expand: false; 47 | horizontal-align: 50%; 48 | placeholder: "Type to search"; 49 | margin: 0% 0% 0% 37%; 50 | padding: 1.5% 5.5%; 51 | blink: true; 52 | } 53 | 54 | inputbar { 55 | children: [ entry ]; 56 | background-color: #00000000; 57 | text-color: @bg; 58 | expand: false; 59 | border: 0% 0% 0% 0%; 60 | border-radius: 0px; 61 | border-color: @ac; 62 | margin: 0% 0% 0% 0%; 63 | padding: 1.5%; 64 | } 65 | 66 | listview { 67 | background-color: @al; 68 | padding: 0px; 69 | columns: 5; 70 | lines: 5; 71 | spacing: 0%; 72 | cycle: false; 73 | dynamic: true; 74 | layout: vertical; 75 | } 76 | 77 | mainbox { 78 | background-color: @al; 79 | border: 0% 0% 0% 0%; 80 | border-radius: 0% 0% 0% 0%; 81 | border-color: @al; 82 | children: [ inputbar, listview ]; 83 | spacing: 0%; 84 | padding: 0%; 85 | } 86 | 87 | element { 88 | background-color: @al; 89 | text-color: #eeeeee; 90 | orientation: horizontal; 91 | border-radius: 5%; 92 | padding: 2% 1% 2% 1%; 93 | } 94 | 95 | element-icon { 96 | size: 48px; 97 | border: 0px; 98 | } 99 | 100 | element-text { 101 | expand: true; 102 | horizontal-align: 0.5; 103 | vertical-align: 0.5; 104 | margin: 0.5% 0.5% -0.5% 0.5%; 105 | } 106 | 107 | element selected { 108 | background-color: @sa; 109 | text-color: #ffffff; 110 | border: 0% 0% 0% 0%; 111 | border-radius: 12px; 112 | border-color: @al; 113 | } 114 | 115 | element-text selected { 116 | text-color: @ac; 117 | } 118 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/layouts.c: -------------------------------------------------------------------------------- 1 | void 2 | grid(Monitor *m) { 3 | unsigned int i, n, cx, cy, cw, ch, aw, ah, cols, rows; 4 | Client *c; 5 | 6 | for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) 7 | n++; 8 | 9 | /* grid dimensions */ 10 | for(rows = 0; rows <= n/2; rows++) 11 | if(rows*rows >= n) 12 | break; 13 | cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows; 14 | 15 | /* window geoms (cell height/width) */ 16 | ch = m->wh / (rows ? rows : 1); 17 | cw = m->ww / (cols ? cols : 1); 18 | for(i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) { 19 | cx = m->wx + (i / rows) * cw; 20 | cy = m->wy + (i % rows) * ch; 21 | /* adjust height/width of last row/column's windows */ 22 | ah = ((i + 1) % rows == 0) ? m->wh - ch * rows : 0; 23 | aw = (i >= rows * (cols - 1)) ? m->ww - cw * cols : 0; 24 | resize(c, cx, cy, cw - 2 * c->bw + aw, ch - 2 * c->bw + ah, False); 25 | i++; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/list-of-patches.readme: -------------------------------------------------------------------------------- 1 | dwm-alphasystray 2 | dwm-autostart 3 | dwm-center 4 | dwm-r1615-selfstart 5 | dwm-cyclelayouts 6 | dwm-shiftview 7 | dwm-fullgaps 8 | dwm-gridmode (#include "layouts.c" above layouts to work, gaps does not work in this layout) 9 | dwm-viewontag 10 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/picom.conf: -------------------------------------------------------------------------------- 1 | shadow = true; 2 | shadow-radius = 7; 3 | shadow-offset-x = -7; 4 | shadow-offset-y = -7; 5 | shadow-exclude = [ 6 | "class_g = 'systray'", 7 | "class_g = 'dwm'", 8 | "class_g = 'dwmsystray'", 9 | "name = 'Notification'", 10 | "class_g ?= 'Notify-osd'", 11 | "name = 'Plank'", 12 | "name = 'Docky'", 13 | "name = 'Kupfer'", 14 | "name = 'xfce4-notifyd'", 15 | "name *= 'VLC'", 16 | "name *= 'Chromium'", 17 | "name *= 'Chrome'", 18 | "class_g = 'Firefox' && argb", 19 | "class_g = 'Conky'", 20 | "class_g = 'Synapse'", 21 | "class_g ?= 'Notify-osd'", 22 | "class_g ?= 'Xfce4-notifyd'", 23 | "class_g ?= 'Xfce4-power-manager'", 24 | ]; 25 | fading = true; 26 | fade-in-step = 0.03; 27 | fade-out-step = 0.03; 28 | inactive-opacity = 0.96; 29 | frame-opacity = 0.96; 30 | inactive-opacity-override = false; 31 | focus-exclude = [ 32 | "class_g = 'YouTube'", 33 | "class_g = 'VirtualBox Machine'", 34 | "class_g = 'Virt-manager'", 35 | "class_g = 'Skype'", 36 | ]; 37 | corner-radius = 0; 38 | rounded-corners-exclude = [ "window_type = 'dock'", "window_type = 'desktop'" ]; 39 | blur-kern = "3x3box"; 40 | blur-background-exclude = [ 41 | "class_g = 'systray'", 42 | "class_g = 'dwmsystray'", 43 | "window_type = 'dock'", 44 | "window_type = 'desktop'", 45 | ]; 46 | 47 | # Specify the backend to use: `xrender`, `glx`, or `xr_glx_hybrid`. 48 | # `xrender` is the default one. 49 | 50 | # backend = "glx" 51 | # backend = "xr_glx_hybrid" 52 | backend = "xrender"; 53 | # Enable/disable VSync. 54 | vsync = false; 55 | #vsync = true; 56 | 57 | mark-wmwin-focused = true; 58 | mark-ovredir-focused = true; 59 | detect-rounded-corners = true; 60 | detect-client-opacity = true; 61 | detect-transient = true; 62 | use-damage = true; 63 | log-level = "warn"; 64 | wintypes : 65 | { 66 | tooltip : 67 | { 68 | fade = true; 69 | shadow = true; 70 | opacity = 0.75; 71 | focus = true; 72 | full-shadow = false; 73 | }; 74 | dock : 75 | { 76 | shadow = false; 77 | clip-shadow-above = true; 78 | }; 79 | dnd : 80 | { 81 | shadow = false; 82 | }; 83 | popup_menu : 84 | { 85 | opacity = 0.8; 86 | }; 87 | dropdown_menu : 88 | { 89 | opacity = 0.8; 90 | }; 91 | }; 92 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/rebuild.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | make clean 4 | make 5 | sudo make install 6 | make clean 7 | 8 | echo 9 | tput setaf 2 10 | echo "################################################################" 11 | echo "Press super + shift + r to reload your new Dwm build" 12 | echo "################################################################" 13 | tput sgr0 14 | echo 15 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/scripts/picom-toggle.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if pgrep -x "picom" > /dev/null 3 | then 4 | killall picom 5 | else 6 | picom -b --config ~/.config/arco-dwm/picom.conf 7 | fi 8 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/selfrestart.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | /** 8 | * Magically finds the current's executable path 9 | * 10 | * I'm doing the do{}while(); trick because Linux (what I'm running) is not 11 | * POSIX compilant and so lstat() cannot be trusted on /proc entries 12 | * 13 | * @return char* the path of the current executable 14 | */ 15 | char *get_dwm_path(){ 16 | struct stat s; 17 | int r, length, rate = 42; 18 | char *path = NULL; 19 | 20 | if(lstat("/proc/self/exe", &s) == -1){ 21 | perror("lstat:"); 22 | return NULL; 23 | } 24 | 25 | length = s.st_size + 1 - rate; 26 | 27 | do{ 28 | length+=rate; 29 | 30 | free(path); 31 | path = malloc(sizeof(char) * length); 32 | 33 | if(path == NULL){ 34 | perror("malloc:"); 35 | return NULL; 36 | } 37 | 38 | r = readlink("/proc/self/exe", path, length); 39 | 40 | if(r == -1){ 41 | perror("readlink:"); 42 | return NULL; 43 | } 44 | }while(r >= length); 45 | 46 | path[r] = '\0'; 47 | 48 | return path; 49 | } 50 | 51 | /** 52 | * self-restart 53 | * 54 | * Initially inspired by: Yu-Jie Lin 55 | * https://sites.google.com/site/yjlnotes/notes/dwm 56 | */ 57 | void self_restart(const Arg *arg) { 58 | char *const argv[] = {get_dwm_path(), NULL}; 59 | 60 | if(argv[0] == NULL){ 61 | return; 62 | } 63 | 64 | execv(argv[0], argv); 65 | } 66 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/shiftview.c: -------------------------------------------------------------------------------- 1 | /** Function to shift the current view to the left/right 2 | * 3 | * @param: "arg->i" stores the number of tags to shift right (positive value) 4 | * or left (negative value) 5 | */ 6 | void 7 | shiftview(const Arg *arg) { 8 | Arg shifted; 9 | 10 | if(arg->i > 0) // left circular shift 11 | shifted.ui = (selmon->tagset[selmon->seltags] << arg->i) 12 | | (selmon->tagset[selmon->seltags] >> (LENGTH(tags) - arg->i)); 13 | 14 | else // right circular shift 15 | shifted.ui = selmon->tagset[selmon->seltags] >> (- arg->i) 16 | | selmon->tagset[selmon->seltags] << (LENGTH(tags) + arg->i); 17 | 18 | view(&shifted); 19 | } 20 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/sxhkd/sxhkdrc: -------------------------------------------------------------------------------- 1 | ################################################################# 2 | # KEYBOARD BINDINGS FOR ANY TWM 3 | ################################################################# 4 | 5 | ################################################################# 6 | # SUPER + FUNCTION KEYS 7 | ################################################################# 8 | 9 | # Vivaldi 10 | super + F1 11 | vivaldi-stable 12 | 13 | # Code 14 | super + F2 15 | code 16 | 17 | #Inkscape 18 | super + F3 19 | inkscape 20 | 21 | #Gimp 22 | super + F4 23 | gimp 24 | 25 | #Meld 26 | super + F5 27 | meld 28 | 29 | #Vlc 30 | super + F6 31 | vlc --video-on-top 32 | 33 | #Virtualbox 34 | super + F7 35 | virtualbox 36 | 37 | #Thunar 38 | super + F8 39 | thunar 40 | 41 | #Audio player 42 | super + F9 43 | lollypop 44 | 45 | #Spotify 46 | super + F10 47 | spotify 48 | 49 | #Rofi Fullscreen 50 | super + F11 51 | rofi -theme-str 'window \{width: 100%;height: 100%;\}' -show drun 52 | 53 | #Rofi 54 | super + F12 55 | rofi -show drun 56 | 57 | ################################################################# 58 | # SUPER + ... KEYS 59 | ################################################################# 60 | 61 | #Code 62 | super + e 63 | code 64 | 65 | #Browser 66 | super + w 67 | vivaldi-stable 68 | 69 | #Conky-toggle 70 | super + c 71 | conky-toggle 72 | 73 | #Htop 74 | #super + h 75 | # urxvt 'htop task manager' -e htop 76 | 77 | #archlinux-logout 78 | super + x 79 | archlinux-logout 80 | 81 | #nlogout 82 | alt + shift + x 83 | nlogout 84 | 85 | #nlogout 86 | alt + x 87 | nlogout 88 | 89 | #powermenu 90 | super + shift + x 91 | arcolinux-powermenu 92 | 93 | #Rofi theme selector 94 | super + r 95 | rofi-theme-selector 96 | 97 | #Urxvt 98 | #super + t 99 | # urxvt 100 | 101 | #Pavucontrol 102 | super + v 103 | pavucontrol 104 | 105 | #Pragha 106 | #super + m 107 | # pragha 108 | 109 | #alacritty 110 | super + Return 111 | alacritty 112 | 113 | #Xkill 114 | super + Escape 115 | xkill 116 | 117 | #Keyboard dependent 118 | #alacritty 119 | super + KP_Enter 120 | alacritty 121 | 122 | ################################################################# 123 | # SUPER + SHIFT KEYS 124 | ################################################################# 125 | 126 | #File-Manager 127 | super + shift + Return 128 | thunar 129 | 130 | #Keyboard dependent 131 | #File-Manager 132 | super + shift + KP_Enter 133 | thunar 134 | 135 | #dmenu 136 | super + shift + d 137 | dmenu_run -i -nb '#191919' -nf '#fea63c' -sb '#fea63c' -sf '#191919' -fn 'NotoMonoRegular:bold:pixelsize=14' 138 | 139 | #rofi 140 | super + d 141 | ~/.config/arco-dwm/launcher/launcher.sh 142 | 143 | #reload sxhkd: 144 | super + shift + s 145 | pkill -USR1 -x sxhkd 146 | 147 | 148 | ################################################################# 149 | # CONTROL + ALT KEYS 150 | ################################################################# 151 | 152 | #arcolinux-welcome-app 153 | ctrl + alt + w 154 | arcolinux-welcome-app 155 | 156 | #archlinux-tweak-tool 157 | ctrl + alt + e 158 | archlinux-tweak-tool 159 | 160 | #conky-rotate 161 | ctrl + alt + Next 162 | conky-rotate -n 163 | 164 | #conky-rotate 165 | ctrl + alt + Prior 166 | conky-rotate -p 167 | 168 | #File-Manager 169 | ctrl + alt + b 170 | thunar 171 | 172 | #Catfish 173 | ctrl + alt + c 174 | catfish 175 | 176 | #Chromium 177 | ctrl + alt + g 178 | chromium -no-default-browser-check 179 | 180 | #Firefox 181 | ctrl + alt + f 182 | firefox 183 | 184 | #Nitrogen 185 | ctrl + alt + i 186 | nitrogen 187 | 188 | #archlinux-logout 189 | ctrl + alt + k 190 | archlinux-logout 191 | 192 | #archlinux-logout 193 | ctrl + alt + l 194 | archlinux-logout 195 | 196 | #Pamac-manager 197 | ctrl + alt + p 198 | pamac-manager 199 | 200 | #Xfce4-settings-manager 201 | ctrl + alt + m 202 | xfce4-settings-manager 203 | 204 | #Pulse Audio Control 205 | ctrl + alt + u 206 | pavucontrol 207 | 208 | #Rofi theme selector 209 | ctrl + alt + r 210 | rofi-theme-selector 211 | 212 | #Spotify 213 | ctrl + alt + s 214 | spotify 215 | 216 | #st 217 | ctrl + alt + Return 218 | st 219 | 220 | #alacritty 221 | ctrl + alt + t 222 | alacritty 223 | 224 | #Vivaldi 225 | ctrl + alt + v 226 | vivaldi-stable 227 | 228 | #Xfce4-appfinder 229 | ctrl + alt + a 230 | xfce4-appfinder 231 | 232 | 233 | #Keyboard dependent 234 | #alacritty 235 | #ctrl + alt + KP_Enter 236 | # alacritty 237 | 238 | 239 | ################################################################# 240 | # ALT + ... KEYS 241 | ################################################################# 242 | 243 | #Wallpaper trash 244 | alt + t 245 | variety -t 246 | 247 | #Wallpaper next 248 | alt + n 249 | variety -n 250 | 251 | #Wallpaper previous 252 | alt + p 253 | variety -p 254 | 255 | #Wallpaper favorite 256 | alt + f 257 | variety -f 258 | 259 | #Wallpaper previous 260 | alt + Left 261 | variety -p 262 | 263 | #Wallpaper next 264 | alt + Right 265 | variety -n 266 | 267 | #Wallpaper toggle-pause 268 | alt + Up 269 | variety --toggle-pause 270 | 271 | #Wallpaper resume 272 | alt + Down 273 | variety --resume 274 | 275 | #Xfce4-appfinder 276 | alt + F2 277 | xfce4-appfinder --collapsed 278 | 279 | #Xfce4-appfinder 280 | alt + F3 281 | xfce4-appfinder 282 | 283 | 284 | ################################################################# 285 | #VARIETY KEYS WITH PYWAL 286 | ################################################################# 287 | 288 | #Wallpaper trash 289 | alt + shift + t 290 | variety -t && wal -i $(cat $HOME/.config/variety/wallpaper/wallpaper.jpg.txt)& 291 | 292 | #Wallpaper next 293 | alt + shift + n 294 | variety -n && wal -i $(cat $HOME/.config/variety/wallpaper/wallpaper.jpg.txt)& 295 | 296 | #Wallpaper previous 297 | alt + shift + p 298 | variety -p && wal -i $(cat $HOME/.config/variety/wallpaper/wallpaper.jpg.txt)& 299 | 300 | #Wallpaper favorite 301 | alt + shift + f 302 | variety -f && wal -i $(cat $HOME/.config/variety/wallpaper/wallpaper.jpg.txt)& 303 | 304 | #Wallpaper update 305 | alt + shift + u 306 | wal -i $(cat $HOME/.config/variety/wallpaper/wallpaper.jpg.txt)& 307 | 308 | ################################################################# 309 | # CONTROL + SHIFT KEYS 310 | ################################################################# 311 | 312 | #Xcfe4-TaskManager 313 | ctrl + shift + Escape 314 | xfce4-taskmanager 315 | 316 | 317 | ################################################################# 318 | # SCREENSHOTS 319 | ################################################################# 320 | 321 | #Scrot 322 | Print 323 | scrot 'ArcoLinux-%Y-%m-%d-%s_screenshot_$wx$h.jpg' -e 'mv $f $$(xdg-user-dir PICTURES)' 324 | 325 | #screeenshooter 326 | ctrl + Print 327 | xfce4-screenshooter 328 | 329 | #Gnome-Screenshot 330 | ctrl + shift + Print 331 | gnome-screenshot -i 332 | 333 | #flameshot 334 | ctrl + super + Print 335 | flameshot gui 336 | 337 | ################################################################# 338 | # FUNCTION KEYS 339 | ################################################################# 340 | 341 | #xfce4-terminal dropdown 342 | F12 343 | xfce4-terminal --drop-down 344 | 345 | 346 | ################################################################# 347 | # MULTIMEDIA KEYS 348 | ################################################################# 349 | 350 | #Raises volume 351 | XF86AudioRaiseVolume 352 | amixer -D pulse set Master 10%+ 353 | 354 | #Lowers volume 355 | XF86AudioLowerVolume 356 | amixer -D pulse set Master 10%- 357 | 358 | #Mute 359 | XF86AudioMute 360 | amixer -D pulse set Master 1+ toggle 361 | 362 | #Playerctl works for Pragha, Spotify and others 363 | #Delete the line for playerctl if you want to use mpc 364 | #and replace it with the corresponding code 365 | #mpc works for e.g.ncmpcpp 366 | #mpc toggle 367 | #mpc next 368 | #mpc prev 369 | #mpc stop 370 | 371 | #PLAY 372 | XF86AudioPlay 373 | playerctl play-pause 374 | 375 | #Next 376 | XF86AudioNext 377 | playerctl next 378 | 379 | #previous 380 | XF86AudioPrev 381 | playerctl previous 382 | 383 | #Stop 384 | XF86AudioStop 385 | playerctl stop 386 | 387 | #Brightness up 388 | XF86MonBrightnessUp 389 | xbacklight -inc 10 390 | 391 | #Brightness down 392 | XF86MonBrightnessDown 393 | xbacklight -dec 10 394 | 395 | 396 | ################################################################# 397 | ################################################################# 398 | ################## DESKTOP SPECIFIC ######################## 399 | ################################################################# 400 | ################################################################# 401 | 402 | ################################################################# 403 | # CTRL + ALT KEYS 404 | ################################################################# 405 | 406 | #Picom Toggle 407 | ctrl + alt + o 408 | ~/.config/arco-dwm/scripts/picom-toggle.sh 409 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/system-overview: -------------------------------------------------------------------------------- 1 | --[[ 2 | #===================================================================================== 3 | # ArcoLinuxD 4 | # 5 | # Author : Erik Dubois at http://www.erikdubois.be 6 | # License : Distributed under the terms of GNU GPL version 2 or later 7 | # Documentation : http://erikdubois.be/category/linux/aureola/ 8 | #====================================================================================== 9 | 10 | 11 | ]] 12 | 13 | conky.config = { 14 | 15 | --Various settings 16 | 17 | background = true, -- forked to background 18 | cpu_avg_samples = 2, -- The number of samples to average for CPU monitoring. 19 | diskio_avg_samples = 10, -- The number of samples to average for disk I/O monitoring. 20 | double_buffer = true, -- Use the Xdbe extension? (eliminates flicker) 21 | if_up_strictness = 'address', -- how strict if testing interface is up - up, link or address 22 | net_avg_samples = 2, -- The number of samples to average for net data 23 | no_buffers = true, -- Subtract (file system) buffers from used memory? 24 | temperature_unit = 'celsius', -- fahrenheit or celsius 25 | text_buffer_size = 2048, -- size of buffer for display of content of large variables - default 256 26 | update_interval = 1, -- update interval 27 | imlib_cache_size = 0, -- disable image cache to get a new spotify cover per song 28 | 29 | 30 | --Placement 31 | 32 | alignment = 'middle_right', -- top-left,top-middle,top-right,bottom-left,bottom-middle,bottom-right, 33 | -- middle-left,middle-middle,middle-right,none 34 | --Arch Duoscreen 35 | --gap_x = -1910, 36 | gap_x = 10, -- pixels between right or left border 37 | gap_y = 10, -- pixels between bottom or left border 38 | minimum_height = 200, -- minimum height of window 39 | minimum_width = 280, -- minimum height of window 40 | maximum_width = 280, -- maximum height of window 41 | 42 | --Graphical 43 | 44 | border_inner_margin = 5, -- margin between border and text 45 | border_outer_margin = 5, -- margin between border and edge of window 46 | border_width = 0, -- border width in pixels 47 | default_bar_width = 280, -- default is 0 - full width 48 | default_bar_height = 10, -- default is 6 49 | default_gauge_height = 25, -- default is 25 50 | default_gauge_width =40, -- default is 40 51 | default_graph_height = 40, -- default is 25 52 | default_graph_width = 153, -- default is 0 - full width 53 | default_shade_color = '#000000', -- default shading colour 54 | default_outline_color = '#000000', -- default outline colour 55 | draw_borders = false, -- draw borders around text 56 | draw_graph_borders = true, -- draw borders around graphs 57 | draw_shades = false, -- draw shades 58 | draw_outline = false, -- draw outline 59 | stippled_borders = 0, -- dashing the border 60 | 61 | --Textual 62 | 63 | extra_newline = false, -- extra newline at the end - for asesome's wiboxes 64 | format_human_readable = true, -- KiB, MiB rather then number of bytes 65 | font = 'Noto Mono:size=11:regular', -- font for complete conky unless in code defined 66 | max_text_width = 0, -- 0 will make sure line does not get broken if width too smal 67 | max_user_text = 16384, -- max text in conky default 16384 68 | override_utf8_locale = true, -- force UTF8 requires xft 69 | short_units = true, -- shorten units from KiB to k 70 | top_name_width = 21, -- width for $top name value default 15 71 | top_name_verbose = false, -- If true, top name shows the full command line of each process - Default value is false. 72 | uppercase = false, -- uppercase or not 73 | use_spacer = 'none', -- adds spaces around certain objects to align - default none 74 | use_xft = true, -- xft font - anti-aliased font 75 | xftalpha = 1, -- alpha of the xft font - between 0-1 76 | 77 | --Windows 78 | 79 | own_window = true, -- create your own window to draw 80 | own_window_argb_value = 150, -- real transparency - composite manager required 0-255 81 | own_window_argb_visual = true, -- use ARGB - composite manager required 82 | own_window_class = 'Conky', -- manually set the WM_CLASS name for use with xprop 83 | own_window_colour = '#000000', -- set colour if own_window_transparent no 84 | own_window_hints = 'undecorated,below,above,sticky,skip_taskbar,skip_pager', -- if own_window true - just hints - own_window_type sets it 85 | own_window_transparent = false, -- if own_window_argb_visual is true sets background opacity 0% 86 | own_window_title = 'system_conky', -- set the name manually - default conky "hostname" 87 | own_window_type = 'override', -- if own_window true options are: normal/override/dock/desktop/panel 88 | 89 | 90 | --Colours 91 | 92 | default_color = '#ff0000', -- default color and border color 93 | color1 = '#FFFFFF', 94 | color2 = '#7aa2e2', 95 | color3 = '#cccccc', 96 | color4 = '#BDBDBD', 97 | color5 = '#CCCCCC', 98 | color6 = '#aa0000', 99 | 100 | --Signal Colours 101 | color7 = '#1F7411', --green 102 | color8 = '#FFA726', --orange 103 | color9 = '#F1544B', --firebrick 104 | 105 | 106 | --Lua 107 | 108 | 109 | }; 110 | conky.text = [[ 111 | ${color1}${alignc}S Y S T E M I N F O${color} 112 | ${color1}${hr}${color} 113 | ${color1}Host:${alignr}${color2}${nodename}${color} 114 | #${color1}Kernel:${color2}${alignr}$kernel${color} 115 | #${color1}Uptime:${color2}${alignr}${uptime}${color} 116 | #${color1}UTC:${color2}${alignr}${utime %H:%M}${color} 117 | 118 | ${color1}${goto 60}Used${alignr}Size${color} 119 | ${color1}Root${goto 60}${color2}${fs_used /}${alignr}${fs_size /}${color} 120 | #${color1}Home${goto 60}${color2}${fs_used /home}${alignr}${fs_size /home}${color} 121 | 122 | ${color1}${goto 60}Mem${alignr}Max${color} 123 | ${color1}RAM${goto 60}${color2}${mem}${alignr}${memmax}${color} 124 | ${color1}Swap${goto 60}${color2}${swap}${alignr}${swapmax}${color} 125 | 126 | ${color1}CPU:${goto 60}Used${alignr}GHz${color} 127 | ${color1}Avg${goto 60}${color2}${if_match ${cpu cpu0}<50} ${cpu cpu0}\ 128 | ${else}${if_match ${cpu cpu0}<=100}${color9} ${cpu cpu0}\ 129 | ${else}${cpu cpu0}${endif}${endif}%${alignr}${freq_g}${color} 130 | 131 | ${color1}${alignc}S H O R T C U T K E Y S${color} 132 | ${color1}${hr}${color} 133 | ${color1}[S]+[Shift]+D${alignr}${color2}Main Menu${color} 134 | ${color1}[Alt]+F2${alignr}${color2}Alt Menu${color} 135 | ${color1}[Alt]+F3${alignr}${color2}Alt Menu${color} 136 | ${color1}${hr}${color} 137 | ${color1}[S]+[Shift]+Enter${alignr}${color2}File Manager${color} 138 | ${color1}[Ctrl]+[Alt]+V${alignr}${color2}Vivaldi${color} 139 | ${color1}[S]+F2${alignr}${color2}Editor${color} 140 | ${color1}[S]+F6${alignr}${color2}Media Player${color} 141 | ${color1}[S]+[Space]${alignr}${color2}Change Layout${color} 142 | ${color1}[Ctrl]+[Shift]+Esc${alignr}${color2}Task Manager${color} 143 | ${color1}[Ctrl]+[Alt]+U${alignr}${color2}Volume Control${color} 144 | ${color1}[PrtSc]${alignr}${color2}Screenshot${color} 145 | ${color1}[S]+[Shift]+R${alignr}${color2}Restart${color} 146 | ${color1}${hr}${color} 147 | ${color1}[S]+[Shift]+Q${alignr}${color2}Stop application${color} 148 | ${color1}[S]+x${alignr}${color2}Exit${color} 149 | ${color1}${hr}${color} 150 | ${color1}${execi 6000 lsb_release -d | grep 'Descr'|awk {'print $2 " " $3" " $4" " $5'}}${alignr}${execi 6000 lsb_release -a | grep 'Release'|awk {'print $2""$3""$4""$5'}}${color} 151 | ]]; 152 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/transient.c: -------------------------------------------------------------------------------- 1 | /* cc transient.c -o transient -lX11 */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int main(void) { 9 | Display *d; 10 | Window r, f, t = None; 11 | XSizeHints h; 12 | XEvent e; 13 | 14 | d = XOpenDisplay(NULL); 15 | if (!d) 16 | exit(1); 17 | r = DefaultRootWindow(d); 18 | 19 | f = XCreateSimpleWindow(d, r, 100, 100, 400, 400, 0, 0, 0); 20 | h.min_width = h.max_width = h.min_height = h.max_height = 400; 21 | h.flags = PMinSize | PMaxSize; 22 | XSetWMNormalHints(d, f, &h); 23 | XStoreName(d, f, "floating"); 24 | XMapWindow(d, f); 25 | 26 | XSelectInput(d, f, ExposureMask); 27 | while (1) { 28 | XNextEvent(d, &e); 29 | 30 | if (t == None) { 31 | sleep(5); 32 | t = XCreateSimpleWindow(d, r, 50, 50, 100, 100, 0, 0, 0); 33 | XSetTransientForHint(d, t, f); 34 | XStoreName(d, t, "transient"); 35 | XMapWindow(d, t); 36 | XSelectInput(d, t, ExposureMask); 37 | } 38 | } 39 | 40 | XCloseDisplay(d); 41 | exit(0); 42 | } 43 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/util.c: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "util.h" 8 | 9 | void * 10 | ecalloc(size_t nmemb, size_t size) 11 | { 12 | void *p; 13 | 14 | if (!(p = calloc(nmemb, size))) 15 | die("calloc:"); 16 | return p; 17 | } 18 | 19 | void 20 | die(const char *fmt, ...) { 21 | va_list ap; 22 | 23 | va_start(ap, fmt); 24 | vfprintf(stderr, fmt, ap); 25 | va_end(ap); 26 | 27 | if (fmt[0] && fmt[strlen(fmt)-1] == ':') { 28 | fputc(' ', stderr); 29 | perror(NULL); 30 | } else { 31 | fputc('\n', stderr); 32 | } 33 | 34 | exit(1); 35 | } 36 | -------------------------------------------------------------------------------- /etc/skel/.config/arco-dwm/util.h: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | 3 | #define MAX(A, B) ((A) > (B) ? (A) : (B)) 4 | #define MIN(A, B) ((A) < (B) ? (A) : (B)) 5 | #define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B)) 6 | 7 | void die(const char *fmt, ...); 8 | void *ecalloc(size_t nmemb, size_t size); 9 | -------------------------------------------------------------------------------- /make-package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #set -e 3 | ################################################################################################################## 4 | # Author : Erik Dubois 5 | # Website : https://www.erikdubois.be 6 | # Website : https://www.arcolinux.info 7 | # Website : https://www.arcolinux.com 8 | # Website : https://www.arcolinuxd.com 9 | # Website : https://www.arcolinuxforum.com 10 | ################################################################################################################## 11 | # 12 | # DO NOT JUST RUN THIS. EXAMINE AND JUDGE. RUN AT YOUR OWN RISK. 13 | # 14 | ################################################################################################################## 15 | 16 | 17 | cd ./etc/skel/.config/arco-dwm/ 18 | make 19 | make clean 20 | -------------------------------------------------------------------------------- /setup-our-git-credentials.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #set -e 3 | ################################################################################################################## 4 | # Author : Erik Dubois 5 | # Website : https://www.erikdubois.be 6 | # Website : https://www.alci.online 7 | # Website : https://www.arcolinux.info 8 | # Website : https://www.arcolinux.com 9 | # Website : https://www.arcolinuxd.com 10 | # Website : https://www.arcolinuxb.com 11 | # Website : https://www.arcolinuxiso.com 12 | # Website : https://www.arcolinuxforum.com 13 | ################################################################################################################## 14 | # 15 | # DO NOT JUST RUN THIS. EXAMINE AND JUDGE. RUN AT YOUR OWN RISK. 16 | # 17 | ################################################################################################################## 18 | #tput setaf 0 = black 19 | #tput setaf 1 = red 20 | #tput setaf 2 = green 21 | #tput setaf 3 = yellow 22 | #tput setaf 4 = dark blue 23 | #tput setaf 5 = purple 24 | #tput setaf 6 = cyan 25 | #tput setaf 7 = gray 26 | #tput setaf 8 = light blue 27 | ################################################################################################################## 28 | 29 | echo 30 | tput setaf 3 31 | echo "################################################################" 32 | echo "################### Start" 33 | echo "################################################################" 34 | tput sgr0 35 | echo 36 | 37 | # Problem solving commands 38 | 39 | # Read before using it. 40 | # https://www.atlassian.com/git/tutorials/undoing-changes/git-reset 41 | # git reset --hard orgin/master 42 | # ONLY if you are very sure and no coworkers are on your github. 43 | 44 | # Command that have helped in the past 45 | # Force git to overwrite local files on pull - no merge 46 | # git fetch all 47 | # git push --set-upstream origin master 48 | # git reset --hard orgin/master 49 | 50 | 51 | #setting up git 52 | #https://www.atlassian.com/git/tutorials/setting-up-a-repository/git-config 53 | #https://medium.com/clarusway/how-to-use-git-github-without-asking-for-authentication-always-passwordless-usage-of-private-git-8c32489bc2e9 54 | #https://blog.nillsf.com/index.php/2021/05/27/github-sso-using-password-protected-ssh-keys 55 | 56 | project=$(basename `pwd`) 57 | githubdir=$(basename $(dirname "$PWD")) 58 | githubdir="arcolinux" 59 | echo "-----------------------------------------------------------------------------" 60 | echo "this is project https://github.com/$githubdir/$project" 61 | echo "-----------------------------------------------------------------------------" 62 | 63 | git config --global pull.rebase false 64 | git config --global push.default simple 65 | git config --global user.name "arcolinuxz" 66 | git config --global user.email "arcolinuxinfo@gmail.com" 67 | sudo git config --system core.editor nano 68 | git remote set-url origin git@github.com-arc:$githubdir/$project 69 | 70 | echo 71 | tput setaf 3 72 | echo "################################################################" 73 | echo "################### End" 74 | echo "################################################################" 75 | tput sgr0 76 | echo -------------------------------------------------------------------------------- /up.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #set -e 3 | ################################################################################################################## 4 | # Author : Erik Dubois 5 | # Website : https://www.erikdubois.be 6 | # Website : https://www.alci.online 7 | # Website : https://www.ariser.eu 8 | # Website : https://www.arcolinux.info 9 | # Website : https://www.arcolinux.com 10 | # Website : https://www.arcolinuxd.com 11 | # Website : https://www.arcolinuxb.com 12 | # Website : https://www.arcolinuxiso.com 13 | # Website : https://www.arcolinuxforum.com 14 | ################################################################################################################## 15 | # 16 | # DO NOT JUST RUN THIS. EXAMINE AND JUDGE. RUN AT YOUR OWN RISK. 17 | # 18 | ################################################################################################################## 19 | #tput setaf 0 = black 20 | #tput setaf 1 = red 21 | #tput setaf 2 = green 22 | #tput setaf 3 = yellow 23 | #tput setaf 4 = dark blue 24 | #tput setaf 5 = purple 25 | #tput setaf 6 = cyan 26 | #tput setaf 7 = gray 27 | #tput setaf 8 = light blue 28 | ################################################################################################################## 29 | 30 | # reset - commit your changes or stash them before you merge 31 | # git reset --hard - personal alias - grh 32 | 33 | # checking if I have the latest files from github 34 | echo "Checking for newer files online first" 35 | git pull 36 | 37 | echo "getting picom.conf" 38 | installed_dir=$(dirname $(readlink -f $(basename `pwd`))) 39 | found_file=$(find "$installed_dir" -type f -name "picom.conf" | head -n 1) 40 | wget -v https://raw.githubusercontent.com/arconetpro/picom/refs/heads/main/picom.conf -O $found_file 41 | 42 | echo "Copy config.h" 43 | rm etc/skel/.config/arco-dwm/config.h 44 | ./make-package.sh 45 | # Below command will backup everything inside the project folder 46 | git add --all . 47 | 48 | # Give a comment to the commit if you want 49 | echo "####################################" 50 | echo "Write your commit comment!" 51 | echo "####################################" 52 | 53 | read input 54 | 55 | # Committing to the local repository with a message containing the time details and commit text 56 | 57 | git commit -m "$input" 58 | 59 | # Push the local files to github 60 | 61 | if grep -q main .git/config; then 62 | echo "Using main" 63 | git push -u origin main 64 | fi 65 | 66 | if grep -q master .git/config; then 67 | echo "Using master" 68 | git push -u origin master 69 | fi 70 | 71 | echo "################################################################" 72 | echo "################### Git Push Done ######################" 73 | echo "################################################################" 74 | -------------------------------------------------------------------------------- /usr/share/doc/dwm/README: -------------------------------------------------------------------------------- 1 | dwm - dynamic window manager 2 | ============================ 3 | dwm is an extremely fast, small, and dynamic window manager for X. 4 | 5 | 6 | Requirements 7 | ------------ 8 | In order to build dwm you need the Xlib header files. 9 | 10 | 11 | Installation 12 | ------------ 13 | Edit config.mk to match your local setup (dwm is installed into 14 | the /usr/local namespace by default). 15 | 16 | Afterwards enter the following command to build and install dwm (if 17 | necessary as root): 18 | 19 | make clean install 20 | 21 | 22 | Running dwm 23 | ----------- 24 | Add the following line to your .xinitrc to start dwm using startx: 25 | 26 | exec dwm 27 | 28 | In order to connect dwm to a specific display, make sure that 29 | the DISPLAY environment variable is set correctly, e.g.: 30 | 31 | DISPLAY=foo.bar:1 exec dwm 32 | 33 | (This will start dwm on display :1 of the host foo.bar.) 34 | 35 | In order to display status info in the bar, you can do something 36 | like this in your .xinitrc: 37 | 38 | while xsetroot -name "`date` `uptime | sed 's/.*,//'`" 39 | do 40 | sleep 1 41 | done & 42 | exec dwm 43 | 44 | 45 | Configuration 46 | ------------- 47 | The configuration of dwm is done by creating a custom config.h 48 | and (re)compiling the source code. 49 | -------------------------------------------------------------------------------- /usr/share/licenses/dwm/LICENSE: -------------------------------------------------------------------------------- 1 | MIT/X Consortium License 2 | 3 | © 2006-2019 Anselm R Garbe 4 | © 2006-2009 Jukka Salmi 5 | © 2006-2007 Sander van Dijk 6 | © 2007-2011 Peter Hartlich 7 | © 2007-2009 Szabolcs Nagy 8 | © 2007-2009 Christof Musik 9 | © 2007-2009 Premysl Hruby 10 | © 2007-2008 Enno Gottox Boland 11 | © 2008 Martin Hurton 12 | © 2008 Neale Pickett 13 | © 2009 Mate Nagy 14 | © 2010-2016 Hiltjo Posthuma 15 | © 2010-2012 Connor Lane Smith 16 | © 2011 Christoph Lohmann <20h@r-36.net> 17 | © 2015-2016 Quentin Rameau 18 | © 2015-2016 Eric Pruitt 19 | © 2016-2017 Markus Teich 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a 22 | copy of this software and associated documentation files (the "Software"), 23 | to deal in the Software without restriction, including without limitation 24 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 25 | and/or sell copies of the Software, and to permit persons to whom the 26 | Software is furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in 29 | all copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 34 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 36 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 37 | DEALINGS IN THE SOFTWARE. 38 | -------------------------------------------------------------------------------- /usr/share/man/man1/dwm.1.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcolinux/arcolinux-dwm/6a16a89d2eee143c0e661611fa9b96a358b7addd/usr/share/man/man1/dwm.1.gz -------------------------------------------------------------------------------- /usr/share/xsessions/dwm.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Encoding=UTF-8 3 | Name=Dwm 4 | Comment=Dynamic window manager 5 | Exec=dwm 6 | Icon=dwm 7 | Type=XSession 8 | --------------------------------------------------------------------------------