├── 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 |
--------------------------------------------------------------------------------