generated

This commit is contained in:
Daniel Demus
2026-04-30 00:57:24 +02:00
parent 04cfa4c8a5
commit b74c725eaf
3810 changed files with 4216050 additions and 1 deletions
+1 -1
View File
@@ -5,7 +5,7 @@
## EXTENSION DESCRIPTION: ## EXTENSION DESCRIPTION:
- Features: - Features:
- The extension is called 'BLE Unlock' and is owned by daniel@demus.dk. - The extension is called 'BLE Unlock' and is owned by daniel@demus.dk. The project is configured for developing in javascript.
- The extension monitors the signal strength of a bluetooth device in the proximity of the computer and calls functions when the signal strength goes below or above configured thresholds, respectively. The functions send a dbus message to then org.gnome.ScreenSaver method SetActive with boolean `true` when the RSSI falls over the threshold and boolean `false` when it goes over with a configurable delay, which is 3 seconds by default. Debug log the transitions. - The extension monitors the signal strength of a bluetooth device in the proximity of the computer and calls functions when the signal strength goes below or above configured thresholds, respectively. The functions send a dbus message to then org.gnome.ScreenSaver method SetActive with boolean `true` when the RSSI falls over the threshold and boolean `false` when it goes over with a configurable delay, which is 3 seconds by default. Debug log the transitions.
- Include a quick settings item allowing to enable/disable the monitoring functionality and showing some status information including the selected device and current signal strength. - Include a quick settings item allowing to enable/disable the monitoring functionality and showing some status information including the selected device and current signal strength.
- The dB thresholds and device to monitor are configurable. The item must have a submenu allowing setting the thresholds and selecting which device to monitor, so the quick settings item it should list nearby devices and allow selecting one of them, similarly to the the gnome Bluetooth Settings dialog. - The dB thresholds and device to monitor are configurable. The item must have a submenu allowing setting the thresholds and selecting which device to monitor, so the quick settings item it should list nearby devices and allow selecting one of them, similarly to the the gnome Bluetooth Settings dialog.
+232
View File
@@ -0,0 +1,232 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright © 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for software and other kinds of works.
The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.
When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.
Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and modification follow.
TERMS AND CONDITIONS
0. Definitions.
“This License” refers to version 3 of the GNU General Public License.
“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.
“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations.
To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work.
A “covered work” means either the unmodified Program or a work based on the Program.
To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.
To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.
1. Source Code.
The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work.
A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.
The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.
The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.
The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.
The Corresponding Source for a work in source code form is that same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.
When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified it, and giving a relevant date.
b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”.
c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.
A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:
a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.
d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.
A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.
A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.
“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.
If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).
The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.
7. Additional Terms.
“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or authors of the material; or
e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.
All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).
However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.
Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.
An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.
11. Patents.
A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”.
A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.
In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.
If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.
A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.
If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.
Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.
blelock
Copyright (C) 2026 demus
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:
blelock Copyright (C) 2026 demus
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”.
You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see <https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read <https://www.gnu.org/philosophy/why-not-lgpl.html>.
+32
View File
@@ -0,0 +1,32 @@
NAME=ble-unlock
DOMAIN=blelock.github.io
UUID=$(NAME)@$(DOMAIN)
.PHONY: all pack install clean test
all: dist/extension.js
node_modules/.package-lock.json: package.json
npm install
dist/extension.js dist/prefs.js: node_modules/.package-lock.json *.ts
npm run build
schemas/gschemas.compiled: schemas/org.gnome.shell.extensions.bleunlock.gschema.xml
glib-compile-schemas schemas
$(NAME).zip: dist/extension.js dist/prefs.js schemas/gschemas.compiled
@cp -r schemas dist/
@cp metadata.json dist/
@(cd dist && zip ../$(NAME).zip -9r .)
pack: $(NAME).zip
install: $(NAME).zip
gnome-extensions install --force $(NAME).zip
clean:
@rm -rf dist node_modules $(NAME).zip
test: node_modules/.package-lock.json
npm test
+122
View File
@@ -0,0 +1,122 @@
# BLE Unlock
A GNOME Shell 49 extension that locks and unlocks your session based on the
Bluetooth RSSI of a nearby device. When your phone (or any BT device) moves
out of range the screen locks; when it comes back in range the screen unlocks
after a short delay.
## Requirements
- GNOME Shell 49
- BlueZ (the Linux Bluetooth stack)
- Node.js and npm (for building)
## Build & Install
```sh
cd generated/
npm install # install TypeScript + type stubs
make # compile TypeScript → dist/
make install # pack extension + gnome-extensions install --force
```
Reload GNOME Shell after installing, then enable the extension:
```sh
gnome-extensions enable ble-unlock@blelock.github.io
```
## Running Tests
```sh
make test # run all vitest tests
npm run test:unit # unit tests only (thresholds pure logic)
npm run test:integration # integration tests (state-machine)
```
## Nested-Shell Testing (GNOME 49)
Start a nested GNOME Shell session to test the extension live without risking
your main session:
```sh
dbus-run-session gnome-shell --devkit --wayland
```
Inside the nested session, enable the extension:
```sh
gnome-extensions enable ble-unlock@blelock.github.io
```
Run the GJS/Jasmine integration test inside the nested session:
```sh
gjs tests/gnome-shell/extension.test.js
```
## GSettings Keys
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `enabled` | boolean | `false` | Whether BLE monitoring is active |
| `device-address` | string | `""` | MAC address of the BT device to monitor |
| `rssi-lock-threshold` | int | `-75` | Screen locks when RSSI falls below this value (dBm) |
| `rssi-unlock-threshold` | int | `-65` | Screen unlocks when RSSI rises above this value (dBm) |
| `poll-interval` | int | `3` | How often to read the BLE RSSI (seconds) |
Read or write keys with gsettings:
```sh
gsettings set org.gnome.shell.extensions.bleunlock device-address 'AA:BB:CC:DD:EE:FF'
gsettings set org.gnome.shell.extensions.bleunlock enabled true
```
## Architecture
```
generated/
├── thresholds.ts # Pure logic: classifySignal / shouldLock / shouldUnlock
├── bleMonitor.ts # GObject that polls BlueZ RSSI via Gio.DBusProxy
├── quickSettingsMenu.ts # Quick Settings toggle + device list submenu
├── extension.ts # Extension enable/disable; wires monitor → screen lock
├── prefs.ts # GTK4/Adwaita preferences window (separate process)
└── schemas/ # GSettings schema (5 keys)
```
**Two-process boundary:**
- **Shell process** (`extension.ts`, `bleMonitor.ts`, `quickSettingsMenu.ts`): GI libs
only — Clutter, St, Meta, Gio, GLib, GObject. No Gtk/Adw/Gdk.
- **Prefs process** (`prefs.ts`): GTK4 + Adwaita + Gio/GLib only. No Clutter/Meta/St/Shell.
**Data flow:**
1. `BleMonitor` polls `org.bluez.Device1.RSSI` (cached D-Bus property) every N seconds.
2. Each poll feeds into `thresholds.ts` pure functions to detect state transitions.
3. On transition, `BleMonitor.onSignalBelowThreshold()` or `onSignalAboveThreshold()` fires.
4. `extension.ts` wires those hooks to `org.gnome.ScreenSaver.SetActive`.
5. Unlock is delayed 3 seconds to avoid spurious unlocks on brief signal loss.
## Debugging
Watch live extension logs:
```sh
journalctl -f -o cat /usr/bin/gnome-shell | grep BleUnlock
```
Inspect GSettings values:
```sh
gsettings list-recursively org.gnome.shell.extensions.bleunlock
```
Check BlueZ device RSSI manually:
```sh
dbus-send --system --print-reply \
--dest=org.bluez /org/bluez/hci0/dev_AA_BB_CC_DD_EE_FF \
org.freedesktop.DBus.Properties.Get \
string:org.bluez.Device1 string:RSSI
```
+4
View File
@@ -0,0 +1,4 @@
import "@girs/gjs";
import "@girs/gjs/dom";
import "@girs/gnome-shell/ambient";
import "@girs/gnome-shell/extensions/global";
+222
View File
@@ -0,0 +1,222 @@
import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
import GObject from 'gi://GObject';
import { classifySignal, SignalClass, ThresholdConfig } from './thresholds.js';
const BLUEZ_SERVICE = 'org.bluez';
const ADAPTER_PATH = '/org/bluez/hci0';
const ADAPTER_IFACE = 'org.bluez.Adapter1';
const DEVICE_IFACE = 'org.bluez.Device1';
const OBJECT_MANAGER_IFACE = 'org.freedesktop.DBus.ObjectManager';
function addressToPath(address: string): string {
return `${ADAPTER_PATH}/dev_${address.replace(/:/g, '_')}`;
}
export class BleMonitor extends GObject.Object {
static {
GObject.registerClass({
GTypeName: 'BleUnlockMonitor',
Signals: {
'rssi-changed': { param_types: [GObject.TYPE_INT] },
'devices-changed': { param_types: [] },
},
}, this);
}
private _deviceAddress: string = '';
private _config: ThresholdConfig = { rssiLockThreshold: -75, rssiUnlockThreshold: -65 };
private _pollIntervalSec: number = 3;
private _timerId: number | null = null;
private _deviceProxy: Gio.DBusProxy | null = null;
private _adapterProxy: Gio.DBusProxy | null = null;
private _lastClass: SignalClass | null = null;
private _knownDevices: Map<string, string> = new Map();
/**
* Start monitoring the given device address.
*/
startMonitoring(deviceAddress: string, config: ThresholdConfig, pollIntervalSec: number): void {
this._deviceAddress = deviceAddress;
this._config = config;
this._pollIntervalSec = pollIntervalSec;
const bus = Gio.DBus.system;
try {
this._adapterProxy = Gio.DBusProxy.new_sync(
bus,
Gio.DBusProxyFlags.NONE,
null,
BLUEZ_SERVICE,
ADAPTER_PATH,
ADAPTER_IFACE,
null,
);
} catch (e) {
console.error(`[BleUnlock] Failed to create adapter proxy: ${e}`);
return;
}
try {
this._deviceProxy = Gio.DBusProxy.new_sync(
bus,
Gio.DBusProxyFlags.NONE,
null,
BLUEZ_SERVICE,
addressToPath(deviceAddress),
DEVICE_IFACE,
null,
);
} catch (e) {
console.warn(`[BleUnlock] Failed to create device proxy for ${deviceAddress}: ${e}`);
}
this._startDiscovery();
this._refreshDevices();
this._timerId = GLib.timeout_add_seconds(
GLib.PRIORITY_DEFAULT,
this._pollIntervalSec,
() => this._poll(),
);
}
/**
* Stop monitoring and clean up D-Bus resources.
*/
stopMonitoring(): void {
if (this._timerId !== null) {
GLib.Source.remove(this._timerId);
this._timerId = null;
}
this._stopDiscovery();
this._deviceProxy = null;
this._adapterProxy = null;
this._lastClass = null;
}
/** Returns the map of known BT devices (address → name). */
get devices(): Map<string, string> {
return this._knownDevices;
}
/** Called when RSSI drops below lock threshold. Wired by extension.ts. */
onSignalBelowThreshold(): void {}
/** Called when RSSI rises above unlock threshold. Wired by extension.ts. */
onSignalAboveThreshold(): void {}
private _startDiscovery(): void {
if (!this._adapterProxy) return;
try {
this._adapterProxy.call(
'StartDiscovery',
null,
Gio.DBusCallFlags.NONE,
-1,
null,
null,
);
} catch (e) {
console.warn(`[BleUnlock] StartDiscovery failed: ${e}`);
}
}
private _stopDiscovery(): void {
if (!this._adapterProxy) return;
try {
this._adapterProxy.call(
'StopDiscovery',
null,
Gio.DBusCallFlags.NONE,
-1,
null,
null,
);
} catch (e) {
console.warn(`[BleUnlock] StopDiscovery failed: ${e}`);
}
}
private _refreshDevices(): void {
const bus = Gio.DBus.system;
try {
const result = bus.call_sync(
BLUEZ_SERVICE,
'/',
OBJECT_MANAGER_IFACE,
'GetManagedObjects',
null,
null,
Gio.DBusCallFlags.NONE,
-1,
null,
);
if (!result) return;
const objects = result.get_child_value(0);
const nObjects = objects.n_children();
this._knownDevices.clear();
for (let i = 0; i < nObjects; i++) {
const entry = objects.get_child_value(i);
const ifaces = entry.get_child_value(1);
const nIfaces = ifaces.n_children();
for (let j = 0; j < nIfaces; j++) {
const ifaceEntry = ifaces.get_child_value(j);
const ifaceName = ifaceEntry.get_child_value(0).get_string()[0];
if (ifaceName !== DEVICE_IFACE) continue;
const props = ifaceEntry.get_child_value(1);
const nProps = props.n_children();
let address: string | null = null;
let name: string = '';
for (let k = 0; k < nProps; k++) {
const prop = props.get_child_value(k);
const propName = prop.get_child_value(0).get_string()[0];
const propValue = prop.get_child_value(1).get_child_value(0);
if (propName === 'Address') address = propValue.get_string()[0];
if (propName === 'Name') name = propValue.get_string()[0];
}
if (address) this._knownDevices.set(address, name);
}
}
this.emit('devices-changed');
} catch (e) {
console.warn(`[BleUnlock] GetManagedObjects failed: ${e}`);
}
}
private _poll(): boolean {
let rssi: number | null = null;
if (this._deviceProxy) {
const variant = this._deviceProxy.get_cached_property('RSSI');
if (variant) {
rssi = variant.get_int16();
}
}
const currentClass = classifySignal(rssi, this._config);
this.emit('rssi-changed', rssi ?? 0);
if (this._lastClass !== currentClass) {
if (currentClass === 'absent' && this._lastClass !== null) {
console.debug(`[BleUnlock] Signal below threshold (RSSI=${rssi}), locking`);
this.onSignalBelowThreshold();
} else if (currentClass === 'strong' && this._lastClass !== 'strong') {
console.debug(`[BleUnlock] Signal above threshold (RSSI=${rssi}), unlocking`);
this.onSignalAboveThreshold();
}
this._lastClass = currentClass;
}
return GLib.SOURCE_CONTINUE;
}
}
+161
View File
@@ -0,0 +1,161 @@
import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
import GObject from 'gi://GObject';
import { classifySignal } from './thresholds.js';
const BLUEZ_SERVICE = 'org.bluez';
const ADAPTER_PATH = '/org/bluez/hci0';
const ADAPTER_IFACE = 'org.bluez.Adapter1';
const DEVICE_IFACE = 'org.bluez.Device1';
const OBJECT_MANAGER_IFACE = 'org.freedesktop.DBus.ObjectManager';
function addressToPath(address) {
return `${ADAPTER_PATH}/dev_${address.replace(/:/g, '_')}`;
}
export class BleMonitor extends GObject.Object {
static {
GObject.registerClass({
GTypeName: 'BleUnlockMonitor',
Signals: {
'rssi-changed': { param_types: [GObject.TYPE_INT] },
'devices-changed': { param_types: [] },
},
}, this);
}
_deviceAddress = '';
_config = { rssiLockThreshold: -75, rssiUnlockThreshold: -65 };
_pollIntervalSec = 3;
_timerId = null;
_deviceProxy = null;
_adapterProxy = null;
_lastClass = null;
_knownDevices = new Map();
/**
* Start monitoring the given device address.
*/
startMonitoring(deviceAddress, config, pollIntervalSec) {
this._deviceAddress = deviceAddress;
this._config = config;
this._pollIntervalSec = pollIntervalSec;
const bus = Gio.DBus.system;
try {
this._adapterProxy = Gio.DBusProxy.new_sync(bus, Gio.DBusProxyFlags.NONE, null, BLUEZ_SERVICE, ADAPTER_PATH, ADAPTER_IFACE, null);
}
catch (e) {
console.error(`[BleUnlock] Failed to create adapter proxy: ${e}`);
return;
}
try {
this._deviceProxy = Gio.DBusProxy.new_sync(bus, Gio.DBusProxyFlags.NONE, null, BLUEZ_SERVICE, addressToPath(deviceAddress), DEVICE_IFACE, null);
}
catch (e) {
console.warn(`[BleUnlock] Failed to create device proxy for ${deviceAddress}: ${e}`);
}
this._startDiscovery();
this._refreshDevices();
this._timerId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, this._pollIntervalSec, () => this._poll());
}
/**
* Stop monitoring and clean up D-Bus resources.
*/
stopMonitoring() {
if (this._timerId !== null) {
GLib.Source.remove(this._timerId);
this._timerId = null;
}
this._stopDiscovery();
this._deviceProxy = null;
this._adapterProxy = null;
this._lastClass = null;
}
/** Returns the map of known BT devices (address → name). */
get devices() {
return this._knownDevices;
}
/** Called when RSSI drops below lock threshold. Wired by extension.ts. */
onSignalBelowThreshold() { }
/** Called when RSSI rises above unlock threshold. Wired by extension.ts. */
onSignalAboveThreshold() { }
_startDiscovery() {
if (!this._adapterProxy)
return;
try {
this._adapterProxy.call('StartDiscovery', null, Gio.DBusCallFlags.NONE, -1, null, null);
}
catch (e) {
console.warn(`[BleUnlock] StartDiscovery failed: ${e}`);
}
}
_stopDiscovery() {
if (!this._adapterProxy)
return;
try {
this._adapterProxy.call('StopDiscovery', null, Gio.DBusCallFlags.NONE, -1, null, null);
}
catch (e) {
console.warn(`[BleUnlock] StopDiscovery failed: ${e}`);
}
}
_refreshDevices() {
const bus = Gio.DBus.system;
try {
const result = bus.call_sync(BLUEZ_SERVICE, '/', OBJECT_MANAGER_IFACE, 'GetManagedObjects', null, null, Gio.DBusCallFlags.NONE, -1, null);
if (!result)
return;
const objects = result.get_child_value(0);
const nObjects = objects.n_children();
this._knownDevices.clear();
for (let i = 0; i < nObjects; i++) {
const entry = objects.get_child_value(i);
const ifaces = entry.get_child_value(1);
const nIfaces = ifaces.n_children();
for (let j = 0; j < nIfaces; j++) {
const ifaceEntry = ifaces.get_child_value(j);
const ifaceName = ifaceEntry.get_child_value(0).get_string()[0];
if (ifaceName !== DEVICE_IFACE)
continue;
const props = ifaceEntry.get_child_value(1);
const nProps = props.n_children();
let address = null;
let name = '';
for (let k = 0; k < nProps; k++) {
const prop = props.get_child_value(k);
const propName = prop.get_child_value(0).get_string()[0];
const propValue = prop.get_child_value(1).get_child_value(0);
if (propName === 'Address')
address = propValue.get_string()[0];
if (propName === 'Name')
name = propValue.get_string()[0];
}
if (address)
this._knownDevices.set(address, name);
}
}
this.emit('devices-changed');
}
catch (e) {
console.warn(`[BleUnlock] GetManagedObjects failed: ${e}`);
}
}
_poll() {
let rssi = null;
if (this._deviceProxy) {
const variant = this._deviceProxy.get_cached_property('RSSI');
if (variant) {
rssi = variant.get_int16();
}
}
const currentClass = classifySignal(rssi, this._config);
this.emit('rssi-changed', rssi ?? 0);
if (this._lastClass !== currentClass) {
if (currentClass === 'absent' && this._lastClass !== null) {
console.debug(`[BleUnlock] Signal below threshold (RSSI=${rssi}), locking`);
this.onSignalBelowThreshold();
}
else if (currentClass === 'strong' && this._lastClass !== 'strong') {
console.debug(`[BleUnlock] Signal above threshold (RSSI=${rssi}), unlocking`);
this.onSignalAboveThreshold();
}
this._lastClass = currentClass;
}
return GLib.SOURCE_CONTINUE;
}
}
+130
View File
@@ -0,0 +1,130 @@
import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
import { Extension } from 'resource:///org/gnome/shell/extensions/extension.js';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import { BleMonitor } from './bleMonitor.js';
import { BleUnlockIndicator } from './quickSettingsMenu.js';
const SCREENSAVER_IFACE = `
<node>
<interface name="org.gnome.ScreenSaver">
<method name="SetActive">
<arg type="b" direction="in"/>
</method>
</interface>
</node>`;
export default class BleUnlockExtension extends Extension {
_monitor = null;
_indicator = null;
_settings = null;
_screenSaverProxy = null;
_unlockTimerId = null;
_settingsChangedIds = [];
enable() {
this._settings = this.getSettings();
this._monitor = new BleMonitor();
// Wire lock/unlock hooks
this._monitor.onSignalBelowThreshold = () => {
console.debug('[BleUnlock] Locking screen');
this._setScreenSaverActive(true);
};
this._monitor.onSignalAboveThreshold = () => {
console.debug('[BleUnlock] Scheduling unlock');
if (this._unlockTimerId !== null) {
GLib.Source.remove(this._unlockTimerId);
this._unlockTimerId = null;
}
const UNLOCK_DELAY_SEC = 3;
this._unlockTimerId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, UNLOCK_DELAY_SEC, () => {
console.debug('[BleUnlock] Unlocking screen');
this._setScreenSaverActive(false);
this._unlockTimerId = null;
return GLib.SOURCE_REMOVE;
});
};
// Create ScreenSaver proxy
try {
this._screenSaverProxy = Gio.DBusProxy.new_sync(Gio.DBus.session, Gio.DBusProxyFlags.NONE, Gio.DBusNodeInfo.new_for_xml(SCREENSAVER_IFACE).lookup_interface('org.gnome.ScreenSaver'), 'org.gnome.ScreenSaver', '/org/gnome/ScreenSaver', 'org.gnome.ScreenSaver', null);
}
catch (e) {
console.error(`[BleUnlock] Failed to create ScreenSaver proxy: ${e}`);
}
// Create indicator and add to quick settings
this._indicator = new BleUnlockIndicator(this._settings, this._monitor, () => this.openPreferences(), this.uuid);
Main.panel.statusArea.quickSettings.addExternalIndicator(this._indicator);
// Start monitoring if enabled
if (this._settings.get_boolean('enabled')) {
this._startMonitoring();
}
// Watch settings changes
this._settingsChangedIds.push(this._settings.connect('changed::enabled', () => {
if (this._settings.get_boolean('enabled')) {
this._startMonitoring();
}
else {
this._monitor?.stopMonitoring();
}
}));
this._settingsChangedIds.push(this._settings.connect('changed::device-address', () => {
if (this._settings.get_boolean('enabled')) {
this._monitor?.stopMonitoring();
this._startMonitoring();
}
}));
this._settingsChangedIds.push(this._settings.connect('changed::poll-interval', () => {
if (this._settings.get_boolean('enabled')) {
this._monitor?.stopMonitoring();
this._startMonitoring();
}
}));
}
/**
* disable() is NOT called on screen lock because this extension uses
* session-modes: ["user", "unlock-dialog"]. It is called when the extension
* is disabled, GNOME Shell exits, or the user logs out.
*
* Stops all timers, disconnects all signals, nulls all references, destroys all widgets.
*/
disable() {
if (this._unlockTimerId !== null) {
GLib.Source.remove(this._unlockTimerId);
this._unlockTimerId = null;
}
this._monitor?.stopMonitoring();
this._monitor = null;
this._indicator?.destroy();
this._indicator = null;
if (this._settings) {
for (const id of this._settingsChangedIds) {
this._settings.disconnect(id);
}
}
this._settingsChangedIds = [];
this._settings = null;
this._screenSaverProxy = null;
}
_startMonitoring() {
if (!this._monitor || !this._settings)
return;
const address = this._settings.get_string('device-address');
if (!address)
return;
const config = {
rssiLockThreshold: this._settings.get_int('rssi-lock-threshold'),
rssiUnlockThreshold: this._settings.get_int('rssi-unlock-threshold'),
};
const pollInterval = this._settings.get_int('poll-interval');
this._monitor.startMonitoring(address, config, pollInterval);
}
_setScreenSaverActive(active) {
if (!this._screenSaverProxy)
return;
try {
this._screenSaverProxy.call('SetActive',
// eslint-disable-next-line @typescript-eslint/no-explicit-any
new GLib.Variant('(b)', [active]), Gio.DBusCallFlags.NONE, -1, null, null);
}
catch (e) {
console.error(`[BleUnlock] SetActive(${active}) failed: ${e}`);
}
}
}
+62
View File
@@ -0,0 +1,62 @@
import Adw from 'gi://Adw';
import Gio from 'gi://Gio';
import Gtk from 'gi://Gtk';
import { ExtensionPreferences } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';
export default class BleUnlockPreferences extends ExtensionPreferences {
async fillPreferencesWindow(window) {
const settings = this.getSettings();
const page = new Adw.PreferencesPage({
title: 'General',
iconName: 'preferences-system-symbolic',
});
window.add(page);
// Device group
const deviceGroup = new Adw.PreferencesGroup({ title: 'Device' });
page.add(deviceGroup);
const deviceRow = new Adw.EntryRow({ title: 'Device MAC Address' });
settings.bind('device-address', deviceRow, 'text', Gio.SettingsBindFlags.DEFAULT);
deviceGroup.add(deviceRow);
// Thresholds group
const thresholdGroup = new Adw.PreferencesGroup({ title: 'Thresholds' });
page.add(thresholdGroup);
const lockRow = new Adw.SpinRow({
title: 'Lock Threshold (dBm)',
subtitle: 'Screen locks when RSSI falls below this value',
adjustment: new Gtk.Adjustment({
lower: -100,
upper: 0,
stepIncrement: 1,
pageIncrement: 5,
}),
});
settings.bind('rssi-lock-threshold', lockRow, 'value', Gio.SettingsBindFlags.DEFAULT);
thresholdGroup.add(lockRow);
const unlockRow = new Adw.SpinRow({
title: 'Unlock Threshold (dBm)',
subtitle: 'Screen unlocks when RSSI rises above this value',
adjustment: new Gtk.Adjustment({
lower: -100,
upper: 0,
stepIncrement: 1,
pageIncrement: 5,
}),
});
settings.bind('rssi-unlock-threshold', unlockRow, 'value', Gio.SettingsBindFlags.DEFAULT);
thresholdGroup.add(unlockRow);
// Polling group
const pollingGroup = new Adw.PreferencesGroup({ title: 'Polling' });
page.add(pollingGroup);
const pollRow = new Adw.SpinRow({
title: 'Poll Interval (seconds)',
subtitle: 'How often to read BLE RSSI',
adjustment: new Gtk.Adjustment({
lower: 1,
upper: 60,
stepIncrement: 1,
pageIncrement: 5,
}),
});
settings.bind('poll-interval', pollRow, 'value', Gio.SettingsBindFlags.DEFAULT);
pollingGroup.add(pollRow);
}
}
+99
View File
@@ -0,0 +1,99 @@
import GObject from 'gi://GObject';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js';
import * as QuickSettings from 'resource:///org/gnome/shell/ui/quickSettings.js';
export const BleUnlockMenuToggle = GObject.registerClass(class BleUnlockMenuToggle extends QuickSettings.QuickMenuToggle {
_settings;
_monitor;
_deviceItems = new Map();
_rssiItem = null;
_rssiChangedId = 0;
_devicesChangedId = 0;
_settingsChangedId = 0;
constructor(settings, monitor, openPreferences, extensionUuid) {
super({
title: 'BLE Unlock',
iconName: 'bluetooth-symbolic',
toggleMode: true,
});
this._settings = settings;
this._monitor = monitor;
this.menu.setHeader('bluetooth-symbolic', 'BLE Unlock');
this._rssiItem = new PopupMenu.PopupMenuItem('RSSI: —', { reactive: false });
this.menu.addMenuItem(this._rssiItem);
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this._buildDeviceList();
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
const settingsItem = this.menu.addAction('Settings', openPreferences);
// Hide the settings item when the screen is locked
settingsItem.visible = Main.sessionMode.allowSettings;
// Register in _settingsActions so it is hidden on the lock screen
this.menu._settingsActions[extensionUuid] = settingsItem;
this._settingsChangedId = this._settings.connect('changed::enabled', () => {
this.checked = this._settings.get_boolean('enabled');
});
this.checked = this._settings.get_boolean('enabled');
this.connect('clicked', () => {
this._settings.set_boolean('enabled', !this._settings.get_boolean('enabled'));
});
this._rssiChangedId = this._monitor.connect('rssi-changed', (_obj, rssi) => {
this._onRssiChanged(rssi);
});
this._devicesChangedId = this._monitor.connect('devices-changed', () => {
this._buildDeviceList();
});
}
_buildDeviceList() {
for (const [, item] of this._deviceItems) {
item.destroy();
}
this._deviceItems.clear();
const selectedAddress = this._settings.get_string('device-address');
for (const [address, name] of this._monitor.devices) {
const label = name ? `${name} (${address})` : address;
const item = new PopupMenu.PopupMenuItem(label);
item.setOrnament(address === selectedAddress
? PopupMenu.Ornament.CHECK
: PopupMenu.Ornament.NONE);
item.connect('activate', () => {
this._settings.set_string('device-address', address);
this._buildDeviceList();
});
this._deviceItems.set(address, item);
// Insert before the last separator and settings item
this.menu.addMenuItem(item, 2);
}
}
_onRssiChanged(rssi) {
const selectedAddress = this._settings.get_string('device-address');
const subtitle = rssi !== 0 ? `${selectedAddress} · ${rssi} dBm` : selectedAddress;
this.subtitle = subtitle;
if (this._rssiItem) {
this._rssiItem.label.text = rssi !== 0 ? `RSSI: ${rssi} dBm` : 'RSSI: —';
}
}
destroy() {
if (this._rssiChangedId)
this._monitor.disconnect(this._rssiChangedId);
if (this._devicesChangedId)
this._monitor.disconnect(this._devicesChangedId);
if (this._settingsChangedId)
this._settings.disconnect(this._settingsChangedId);
super.destroy();
}
});
export const BleUnlockIndicator = GObject.registerClass(class BleUnlockIndicator extends QuickSettings.SystemIndicator {
_toggle = null;
constructor(settings, monitor, openPreferences, extensionUuid) {
super();
this._toggle = new BleUnlockMenuToggle(settings, monitor, openPreferences, extensionUuid);
this.quickSettingsItems.push(this._toggle);
}
destroy() {
if (this._toggle) {
this._toggle.destroy();
this._toggle = null;
}
super.destroy();
}
});
+30
View File
@@ -0,0 +1,30 @@
/**
* Classify a raw RSSI reading relative to configured thresholds.
* null means device is absent (not visible / out of range).
* 'strong' means above unlock threshold → can unlock.
* 'weak' means between lock and unlock thresholds → hysteresis zone.
* 'absent' means below lock threshold → should lock.
*/
export function classifySignal(rssi, config) {
if (rssi === null || rssi <= config.rssiLockThreshold) {
return 'absent';
}
if (rssi > config.rssiUnlockThreshold) {
return 'strong';
}
return 'weak';
}
/**
* Determine whether the screen should be locked based on current RSSI.
* Returns true when the signal is absent (below lock threshold).
*/
export function shouldLock(rssi, config) {
return classifySignal(rssi, config) === 'absent';
}
/**
* Determine whether the screen should be unlocked based on current RSSI.
* Returns true when the signal is strong (above unlock threshold).
*/
export function shouldUnlock(rssi, config) {
return classifySignal(rssi, config) === 'strong';
}
+171
View File
@@ -0,0 +1,171 @@
import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
import { Extension } from 'resource:///org/gnome/shell/extensions/extension.js';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import { BleMonitor } from './bleMonitor.js';
import { BleUnlockIndicator } from './quickSettingsMenu.js';
const SCREENSAVER_IFACE = `
<node>
<interface name="org.gnome.ScreenSaver">
<method name="SetActive">
<arg type="b" direction="in"/>
</method>
</interface>
</node>`;
export default class BleUnlockExtension extends Extension {
private _monitor: BleMonitor | null = null;
private _indicator: InstanceType<typeof BleUnlockIndicator> | null = null;
private _settings: Gio.Settings | null = null;
private _screenSaverProxy: Gio.DBusProxy | null = null;
private _unlockTimerId: number | null = null;
private _settingsChangedIds: number[] = [];
enable(): void {
this._settings = this.getSettings();
this._monitor = new BleMonitor();
// Wire lock/unlock hooks
this._monitor.onSignalBelowThreshold = () => {
console.debug('[BleUnlock] Locking screen');
this._setScreenSaverActive(true);
};
this._monitor.onSignalAboveThreshold = () => {
console.debug('[BleUnlock] Scheduling unlock');
if (this._unlockTimerId !== null) {
GLib.Source.remove(this._unlockTimerId);
this._unlockTimerId = null;
}
const UNLOCK_DELAY_SEC = 3;
this._unlockTimerId = GLib.timeout_add_seconds(
GLib.PRIORITY_DEFAULT,
UNLOCK_DELAY_SEC,
() => {
console.debug('[BleUnlock] Unlocking screen');
this._setScreenSaverActive(false);
this._unlockTimerId = null;
return GLib.SOURCE_REMOVE;
},
);
};
// Create ScreenSaver proxy
try {
this._screenSaverProxy = Gio.DBusProxy.new_sync(
Gio.DBus.session,
Gio.DBusProxyFlags.NONE,
Gio.DBusNodeInfo.new_for_xml(SCREENSAVER_IFACE).lookup_interface('org.gnome.ScreenSaver'),
'org.gnome.ScreenSaver',
'/org/gnome/ScreenSaver',
'org.gnome.ScreenSaver',
null,
);
} catch (e) {
console.error(`[BleUnlock] Failed to create ScreenSaver proxy: ${e}`);
}
// Create indicator and add to quick settings
this._indicator = new BleUnlockIndicator(
this._settings,
this._monitor,
() => this.openPreferences(),
this.uuid,
);
Main.panel.statusArea.quickSettings.addExternalIndicator(this._indicator as any);
// Start monitoring if enabled
if (this._settings.get_boolean('enabled')) {
this._startMonitoring();
}
// Watch settings changes
this._settingsChangedIds.push(
this._settings.connect('changed::enabled', () => {
if (this._settings!.get_boolean('enabled')) {
this._startMonitoring();
} else {
this._monitor?.stopMonitoring();
}
}),
);
this._settingsChangedIds.push(
this._settings.connect('changed::device-address', () => {
if (this._settings!.get_boolean('enabled')) {
this._monitor?.stopMonitoring();
this._startMonitoring();
}
}),
);
this._settingsChangedIds.push(
this._settings.connect('changed::poll-interval', () => {
if (this._settings!.get_boolean('enabled')) {
this._monitor?.stopMonitoring();
this._startMonitoring();
}
}),
);
}
/**
* disable() is NOT called on screen lock because this extension uses
* session-modes: ["user", "unlock-dialog"]. It is called when the extension
* is disabled, GNOME Shell exits, or the user logs out.
*
* Stops all timers, disconnects all signals, nulls all references, destroys all widgets.
*/
disable(): void {
if (this._unlockTimerId !== null) {
GLib.Source.remove(this._unlockTimerId);
this._unlockTimerId = null;
}
this._monitor?.stopMonitoring();
this._monitor = null;
this._indicator?.destroy();
this._indicator = null;
if (this._settings) {
for (const id of this._settingsChangedIds) {
this._settings.disconnect(id);
}
}
this._settingsChangedIds = [];
this._settings = null;
this._screenSaverProxy = null;
}
private _startMonitoring(): void {
if (!this._monitor || !this._settings) return;
const address = this._settings.get_string('device-address');
if (!address) return;
const config = {
rssiLockThreshold: this._settings.get_int('rssi-lock-threshold'),
rssiUnlockThreshold: this._settings.get_int('rssi-unlock-threshold'),
};
const pollInterval = this._settings.get_int('poll-interval');
this._monitor.startMonitoring(address, config, pollInterval);
}
private _setScreenSaverActive(active: boolean): void {
if (!this._screenSaverProxy) return;
try {
this._screenSaverProxy.call(
'SetActive',
// eslint-disable-next-line @typescript-eslint/no-explicit-any
new GLib.Variant('(b)', [active]) as any,
Gio.DBusCallFlags.NONE,
-1,
null,
null,
);
} catch (e) {
console.error(`[BleUnlock] SetActive(${active}) failed: ${e}`);
}
}
}
+10
View File
@@ -0,0 +1,10 @@
{
"uuid": "ble-unlock@blelock.github.io",
"name": "BLE Unlock",
"description": "Lock/unlock your GNOME session based on Bluetooth RSSI of a nearby device.",
"version": 1,
"shell-version": ["49"],
"session-modes": ["user", "unlock-dialog"],
"settings-schema": "org.gnome.shell.extensions.bleunlock",
"url": "https://github.com/blelock/blelock"
}
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../acorn/bin/acorn
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../esbuild/bin/esbuild
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../nanoid/bin/nanoid.cjs
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../which/bin/node-which
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../rollup/dist/bin/rollup
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../typescript/bin/tsc
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../typescript/bin/tsserver
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../vite/bin/vite.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../vite-node/vite-node.mjs
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../vitest/vitest.mjs
+1
View File
@@ -0,0 +1 @@
../why-is-node-running/cli.js
+3369
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -0,0 +1 @@
{"version":"1.6.1","results":[[":tests/integration/bleMonitor.test.ts",{"duration":2,"failed":false}],[":tests/unit/thresholds.test.ts",{"duration":2,"failed":false}]]}
+3
View File
@@ -0,0 +1,3 @@
# esbuild
This is the Linux ARM 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.
+20
View File
@@ -0,0 +1,20 @@
{
"name": "@esbuild/linux-arm64",
"version": "0.21.5",
"description": "The Linux ARM 64-bit binary for esbuild, a JavaScript bundler.",
"repository": {
"type": "git",
"url": "git+https://github.com/evanw/esbuild.git"
},
"license": "MIT",
"preferUnplugged": true,
"engines": {
"node": ">=12"
},
"os": [
"linux"
],
"cpu": [
"arm64"
]
}
+85
View File
@@ -0,0 +1,85 @@
# AccountsService-1.0
![version](https://img.shields.io/npm/v/@girs/accountsservice-1.0)
![downloads/week](https://img.shields.io/npm/dw/@girs/accountsservice-1.0)
GJS TypeScript type definitions for AccountsService-1.0, generated from library version 1.0.0 using [ts-for-gir](https://github.com/gjsify/ts-for-gir) v4.0.0-beta.38.
## Install
To use this type definitions, install them with NPM:
```bash
npm install @girs/accountsservice-1.0
```
## Usage
You can import this package into your project like this:
```ts
import AccountsService from '@girs/accountsservice-1.0';
```
### Ambient Modules
You can also use [ambient modules](https://github.com/gjsify/ts-for-gir/tree/main/packages/cli#ambient-modules) to import this module like you would do this in JavaScript.
For this you need to include `@girs/accountsservice-1.0` or `@girs/accountsservice-1.0/ambient` in your `tsconfig` or entry point Typescript file:
`index.ts`:
```ts
import '@girs/accountsservice-1.0'
```
`tsconfig.json`:
```json
{
"compilerOptions": {
...
},
"include": ["@girs/accountsservice-1.0"],
...
}
```
Now you can import the ambient module with TypeScript support:
```ts
import AccountsService from 'gi://AccountsService?version=1.0';
```
### Global import
You can also import the module with Typescript support using the global `imports.gi` object of GJS.
For this you need to include `@girs/accountsservice-1.0` or `@girs/accountsservice-1.0/import` in your `tsconfig` or entry point Typescript file:
`index.ts`:
```ts
import '@girs/accountsservice-1.0'
```
`tsconfig.json`:
```json
{
"compilerOptions": {
...
},
"include": ["@girs/accountsservice-1.0"],
...
}
```
Now you have also type support for this, too:
```ts
const AccountsService = imports.gi.AccountsService;
```
### Bundle
Depending on your project configuration, it is recommended to use a bundler like [esbuild](https://esbuild.github.io/). You can find examples using different bundlers [here](https://github.com/gjsify/ts-for-gir/tree/main/examples).
## Other packages
All existing pre-generated packages can be found on [gjsify/types](https://github.com/gjsify/types).
@@ -0,0 +1,9 @@
declare module 'gi://AccountsService?version=1.0' {
import AccountsService10 from '@girs/accountsservice-1.0';
export default AccountsService10;
}
declare module 'gi://AccountsService' {
import AccountsService10 from 'gi://AccountsService?version=1.0';
export default AccountsService10;
}
@@ -0,0 +1,2 @@
export {}
@@ -0,0 +1,9 @@
import type AccountsService10 from '@girs/accountsservice-1.0';
declare global {
export interface GjsGiImports {
AccountsService: typeof AccountsService10;
}
}
export default GjsGiImports;
@@ -0,0 +1,3 @@
const gi = globalThis.imports?.gi || {};
export default gi;
@@ -0,0 +1,971 @@
/**
* Type Definitions for Gjs (https://gjs.guide/)
*
* These type definitions are automatically generated, do not edit them by hand.
* If you found a bug fix it in `ts-for-gir` or create a bug report on https://github.com/gjsify/ts-for-gir
*
* The based EJS template file is used for the generated .d.ts file of each GIR module like Gtk-4.0, GObject-2.0, ...
*/
import '@girs/gjs';
// Module dependencies
import type Gio from '@girs/gio-2.0';
import type GObject from '@girs/gobject-2.0';
import type GLib from '@girs/glib-2.0';
import type GModule from '@girs/gmodule-2.0';
export namespace AccountsService {
/**
* AccountsService-1.0
*/
/**
* Type of user account
*/
/**
* Type of user account
*/
export namespace UserAccountType {
export const $gtype: GObject.GType<UserAccountType>;
}
enum UserAccountType {
/**
* Normal non-administrative user
*/
STANDARD,
/**
* Administrative user
*/
ADMINISTRATOR,
}
/**
* Various error codes returned by the accounts service.
*/
class UserManagerError extends GLib.Error {
static $gtype: GObject.GType<UserManagerError>;
// Static fields
/**
* Generic failure
*/
static FAILED: number;
/**
* The user already exists
*/
static USER_EXISTS: number;
/**
* The user does not exist
*/
static USER_DOES_NOT_EXIST: number;
/**
* Permission denied
*/
static PERMISSION_DENIED: number;
/**
* Operation not supported
*/
static NOT_SUPPORTED: number;
// Constructors
constructor(options: { message: string; code: number });
_init(...args: any[]): void;
// Static methods
static quark(): GLib.Quark;
}
/**
* Mode for setting the user's password.
*/
/**
* Mode for setting the user's password.
*/
export namespace UserPasswordMode {
export const $gtype: GObject.GType<UserPasswordMode>;
}
enum UserPasswordMode {
/**
* Password set normally
*/
REGULAR,
/**
* Password will be chosen at next login
*/
SET_AT_LOGIN,
/**
* No password set
*/
NONE,
}
function user_manager_error_quark(): GLib.Quark;
namespace User {
// Signal signatures
interface SignalSignatures extends GObject.Object.SignalSignatures {
changed: () => void;
'sessions-changed': () => void;
'notify::account-type': (pspec: GObject.ParamSpec) => void;
'notify::automatic-login': (pspec: GObject.ParamSpec) => void;
'notify::email': (pspec: GObject.ParamSpec) => void;
'notify::home-directory': (pspec: GObject.ParamSpec) => void;
'notify::icon-file': (pspec: GObject.ParamSpec) => void;
'notify::is-loaded': (pspec: GObject.ParamSpec) => void;
'notify::language': (pspec: GObject.ParamSpec) => void;
'notify::local-account': (pspec: GObject.ParamSpec) => void;
'notify::location': (pspec: GObject.ParamSpec) => void;
'notify::locked': (pspec: GObject.ParamSpec) => void;
'notify::login-frequency': (pspec: GObject.ParamSpec) => void;
'notify::login-history': (pspec: GObject.ParamSpec) => void;
'notify::login-time': (pspec: GObject.ParamSpec) => void;
'notify::nonexistent': (pspec: GObject.ParamSpec) => void;
'notify::password-hint': (pspec: GObject.ParamSpec) => void;
'notify::password-mode': (pspec: GObject.ParamSpec) => void;
'notify::real-name': (pspec: GObject.ParamSpec) => void;
'notify::shell': (pspec: GObject.ParamSpec) => void;
'notify::system-account': (pspec: GObject.ParamSpec) => void;
'notify::uid': (pspec: GObject.ParamSpec) => void;
'notify::user-name': (pspec: GObject.ParamSpec) => void;
'notify::x-session': (pspec: GObject.ParamSpec) => void;
}
// Constructor properties interface
interface ConstructorProps extends GObject.Object.ConstructorProps {
account_type: number;
accountType: number;
automatic_login: boolean;
automaticLogin: boolean;
email: string;
home_directory: string;
homeDirectory: string;
icon_file: string;
iconFile: string;
is_loaded: boolean;
isLoaded: boolean;
language: string;
local_account: boolean;
localAccount: boolean;
location: string;
locked: boolean;
login_frequency: number;
loginFrequency: number;
login_history: GLib.Variant;
loginHistory: GLib.Variant;
login_time: number;
loginTime: number;
nonexistent: boolean;
password_hint: string;
passwordHint: string;
password_mode: number;
passwordMode: number;
real_name: string;
realName: string;
shell: string;
system_account: boolean;
systemAccount: boolean;
uid: number;
user_name: string;
userName: string;
x_session: string;
xSession: string;
}
}
/**
* Represents a user account on the system.
*/
class User extends GObject.Object {
static $gtype: GObject.GType<User>;
// Properties
get account_type(): number;
get accountType(): number;
get automatic_login(): boolean;
get automaticLogin(): boolean;
get email(): string;
get home_directory(): string;
get homeDirectory(): string;
get icon_file(): string;
get iconFile(): string;
get is_loaded(): boolean;
get isLoaded(): boolean;
/**
* The users locale, in the format
* `language[_territory][.codeset][`modifier]``, where `language` is an
* ISO 639 language code, `territory` is an ISO 3166 country code, and
* `codeset` is a character set or encoding identifier like `ISO-8859-1`
* or `UTF-8`; as specified by [`setlocale(3)`](man:setlocale(3)).
*
* The locale may be the empty string, which means the user is using the
* system default locale.
*
* The property may be %NULL if it wasnt possible to load it from the
* daemon.
*/
get language(): string;
get local_account(): boolean;
get localAccount(): boolean;
get location(): string;
get locked(): boolean;
get login_frequency(): number;
get loginFrequency(): number;
get login_history(): GLib.Variant;
get loginHistory(): GLib.Variant;
get login_time(): number;
get loginTime(): number;
get nonexistent(): boolean;
get password_hint(): string;
get passwordHint(): string;
get password_mode(): number;
get passwordMode(): number;
get real_name(): string;
get realName(): string;
get shell(): string;
get system_account(): boolean;
get systemAccount(): boolean;
get uid(): number;
get user_name(): string;
get userName(): string;
get x_session(): string;
get xSession(): string;
/**
* Compile-time signal type information.
*
* This instance property is generated only for TypeScript type checking.
* It is not defined at runtime and should not be accessed in JS code.
* @internal
*/
$signals: User.SignalSignatures;
// Constructors
constructor(properties?: Partial<User.ConstructorProps>, ...args: any[]);
_init(...args: any[]): void;
// Signals
connect<K extends keyof User.SignalSignatures>(
signal: K,
callback: GObject.SignalCallback<this, User.SignalSignatures[K]>,
): number;
connect(signal: string, callback: (...args: any[]) => any): number;
connect_after<K extends keyof User.SignalSignatures>(
signal: K,
callback: GObject.SignalCallback<this, User.SignalSignatures[K]>,
): number;
connect_after(signal: string, callback: (...args: any[]) => any): number;
emit<K extends keyof User.SignalSignatures>(
signal: K,
...args: GObject.GjsParameters<User.SignalSignatures[K]> extends [any, ...infer Q] ? Q : never
): void;
emit(signal: string, ...args: any[]): void;
// Methods
/**
* Organize the user by login frequency and names.
* @param user2 a user
* @returns negative if @user1 is before @user2, zero if equal or positive if @user1 is after @user2
*/
collate(user2: User): number;
/**
* Retrieves the account type of `user`.
* @returns a #ActUserAccountType
*/
get_account_type(): UserAccountType;
/**
* Returns whether or not #ActUser is automatically logged in at boot time.
* @returns %TRUE or %FALSE
*/
get_automatic_login(): boolean;
/**
* Retrieves the email address set by `user`.
* @returns a pointer to an array of characters which must not be modified or freed, or %NULL.
*/
get_email(): string;
/**
* Retrieves the home directory for `user`.
* @returns a pointer to an array of characters which must not be modified or freed, or %NULL.
*/
get_home_dir(): string;
/**
* Returns the path to the account icon belonging to `user`.
* @returns a path to an icon
*/
get_icon_file(): string;
/**
* Returns the value of #ActUser:language.
* @returns the users language, or the empty string if they are using the system default language, or %NULL if there is no connection to the daemon
*/
get_language(): string | null;
/**
* Returns the value of #ActUser:languages.
* @returns the users preferred languages, or the empty string if they are using the system default language, or %NULL if there is no connection to the daemon
*/
get_languages(): string[] | null;
/**
* Retrieves the location set by `user`.
* @returns a pointer to an array of characters which must not be modified or freed, or %NULL.
*/
get_location(): string;
/**
* Returns whether or not the #ActUser account is locked.
* @returns %TRUE or %FALSE
*/
get_locked(): boolean;
/**
* Returns the number of times `user` has logged in.
* @returns the login frequency
*/
get_login_frequency(): number;
/**
* Returns the login history for `user`.
* @returns a pointer to GVariant of type "a(xxa{sv})" which must not be modified or freed, or %NULL.
*/
get_login_history(): GLib.Variant;
/**
* Returns the last login time for `user`.
* @returns the login time
*/
get_login_time(): number;
/**
* Get the number of sessions for a user that are graphical and on the
* same seat as the session of the calling process.
* @returns the number of sessions
*/
get_num_sessions(): number;
/**
* Get the number of sessions for a user on any seat of any type.
* See also act_user_get_num_sessions().
*
* (Currently, this function is only implemented for systemd-logind.
* For ConsoleKit, it is equivalent to act_user_get_num_sessions.)
* @returns the number of sessions
*/
get_num_sessions_anywhere(): number;
/**
* Returns the user accounts service object path of `user,`
* or %NULL if `user` doesn't have an object path associated
* with it.
* @returns the object path of the user
*/
get_object_path(): string;
/**
* Get the password expiration policy for a user.
*
* Note this function is synchronous and ignores errors.
*/
get_password_expiration_policy(): [number, number, number, number, number, number];
/**
* Retrieves the password hint set by `user`.
* @returns a pointer to an array of characters which must not be modified or freed, or %NULL.
*/
get_password_hint(): string;
/**
* Retrieves the password mode of `user`.
* @returns a #ActUserPasswordMode
*/
get_password_mode(): UserPasswordMode;
/**
* Returns the id of the primary session of `user,` or %NULL if `user`
* has no primary session. The primary session will always be
* graphical and will be chosen from the sessions on the same seat as
* the seat of the session of the calling process.
* @returns the id of the primary session of the user
*/
get_primary_session_id(): string;
/**
* Retrieves the display name of `user`.
* @returns a pointer to an array of characters which must not be modified or freed, or %NULL.
*/
get_real_name(): string;
/**
* Returns whether or not the #ActUser account has retained state in accountsservice.
* @returns %TRUE or %FALSE
*/
get_saved(): boolean;
/**
* Returns the path to the configured session for `user`.
* @returns a path to an icon
*/
get_session(): string;
/**
* Returns the type of the configured session for `user`.
* @returns a path to an icon
*/
get_session_type(): string;
/**
* Retrieves the shell assigned to `user`.
* @returns a pointer to an array of characters which must not be modified or freed, or %NULL.
*/
get_shell(): string;
/**
* Retrieves the ID of `user`.
* @returns a pointer to an array of characters which must not be modified or freed, or %NULL.
*/
get_uid(): number;
/**
* Retrieves the login name of `user`.
* @returns a pointer to an array of characters which must not be modified or freed, or %NULL.
*/
get_user_name(): string;
/**
* Returns the path to the configured X session for `user`.
* @returns a path to an icon
*/
get_x_session(): string;
/**
* Retrieves whether the user is a local account or not.
* @returns %TRUE if the user is local
*/
is_local_account(): boolean;
/**
* Returns whether or not #ActUser is currently graphically logged in
* on the same seat as the seat of the session of the calling process.
* @returns %TRUE or %FALSE
*/
is_logged_in(): boolean;
/**
* Returns whether or not #ActUser is currently logged in in any way
* whatsoever. See also act_user_is_logged_in().
*
* (Currently, this function is only implemented for systemd-logind.
* For ConsoleKit, it is equivalent to act_user_is_logged_in.)
* @returns %TRUE or %FALSE
*/
is_logged_in_anywhere(): boolean;
/**
* Retrieves whether the user is nonexistent or not.
* @returns %TRUE if the user is nonexistent
*/
is_nonexistent(): boolean;
/**
* Returns whether or not #ActUser represents a 'system account' like
* 'root' or 'nobody'.
* @returns %TRUE or %FALSE
*/
is_system_account(): boolean;
/**
* Changes the account type of `user`.
*
* Note this function is synchronous and ignores errors.
* @param account_type a #ActUserAccountType
*/
set_account_type(account_type: UserAccountType | null): void;
/**
* If enabled is set to %TRUE then this user will automatically be logged in
* at boot up time. Only one user can be configured to auto login at any given
* time, so subsequent calls to act_user_set_automatic_login() override previous
* calls.
*
* Note this function is synchronous and ignores errors.
* @param enabled whether or not to autologin for user.
*/
set_automatic_login(enabled: boolean): void;
/**
* Assigns a new email to `user`.
*
* Note this function is synchronous and ignores errors.
* @param email an email address
*/
set_email(email: string): void;
/**
* Assigns a new icon for `user`.
*
* Note this function is synchronous and ignores errors.
* @param icon_file path to an icon
*/
set_icon_file(icon_file: string): void;
/**
* Assigns a new locale for `user,` setting #ActUser:language.
*
* Note this function is synchronous and ignores errors.
* @param language a locale (for example, `en_US.utf8`), or the empty string to use the system default locale
*/
set_language(language: string): void;
/**
* Assigns preferred languages for `user,` setting #ActUser:languages, and
* overriding #ActUser:language with the first item in the list if there is one.
*
* Note this function is synchronous and ignores errors.
* @param languages an array of locale (for example, `en_US.utf8`), or the empty string to use the system default locale
*/
set_languages(languages: string[]): void;
/**
* Assigns a new location for `user`.
*
* Note this function is synchronous and ignores errors.
* @param location a location
*/
set_location(location: string): void;
/**
* Note this function is synchronous and ignores errors.
* @param locked whether or not the account is locked
*/
set_locked(locked: boolean): void;
/**
* Changes the password of `user` to `password`.
* `hint` is displayed to the user if they forget the password.
*
* Note this function is synchronous and ignores errors.
* @param password a password
* @param hint a hint to help user recall password
*/
set_password(password: string, hint: string): void;
/**
* Set the password expiration policy for a user.
*
* Note this function is synchronous and ignores errors.
* @param min_days_between_changes location to write minimum number of days needed between password changes.
* @param max_days_between_changes location to write maximum number of days password can stay unchanged.
* @param days_to_warn location to write number of days to warn user password is about to expire.
* @param days_after_expiration_until_lock location to write number of days account will be locked after password expires.
*/
set_password_expiration_policy(
min_days_between_changes: number,
max_days_between_changes: number,
days_to_warn: number,
days_after_expiration_until_lock: number,
): void;
set_password_hint(hint: string): void;
/**
* Changes the password of `user`. If `password_mode` is
* ACT_USER_PASSWORD_MODE_SET_AT_LOGIN then the user will
* be asked for a new password at the next login. If `password_mode`
* is ACT_USER_PASSWORD_MODE_NONE then the user will not require
* a password to log in.
*
* Note this function is synchronous and ignores errors.
* @param password_mode a #ActUserPasswordMode
*/
set_password_mode(password_mode: UserPasswordMode | null): void;
/**
* Assigns a new name for `user`.
*
* Note this function is synchronous and ignores errors.
* @param real_name a new name
*/
set_real_name(real_name: string): void;
/**
* Assigns a new session for `user`.
*
* Note this function is synchronous and ignores errors.
* @param session a session (e.g. gnome)
*/
set_session(session: string): void;
/**
* Assigns a type to the session for `user`.
*
* Note this function is synchronous and ignores errors.
* @param session_type a type of session (e.g. "wayland" or "x11")
*/
set_session_type(session_type: string): void;
/**
* Set the user expiration policy for a user.
*
* Note this function is synchronous and ignores errors.
* @param expiration_time location to write users expires timestamp
*/
set_user_expiration_policy(expiration_time: number): void;
/**
* Assigns a new username for `user`.
*
* Note this function is synchronous and ignores errors.
* @param user_name a new user name
*/
set_user_name(user_name: string): void;
/**
* Assigns a new x session for `user`.
*
* Note this function is synchronous and ignores errors.
* @param x_session an x session (e.g. gnome)
*/
set_x_session(x_session: string): void;
}
namespace UserManager {
// Signal signatures
interface SignalSignatures extends GObject.Object.SignalSignatures {
'user-added': (arg0: User) => void;
'user-changed': (arg0: User) => void;
'user-is-logged-in-changed': (arg0: User) => void;
'user-removed': (arg0: User) => void;
'notify::exclude-usernames-list': (pspec: GObject.ParamSpec) => void;
'notify::has-multiple-users': (pspec: GObject.ParamSpec) => void;
'notify::include-usernames-list': (pspec: GObject.ParamSpec) => void;
'notify::is-loaded': (pspec: GObject.ParamSpec) => void;
}
// Constructor properties interface
interface ConstructorProps extends GObject.Object.ConstructorProps {
exclude_usernames_list: any;
excludeUsernamesList: any;
has_multiple_users: boolean;
hasMultipleUsers: boolean;
include_usernames_list: any;
includeUsernamesList: any;
is_loaded: boolean;
isLoaded: boolean;
}
}
/**
* A user manager object.
*/
class UserManager extends GObject.Object {
static $gtype: GObject.GType<UserManager>;
// Properties
get exclude_usernames_list(): any;
set exclude_usernames_list(val: any);
get excludeUsernamesList(): any;
set excludeUsernamesList(val: any);
get has_multiple_users(): boolean;
set has_multiple_users(val: boolean);
get hasMultipleUsers(): boolean;
set hasMultipleUsers(val: boolean);
get include_usernames_list(): any;
set include_usernames_list(val: any);
get includeUsernamesList(): any;
set includeUsernamesList(val: any);
get is_loaded(): boolean;
get isLoaded(): boolean;
/**
* Compile-time signal type information.
*
* This instance property is generated only for TypeScript type checking.
* It is not defined at runtime and should not be accessed in JS code.
* @internal
*/
$signals: UserManager.SignalSignatures;
// Constructors
constructor(properties?: Partial<UserManager.ConstructorProps>, ...args: any[]);
_init(...args: any[]): void;
// Signals
connect<K extends keyof UserManager.SignalSignatures>(
signal: K,
callback: GObject.SignalCallback<this, UserManager.SignalSignatures[K]>,
): number;
connect(signal: string, callback: (...args: any[]) => any): number;
connect_after<K extends keyof UserManager.SignalSignatures>(
signal: K,
callback: GObject.SignalCallback<this, UserManager.SignalSignatures[K]>,
): number;
connect_after(signal: string, callback: (...args: any[]) => any): number;
emit<K extends keyof UserManager.SignalSignatures>(
signal: K,
...args: GObject.GjsParameters<UserManager.SignalSignatures[K]> extends [any, ...infer Q] ? Q : never
): void;
emit(signal: string, ...args: any[]): void;
// Static methods
/**
* Returns the user manager singleton instance. Calling this function will
* automatically being loading the user list if it isn't loaded already.
* The #ActUserManager:is-loaded property will be set to %TRUE when the users
* are finished loading and then act_user_manager_list_users() can be called.
*/
static get_default(): UserManager;
// Virtual methods
vfunc_user_added(user: User): void;
vfunc_user_changed(user: User): void;
vfunc_user_is_logged_in_changed(user: User): void;
vfunc_user_removed(user: User): void;
// Methods
/**
* Activate the session for a given user.
* @param user the user to activate
* @returns whether successfully activated
*/
activate_user_session(user: User): boolean;
/**
* Caches a user account so it shows up via act_user_manager_list_users().
* @param username a user name
* @returns user object
*/
cache_user(username: string): User;
/**
* Asynchronously caches a user account so it shows up via
* act_user_manager_list_users().
*
* For more details, see act_user_manager_cache_user(), which
* is the synchronous version of this call.
* @param username a unix user name
* @param cancellable optional #GCancellable object, %NULL to ignore
*/
cache_user_async(username: string, cancellable?: Gio.Cancellable | null): globalThis.Promise<User>;
/**
* Asynchronously caches a user account so it shows up via
* act_user_manager_list_users().
*
* For more details, see act_user_manager_cache_user(), which
* is the synchronous version of this call.
* @param username a unix user name
* @param cancellable optional #GCancellable object, %NULL to ignore
* @param callback a #GAsyncReadyCallback to call when the request is satisfied
*/
cache_user_async(
username: string,
cancellable: Gio.Cancellable | null,
callback: Gio.AsyncReadyCallback<this> | null,
): void;
/**
* Asynchronously caches a user account so it shows up via
* act_user_manager_list_users().
*
* For more details, see act_user_manager_cache_user(), which
* is the synchronous version of this call.
* @param username a unix user name
* @param cancellable optional #GCancellable object, %NULL to ignore
* @param callback a #GAsyncReadyCallback to call when the request is satisfied
*/
cache_user_async(
username: string,
cancellable?: Gio.Cancellable | null,
callback?: Gio.AsyncReadyCallback<this> | null,
): globalThis.Promise<User> | void;
/**
* Finishes an asynchronous user caching.
*
* See act_user_manager_cache_user_async().
* @param result a #GAsyncResult
* @returns user object
*/
cache_user_finish(result: Gio.AsyncResult): User;
/**
* Check whether the user can switch to another session.
* @returns whether we can switch to another session
*/
can_switch(): boolean;
/**
* Creates a user account on the system.
* @param username a unix user name
* @param fullname a unix GECOS value
* @param accounttype a #ActUserAccountType
* @returns user object
*/
create_user(username: string, fullname: string, accounttype: UserAccountType | null): User;
/**
* Asynchronously creates a user account on the system.
*
* For more details, see act_user_manager_create_user(), which
* is the synchronous version of this call.
* @param username a unix user name
* @param fullname a unix GECOS value
* @param accounttype a #ActUserAccountType
* @param cancellable optional #GCancellable object, %NULL to ignore
*/
create_user_async(
username: string,
fullname: string,
accounttype: UserAccountType | null,
cancellable?: Gio.Cancellable | null,
): globalThis.Promise<User>;
/**
* Asynchronously creates a user account on the system.
*
* For more details, see act_user_manager_create_user(), which
* is the synchronous version of this call.
* @param username a unix user name
* @param fullname a unix GECOS value
* @param accounttype a #ActUserAccountType
* @param cancellable optional #GCancellable object, %NULL to ignore
* @param callback a #GAsyncReadyCallback to call when the request is satisfied
*/
create_user_async(
username: string,
fullname: string,
accounttype: UserAccountType | null,
cancellable: Gio.Cancellable | null,
callback: Gio.AsyncReadyCallback<this> | null,
): void;
/**
* Asynchronously creates a user account on the system.
*
* For more details, see act_user_manager_create_user(), which
* is the synchronous version of this call.
* @param username a unix user name
* @param fullname a unix GECOS value
* @param accounttype a #ActUserAccountType
* @param cancellable optional #GCancellable object, %NULL to ignore
* @param callback a #GAsyncReadyCallback to call when the request is satisfied
*/
create_user_async(
username: string,
fullname: string,
accounttype: UserAccountType | null,
cancellable?: Gio.Cancellable | null,
callback?: Gio.AsyncReadyCallback<this> | null,
): globalThis.Promise<User> | void;
/**
* Finishes an asynchronous user creation.
*
* See act_user_manager_create_user_async().
* @param result a #GAsyncResult
* @returns user object
*/
create_user_finish(result: Gio.AsyncResult): User;
/**
* Deletes a user account on the system.
* @param user an #ActUser object
* @param remove_files %TRUE to delete the users home directory
* @returns %TRUE if the user account was successfully deleted
*/
delete_user(user: User, remove_files: boolean): boolean;
/**
* Asynchronously deletes a user account from the system.
*
* For more details, see act_user_manager_delete_user(), which
* is the synchronous version of this call.
* @param user a #ActUser object
* @param remove_files %TRUE to delete the users home directory
* @param cancellable optional #GCancellable object, %NULL to ignore
*/
delete_user_async(
user: User,
remove_files: boolean,
cancellable?: Gio.Cancellable | null,
): globalThis.Promise<boolean>;
/**
* Asynchronously deletes a user account from the system.
*
* For more details, see act_user_manager_delete_user(), which
* is the synchronous version of this call.
* @param user a #ActUser object
* @param remove_files %TRUE to delete the users home directory
* @param cancellable optional #GCancellable object, %NULL to ignore
* @param callback a #GAsyncReadyCallback to call when the request is satisfied
*/
delete_user_async(
user: User,
remove_files: boolean,
cancellable: Gio.Cancellable | null,
callback: Gio.AsyncReadyCallback<this> | null,
): void;
/**
* Asynchronously deletes a user account from the system.
*
* For more details, see act_user_manager_delete_user(), which
* is the synchronous version of this call.
* @param user a #ActUser object
* @param remove_files %TRUE to delete the users home directory
* @param cancellable optional #GCancellable object, %NULL to ignore
* @param callback a #GAsyncReadyCallback to call when the request is satisfied
*/
delete_user_async(
user: User,
remove_files: boolean,
cancellable?: Gio.Cancellable | null,
callback?: Gio.AsyncReadyCallback<this> | null,
): globalThis.Promise<boolean> | void;
/**
* Finishes an asynchronous user account deletion.
*
* See act_user_manager_delete_user_async().
* @param result a #GAsyncResult
* @returns %TRUE if the user account was successfully deleted
*/
delete_user_finish(result: Gio.AsyncResult): boolean;
/**
* Retrieves a pointer to the #ActUser object for the login `username`
* from `manager`. Trying to use this object before its
* #ActUser:is-loaded property is %TRUE will result in undefined
* behavior.
* @param username the login name of the user to get.
* @returns #ActUser object
*/
get_user(username: string): User;
/**
* Retrieves a pointer to the #ActUser object for the user with the
* given uid from `manager`. Trying to use this object before its
* #ActUser:is-loaded property is %TRUE will result in undefined
* behavior.
* @param id the uid of the user to get.
* @returns #ActUser object
*/
get_user_by_id(id: number): User;
/**
* Switch the display to the login manager.
* @returns whether successful or not
*/
goto_login_session(): boolean;
/**
* Get a list of system user accounts
* @returns List of #ActUser objects
*/
list_users(): User[];
/**
* Check whether or not the accounts service is running.
* @returns whether or not accounts service is running
*/
no_service(): boolean;
/**
* Releases all metadata about a user account, including icon,
* language and session. If the user account is from a remote
* server and the user has never logged in before, then that
* account will no longer show up in ListCachedUsers() output.
* @param username a user name
* @returns %TRUE if successful, otherwise %FALSE
*/
uncache_user(username: string): boolean;
uncache_user_async(username: string, cancellable?: Gio.Cancellable | null): globalThis.Promise<boolean>;
uncache_user_async(
username: string,
cancellable: Gio.Cancellable | null,
callback: Gio.AsyncReadyCallback<this> | null,
): void;
uncache_user_async(
username: string,
cancellable?: Gio.Cancellable | null,
callback?: Gio.AsyncReadyCallback<this> | null,
): globalThis.Promise<boolean> | void;
/**
* Finishes an asynchronous user uncaching.
*
* See act_user_manager_uncache_user_async().
* @param result a #GAsyncResult
* @returns %TRUE if the user account was successfully uncached
*/
uncache_user_finish(result: Gio.AsyncResult): boolean;
}
type UserClass = typeof User;
type UserManagerClass = typeof UserManager;
/**
* Name of the imported GIR library
* `see` https://gitlab.gnome.org/GNOME/gjs/-/blob/master/gi/ns.cpp#L188
*/
const __name__: string;
/**
* Version of the imported GIR library
* `see` https://gitlab.gnome.org/GNOME/gjs/-/blob/master/gi/ns.cpp#L189
*/
const __version__: string;
}
export default AccountsService;
// END
@@ -0,0 +1,5 @@
// @ts-expect-error
import AccountsService from 'gi://AccountsService?version=1.0';
export default AccountsService;
+15
View File
@@ -0,0 +1,15 @@
/**
* Type Definitions for Gjs (https://gjs.guide/)
*
* These type definitions are automatically generated, do not edit them by hand.
* If you found a bug fix it in `ts-for-gir` or create a bug report on https://github.com/gjsify/ts-for-gir
*
* This template is used to generate the index.d.ts file of each GIR module like Gtk-4.0, GObject-2.0, ...
*/
import './accountsservice-1.0-ambient.d.ts';
import './accountsservice-1.0-import.d.ts';
import AccountsService from './accountsservice-1.0.js';
export default AccountsService;
+5
View File
@@ -0,0 +1,5 @@
// @ts-expect-error
import AccountsService from './accountsservice-1.0.js';
export default AccountsService;
@@ -0,0 +1,85 @@
# cairo-1.0
![version](https://img.shields.io/npm/v/@girs/cairo-1.0)
![downloads/week](https://img.shields.io/npm/dw/@girs/cairo-1.0)
GJS TypeScript type definitions for cairo-1.0, generated from library version 1.0.0 using [ts-for-gir](https://github.com/gjsify/ts-for-gir) v4.0.0-beta.38.
## Install
To use this type definitions, install them with NPM:
```bash
npm install @girs/cairo-1.0
```
## Usage
You can import this package into your project like this:
```ts
import cairo from '@girs/cairo-1.0';
```
### Ambient Modules
You can also use [ambient modules](https://github.com/gjsify/ts-for-gir/tree/main/packages/cli#ambient-modules) to import this module like you would do this in JavaScript.
For this you need to include `@girs/cairo-1.0` or `@girs/cairo-1.0/ambient` in your `tsconfig` or entry point Typescript file:
`index.ts`:
```ts
import '@girs/cairo-1.0'
```
`tsconfig.json`:
```json
{
"compilerOptions": {
...
},
"include": ["@girs/cairo-1.0"],
...
}
```
Now you can import the ambient module with TypeScript support:
```ts
import cairo from 'gi://cairo?version=1.0';
```
### Global import
You can also import the module with Typescript support using the global `imports.gi` object of GJS.
For this you need to include `@girs/cairo-1.0` or `@girs/cairo-1.0/import` in your `tsconfig` or entry point Typescript file:
`index.ts`:
```ts
import '@girs/cairo-1.0'
```
`tsconfig.json`:
```json
{
"compilerOptions": {
...
},
"include": ["@girs/cairo-1.0"],
...
}
```
Now you have also type support for this, too:
```ts
const cairo = imports.gi.cairo;
```
### Bundle
Depending on your project configuration, it is recommended to use a bundler like [esbuild](https://esbuild.github.io/). You can find examples using different bundlers [here](https://github.com/gjsify/ts-for-gir/tree/main/examples).
## Other packages
All existing pre-generated packages can be found on [gjsify/types](https://github.com/gjsify/types).
@@ -0,0 +1,9 @@
declare module 'gi://cairo?version=1.0' {
import Cairo10 from '@girs/cairo-1.0';
export default Cairo10;
}
declare module 'gi://cairo' {
import Cairo10 from 'gi://cairo?version=1.0';
export default Cairo10;
}
@@ -0,0 +1,2 @@
export {}
@@ -0,0 +1,9 @@
import type Cairo10 from '@girs/cairo-1.0';
declare global {
export interface GjsGiImports {
cairo: typeof Cairo10;
}
}
export default GjsGiImports;
@@ -0,0 +1,3 @@
const gi = globalThis.imports?.gi || {};
export default gi;
@@ -0,0 +1,529 @@
/**
* Type Definitions for Gjs (https://gjs.guide/)
*
* These type definitions are automatically generated, do not edit them by hand.
* If you found a bug fix it in `ts-for-gir` or create a bug report on https://github.com/gjsify/ts-for-gir
*
* The based EJS template file is used for the generated .d.ts file of each GIR module like Gtk-4.0, GObject-2.0, ...
*/
import '@girs/gjs';
// Module dependencies
import type GObject from '@girs/gobject-2.0';
import type GLib from '@girs/glib-2.0';
export namespace cairo {
/**
* cairo-1.0
*/
export namespace Status {
export const $gtype: GObject.GType<Status>;
}
enum Status {
SUCCESS,
NO_MEMORY,
INVALID_RESTORE,
INVALID_POP_GROUP,
NO_CURRENT_POINT,
INVALID_MATRIX,
INVALID_STATUS,
NULL_POINTER,
INVALID_STRING,
INVALID_PATH_DATA,
READ_ERROR,
WRITE_ERROR,
SURFACE_FINISHED,
SURFACE_TYPE_MISMATCH,
PATTERN_TYPE_MISMATCH,
INVALID_CONTENT,
INVALID_FORMAT,
INVALID_VISUAL,
FILE_NOT_FOUND,
INVALID_DASH,
INVALID_DSC_COMMENT,
INVALID_INDEX,
CLIP_NOT_REPRESENTABLE,
TEMP_FILE_ERROR,
INVALID_STRIDE,
FONT_TYPE_MISMATCH,
USER_FONT_IMMUTABLE,
USER_FONT_ERROR,
NEGATIVE_COUNT,
INVALID_CLUSTERS,
INVALID_SLANT,
INVALID_WEIGHT,
INVALID_SIZE,
USER_FONT_NOT_IMPLEMENTED,
DEVICE_TYPE_MISMATCH,
DEVICE_ERROR,
INVALID_MESH_CONSTRUCTION,
DEVICE_FINISHED,
JBIG2_GLOBAL_MISSING,
}
export namespace Content {
export const $gtype: GObject.GType<Content>;
}
enum Content {
COLOR,
ALPHA,
COLOR_ALPHA,
}
export namespace Operator {
export const $gtype: GObject.GType<Operator>;
}
enum Operator {
CLEAR,
SOURCE,
OVER,
IN,
OUT,
ATOP,
DEST,
DEST_OVER,
DEST_IN,
DEST_OUT,
DEST_ATOP,
XOR,
ADD,
SATURATE,
MULTIPLY,
SCREEN,
OVERLAY,
DARKEN,
LIGHTEN,
COLOR_DODGE,
COLOR_BURN,
HARD_LIGHT,
SOFT_LIGHT,
DIFFERENCE,
EXCLUSION,
HSL_HUE,
HSL_SATURATION,
HSL_COLOR,
HSL_LUMINOSITY,
}
export namespace Antialias {
export const $gtype: GObject.GType<Antialias>;
}
enum Antialias {
DEFAULT,
NONE,
GRAY,
SUBPIXEL,
FAST,
GOOD,
BEST,
}
export namespace FillRule {
export const $gtype: GObject.GType<FillRule>;
}
enum FillRule {
WINDING,
EVEN_ODD,
}
export namespace LineCap {
export const $gtype: GObject.GType<LineCap>;
}
enum LineCap {
BUTT,
ROUND,
SQUARE,
}
export namespace LineJoin {
export const $gtype: GObject.GType<LineJoin>;
}
enum LineJoin {
MITER,
ROUND,
BEVEL,
}
export namespace TextClusterFlags {
export const $gtype: GObject.GType<TextClusterFlags>;
}
enum TextClusterFlags {
BACKWARD,
}
export namespace FontSlant {
export const $gtype: GObject.GType<FontSlant>;
}
enum FontSlant {
NORMAL,
ITALIC,
OBLIQUE,
}
export namespace FontWeight {
export const $gtype: GObject.GType<FontWeight>;
}
enum FontWeight {
NORMAL,
BOLD,
}
export namespace SubpixelOrder {
export const $gtype: GObject.GType<SubpixelOrder>;
}
enum SubpixelOrder {
DEFAULT,
RGB,
BGR,
VRGB,
VBGR,
}
export namespace HintStyle {
export const $gtype: GObject.GType<HintStyle>;
}
enum HintStyle {
DEFAULT,
NONE,
SLIGHT,
MEDIUM,
FULL,
}
export namespace HintMetrics {
export const $gtype: GObject.GType<HintMetrics>;
}
enum HintMetrics {
DEFAULT,
OFF,
ON,
}
export namespace FontType {
export const $gtype: GObject.GType<FontType>;
}
enum FontType {
TOY,
FT,
WIN32,
QUARTZ,
USER,
}
export namespace PathDataType {
export const $gtype: GObject.GType<PathDataType>;
}
enum PathDataType {
MOVE_TO,
LINE_TO,
CURVE_TO,
CLOSE_PATH,
}
export namespace DeviceType {
export const $gtype: GObject.GType<DeviceType>;
}
enum DeviceType {
DRM,
GL,
SCRIPT,
XCB,
XLIB,
XML,
COGL,
WIN32,
INVALID,
}
export namespace SurfaceType {
export const $gtype: GObject.GType<SurfaceType>;
}
enum SurfaceType {
IMAGE,
PDF,
PS,
XLIB,
XCB,
GLITZ,
QUARTZ,
WIN32,
BEOS,
DIRECTFB,
SVG,
OS2,
WIN32_PRINTING,
QUARTZ_IMAGE,
SCRIPT,
QT,
RECORDING,
VG,
GL,
DRM,
TEE,
XML,
SKIA,
SUBSURFACE,
COGL,
}
export namespace Format {
export const $gtype: GObject.GType<Format>;
}
enum Format {
INVALID,
ARGB32,
RGB24,
A8,
A1,
RGB16_565,
RGB30,
}
export namespace PatternType {
export const $gtype: GObject.GType<PatternType>;
}
enum PatternType {
SOLID,
SURFACE,
LINEAR,
RADIAL,
MESH,
RASTER_SOURCE,
}
export namespace Extend {
export const $gtype: GObject.GType<Extend>;
}
enum Extend {
NONE,
REPEAT,
REFLECT,
PAD,
}
export namespace Filter {
export const $gtype: GObject.GType<Filter>;
}
enum Filter {
FAST,
GOOD,
BEST,
NEAREST,
BILINEAR,
GAUSSIAN,
}
export namespace RegionOverlap {
export const $gtype: GObject.GType<RegionOverlap>;
}
enum RegionOverlap {
IN,
OUT,
PART,
}
function image_surface_create(): void;
class Context {
static $gtype: GObject.GType<Context>;
// Constructors
_init(...args: any[]): void;
}
class Device {
static $gtype: GObject.GType<Device>;
// Constructors
_init(...args: any[]): void;
}
class Surface {
static $gtype: GObject.GType<Surface>;
// Constructors
_init(...args: any[]): void;
}
class Matrix {
static $gtype: GObject.GType<Matrix>;
// Constructors
_init(...args: any[]): void;
}
class Pattern {
static $gtype: GObject.GType<Pattern>;
// Constructors
_init(...args: any[]): void;
}
class Region {
static $gtype: GObject.GType<Region>;
// Constructors
_init(...args: any[]): void;
}
class FontOptions {
static $gtype: GObject.GType<FontOptions>;
// Constructors
_init(...args: any[]): void;
}
class FontFace {
static $gtype: GObject.GType<FontFace>;
// Constructors
_init(...args: any[]): void;
}
class ScaledFont {
static $gtype: GObject.GType<ScaledFont>;
// Constructors
_init(...args: any[]): void;
}
class Path {
static $gtype: GObject.GType<Path>;
// Constructors
_init(...args: any[]): void;
}
class Rectangle {
static $gtype: GObject.GType<Rectangle>;
// Fields
x: number;
y: number;
width: number;
height: number;
// Constructors
constructor(
properties?: Partial<{
x: number;
y: number;
width: number;
height: number;
}>,
);
_init(...args: any[]): void;
}
class RectangleInt {
static $gtype: GObject.GType<RectangleInt>;
// Fields
x: number;
y: number;
width: number;
height: number;
// Constructors
constructor(
properties?: Partial<{
x: number;
y: number;
width: number;
height: number;
}>,
);
_init(...args: any[]): void;
}
class Glyph {
static $gtype: GObject.GType<Glyph>;
// Fields
index: number;
x: number;
y: number;
// Constructors
constructor(
properties?: Partial<{
index: number;
x: number;
y: number;
}>,
);
_init(...args: any[]): void;
}
class TextCluster {
static $gtype: GObject.GType<TextCluster>;
// Fields
num_bytes: number;
num_glyphs: number;
// Constructors
constructor(
properties?: Partial<{
num_bytes: number;
num_glyphs: number;
}>,
);
_init(...args: any[]): void;
}
/**
* Name of the imported GIR library
* `see` https://gitlab.gnome.org/GNOME/gjs/-/blob/master/gi/ns.cpp#L188
*/
const __name__: string;
/**
* Version of the imported GIR library
* `see` https://gitlab.gnome.org/GNOME/gjs/-/blob/master/gi/ns.cpp#L189
*/
const __version__: string;
}
export default cairo;
// END
@@ -0,0 +1,5 @@
// @ts-expect-error
import cairo from 'gi://cairo?version=1.0';
export default cairo;
@@ -0,0 +1,15 @@
/**
* Type Definitions for Gjs (https://gjs.guide/)
*
* These type definitions are automatically generated, do not edit them by hand.
* If you found a bug fix it in `ts-for-gir` or create a bug report on https://github.com/gjsify/ts-for-gir
*
* This template is used to generate the index.d.ts file of each GIR module like Gtk-4.0, GObject-2.0, ...
*/
import './cairo-1.0-ambient.d.ts';
import './cairo-1.0-import.d.ts';
import cairo from './cairo-1.0.js';
export default cairo;
@@ -0,0 +1,5 @@
// @ts-expect-error
import cairo from './cairo-1.0.js';
export default cairo;
@@ -0,0 +1,53 @@
{
"name": "@girs/cairo-1.0",
"version": "1.0.0-4.0.0-beta.38",
"description": "GJS TypeScript type definitions for cairo-1.0, generated from library version 1.0.0",
"type": "module",
"module": "cairo-1.0.js",
"main": "cairo-1.0.js",
"exports": {
"./ambient": {
"types": "./cairo-1.0-ambient.d.ts",
"import": "./cairo-1.0-ambient.js",
"default": "./cairo-1.0-ambient.js"
},
"./import": {
"types": "./cairo-1.0-import.d.ts",
"import": "./cairo-1.0-import.js",
"default": "./cairo-1.0-import.js"
},
"./cairo-1.0": {
"types": "./cairo-1.0.d.ts",
"import": "./cairo-1.0.js",
"default": "./cairo-1.0.js"
},
".": {
"types": "./index.d.ts",
"import": "./index.js",
"default": "./index.js"
}
},
"scripts": {
"test": "tsc --project tsconfig.json"
},
"dependencies": {
"@girs/gjs": "4.0.0-beta.38",
"@girs/gobject-2.0": "2.86.0-4.0.0-beta.38",
"@girs/glib-2.0": "2.86.0-4.0.0-beta.38" },
"devDependencies": {
"typescript": "*"
},
"keywords": ["Gir", "TypeScript", "types", "GObject-Introspection", "GJS", "cairo-1.0"],
"author": "ts-for-gir",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/gjsify/types.git"
},
"bugs": {
"url": "https://github.com/gjsify/ts-for-gir/issues"
},
"homepage": "https://github.com/gjsify/types/tree/main/cairo-1.0#readme"
}
@@ -0,0 +1,25 @@
{
"compilerOptions": {
// General settings for code interpretation
"target": "ESNext",
"module": "NodeNext",
"lib": ["ESNext"],
"types": [],
"experimentalDecorators": true,
"moduleResolution": "NodeNext",
"noEmit": true,
"noEmitOnError": false,
"baseUrl": "./",
"rootDir": ".",
// General settings for code generation
"removeComments": false,
"inlineSourceMap": false,
"inlineSources": false,
"newLine": "LF",
// Show diagnostics
"diagnostics": true
},
"include": ["./cairo-1.0.d.ts"]
}
@@ -0,0 +1,7 @@
{
"entryPoints": ["./cairo-1.0.d.ts"],
"readme": "./README.md",
"name": "cairo-1.0",
"tsconfig": "./tsconfig.json"
}
@@ -0,0 +1,85 @@
# Gio-2.0
![version](https://img.shields.io/npm/v/@girs/gio-2.0)
![downloads/week](https://img.shields.io/npm/dw/@girs/gio-2.0)
GJS TypeScript type definitions for Gio-2.0, generated from library version 2.86.0 using [ts-for-gir](https://github.com/gjsify/ts-for-gir) v4.0.0-beta.38.
## Install
To use this type definitions, install them with NPM:
```bash
npm install @girs/gio-2.0
```
## Usage
You can import this package into your project like this:
```ts
import Gio from '@girs/gio-2.0';
```
### Ambient Modules
You can also use [ambient modules](https://github.com/gjsify/ts-for-gir/tree/main/packages/cli#ambient-modules) to import this module like you would do this in JavaScript.
For this you need to include `@girs/gio-2.0` or `@girs/gio-2.0/ambient` in your `tsconfig` or entry point Typescript file:
`index.ts`:
```ts
import '@girs/gio-2.0'
```
`tsconfig.json`:
```json
{
"compilerOptions": {
...
},
"include": ["@girs/gio-2.0"],
...
}
```
Now you can import the ambient module with TypeScript support:
```ts
import Gio from 'gi://Gio?version=2.0';
```
### Global import
You can also import the module with Typescript support using the global `imports.gi` object of GJS.
For this you need to include `@girs/gio-2.0` or `@girs/gio-2.0/import` in your `tsconfig` or entry point Typescript file:
`index.ts`:
```ts
import '@girs/gio-2.0'
```
`tsconfig.json`:
```json
{
"compilerOptions": {
...
},
"include": ["@girs/gio-2.0"],
...
}
```
Now you have also type support for this, too:
```ts
const Gio = imports.gi.Gio;
```
### Bundle
Depending on your project configuration, it is recommended to use a bundler like [esbuild](https://esbuild.github.io/). You can find examples using different bundlers [here](https://github.com/gjsify/ts-for-gir/tree/main/examples).
## Other packages
All existing pre-generated packages can be found on [gjsify/types](https://github.com/gjsify/types).
@@ -0,0 +1,9 @@
declare module 'gi://Gio?version=2.0' {
import Gio20 from '@girs/gio-2.0';
export default Gio20;
}
declare module 'gi://Gio' {
import Gio20 from 'gi://Gio?version=2.0';
export default Gio20;
}
@@ -0,0 +1,2 @@
export {}
@@ -0,0 +1,9 @@
import type Gio20 from '@girs/gio-2.0';
declare global {
export interface GjsGiImports {
Gio: typeof Gio20;
}
}
export default GjsGiImports;
@@ -0,0 +1,3 @@
const gi = globalThis.imports?.gi || {};
export default gi;
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,5 @@
// @ts-expect-error
import Gio from 'gi://Gio?version=2.0';
export default Gio;
@@ -0,0 +1,15 @@
/**
* Type Definitions for Gjs (https://gjs.guide/)
*
* These type definitions are automatically generated, do not edit them by hand.
* If you found a bug fix it in `ts-for-gir` or create a bug report on https://github.com/gjsify/ts-for-gir
*
* This template is used to generate the index.d.ts file of each GIR module like Gtk-4.0, GObject-2.0, ...
*/
import './gio-2.0-ambient.d.ts';
import './gio-2.0-import.d.ts';
import Gio from './gio-2.0.js';
export default Gio;
@@ -0,0 +1,5 @@
// @ts-expect-error
import Gio from './gio-2.0.js';
export default Gio;
@@ -0,0 +1,54 @@
{
"name": "@girs/gio-2.0",
"version": "2.86.0-4.0.0-beta.38",
"description": "GJS TypeScript type definitions for Gio-2.0, generated from library version 2.86.0",
"type": "module",
"module": "gio-2.0.js",
"main": "gio-2.0.js",
"exports": {
"./ambient": {
"types": "./gio-2.0-ambient.d.ts",
"import": "./gio-2.0-ambient.js",
"default": "./gio-2.0-ambient.js"
},
"./import": {
"types": "./gio-2.0-import.d.ts",
"import": "./gio-2.0-import.js",
"default": "./gio-2.0-import.js"
},
"./gio-2.0": {
"types": "./gio-2.0.d.ts",
"import": "./gio-2.0.js",
"default": "./gio-2.0.js"
},
".": {
"types": "./index.d.ts",
"import": "./index.js",
"default": "./index.js"
}
},
"scripts": {
"test": "tsc --project tsconfig.json"
},
"dependencies": {
"@girs/gjs": "4.0.0-beta.38",
"@girs/gobject-2.0": "2.86.0-4.0.0-beta.38",
"@girs/glib-2.0": "2.86.0-4.0.0-beta.38",
"@girs/gmodule-2.0": "2.0.0-4.0.0-beta.38" },
"devDependencies": {
"typescript": "*"
},
"keywords": ["Gir", "TypeScript", "types", "GObject-Introspection", "GJS", "Gio-2.0"],
"author": "ts-for-gir",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/gjsify/types.git"
},
"bugs": {
"url": "https://github.com/gjsify/ts-for-gir/issues"
},
"homepage": "https://github.com/gjsify/types/tree/main/gio-2.0#readme"
}
@@ -0,0 +1,25 @@
{
"compilerOptions": {
// General settings for code interpretation
"target": "ESNext",
"module": "NodeNext",
"lib": ["ESNext"],
"types": [],
"experimentalDecorators": true,
"moduleResolution": "NodeNext",
"noEmit": true,
"noEmitOnError": false,
"baseUrl": "./",
"rootDir": ".",
// General settings for code generation
"removeComments": false,
"inlineSourceMap": false,
"inlineSources": false,
"newLine": "LF",
// Show diagnostics
"diagnostics": true
},
"include": ["./gio-2.0.d.ts"]
}
@@ -0,0 +1,7 @@
{
"entryPoints": ["./gio-2.0.d.ts"],
"readme": "./README.md",
"name": "Gio-2.0",
"tsconfig": "./tsconfig.json"
}
@@ -0,0 +1,126 @@
# Gjs
![version](https://img.shields.io/npm/v/@girs/gjs)
![downloads/week](https://img.shields.io/npm/dw/@girs/gjs)
GJS TypeScript type definitions for Gjs using [ts-for-gir](https://github.com/gjsify/ts-for-gir) v4.0.0-beta.38.
[GJS](https://gitlab.gnome.org/GNOME/gjs) is a JavaScript runtime for the GNOME ecosystem. Using GJS and the type definitions in this NPM package, you can build GTK applications in JavaScript or TypeScript with type checking, better autocompletion and inline documentations.
## Install
To use this type definitions, install them with NPM:
```bash
npm install @girs/gjs
```
## Usage
You can import this package into your project like this:
```ts
import Gjs from '@girs/gjs';
```
Or if you prefer CommonJS, you can also use this:
```ts
const Gjs = require('@girs/gjs');
```
### Global types
After the import, the global types of GJS are also available:
```ts
import '@girs/gjs';
print('Hello World from print');
const ByteArray = imports.byteArray;
// And so on...
```
### Global DOM types
Some types that conflict with the DOM are outsourced to allow frameworks like Gjsify to rebuild the DOM API without causing type conflicts.
But you can easily import them:
```ts
import '@girs/gjs/dom';
console.log('Hello World from console');
const encoder = new TextEncoder();
const encoded = encoder.encode('𝓽𝓮𝔁𝓽');
setTimeout(() => {
// ...
}, 1000);
// And so on...
```
To avoid a type conflict with the DOM types it is recommended to either modify your `tsconfig.json` or `jsconfig.json` file to exclude the DOM lib, or to enable the `noLib` property.
### Ambient Modules
You can import the built in [ambient modules](https://github.com/gjsify/ts-for-gir/tree/main/packages/cli#ambient-modules) of GJS.
For this you need to include the `@girs/gjs` or `@girs/gjs/ambient` in your `tsconfig` or entry point Typescript file:
`index.ts`:
```ts
import '@girs/gjs'
```
`tsconfig.json`:
```json
{
"compilerOptions": {
...
},
"include": ["@girs/gjs"],
...
}
```
Now you can import `gettext`, `system` and `cairo` in ESM style with Typescript support:
```ts
import gettext from 'gettext';
import system from 'system';
import cairo from 'cairo';
```
### GIR modules
If you want to have types for [GObject Introspection](https://gi.readthedocs.io/en/latest/) modules, you have to add them to your dependencies and import them as well, see the description of these modules, e.g. [gtk-4.0](https://www.npmjs.com/package/@girs/gtk-4.0), [gio-2.0](https://www.npmjs.com/package/@girs/gio-2.0), [adw-1](https://www.npmjs.com/package/@girs/adw-1) and [much more](https://github.com/gjsify/types).
These types will then be available to you:
```ts
import '@girs/gjs'
import '@girs/gjs/dom'
import '@girs/gio-2.0'
import '@girs/gtk-4.0'
import '@girs/adw-1'
import Gio from 'gi://Gio?version=2.0';
import Gtk from 'gi://Gtk?version=4.0';
import Adwaita from 'gi://adw?version=1';
const button = new Gtk.Button();
// ...
```
### Bundle
Depending on your project configuration, it is recommended to use a bundler like [esbuild](https://esbuild.github.io/). You can find examples using different bundlers [here](https://github.com/gjsify/ts-for-gir/tree/main/examples).
## Other packages
All existing pre-generated packages can be found on [gjsify/types](https://github.com/gjsify/types).
@@ -0,0 +1,843 @@
// Cairo 1.0
import Cairo from '@girs/cairo-1.0';
import type GObject from '@girs/gobject-2.0';
declare namespace giCairo {
// Re-export enums directly from Cairo
export import Status = Cairo.Status;
export import Content = Cairo.Content;
export import Operator = Cairo.Operator;
export import Antialias = Cairo.Antialias;
export import FillRule = Cairo.FillRule;
export import LineCap = Cairo.LineCap;
export import LineJoin = Cairo.LineJoin;
export import TextClusterFlags = Cairo.TextClusterFlags;
export import FontSlant = Cairo.FontSlant;
export import FontWeight = Cairo.FontWeight;
export import SubpixelOrder = Cairo.SubpixelOrder;
export import HintStyle = Cairo.HintStyle;
export import HintMetrics = Cairo.HintMetrics;
export import FontType = Cairo.FontType;
export import PathDataType = Cairo.PathDataType;
export import DeviceType = Cairo.DeviceType;
export import SurfaceType = Cairo.SurfaceType;
export import Format = Cairo.Format;
export import PatternType = Cairo.PatternType;
export import Extend = Cairo.Extend;
export import Filter = Cairo.Filter;
export import RegionOverlap = Cairo.RegionOverlap;
/**
* Describes the metrics of a string of text
*/
export interface TextExtents {
/** The horizontal distance from the origin to the leftmost part of the text */
xBearing: number;
/** The vertical distance from the origin to the topmost part of the text */
yBearing: number;
/** The width of the text */
width: number;
/** The height of the text */
height: number;
/** The distance to advance horizontally after drawing the text */
xAdvance: number;
/** The distance to advance vertically after drawing the text */
yAdvance: number;
}
/**
* The main Cairo drawing context
*
* A Cairo context is used to draw to surfaces and perform drawing operations.
* When you're done with a context, you must call $dispose() to free memory.
*/
export class Context extends Cairo.Context {
/**
* Creates a new Cairo context for drawing to the given surface
* @param surface The surface to draw on
*/
constructor(surface: Surface);
/**
* Free a Cairo.Context and all associated memory
*
* Unlike other objects in GJS, Cairo contexts must be explicitly disposed
* to avoid memory leaks.
*/
$dispose(): void;
/**
* Adds a circular arc of the given radius to the current path
* @param xc X coordinate of the center of the arc
* @param yc Y coordinate of the center of the arc
* @param radius Radius of the arc
* @param angle1 Starting angle in radians
* @param angle2 End angle in radians
*/
arc(xc: number, yc: number, radius: number, angle1: number, angle2: number): void;
/**
* Adds a circular arc of the given radius to the current path, but draws
* the arc in the opposite direction from arc()
* @param xc X coordinate of the center of the arc
* @param yc Y coordinate of the center of the arc
* @param radius Radius of the arc
* @param angle1 Starting angle in radians
* @param angle2 End angle in radians
*/
arcNegative(xc: number, yc: number, radius: number, angle1: number, angle2: number): void;
/**
* Adds a cubic Bézier spline to the current path
* @param x1 X coordinate of the first control point
* @param y1 Y coordinate of the first control point
* @param x2 X coordinate of the second control point
* @param y2 Y coordinate of the second control point
* @param x3 X coordinate of the end point
* @param y3 Y coordinate of the end point
*/
curveTo(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number): void;
/**
* Establishes a new clip region by intersecting the current clip region
* with the current path, then clearing the current path
*/
clip(): void;
/**
* Like clip() but preserves the current path
*/
clipPreserve(): void;
/**
* Returns the current clip extents as [x1, y1, x2, y2]
* @returns An array with [x1, y1, x2, y2] clip extents
*/
clipExtents(): [number, number, number, number];
/**
* Closes the current path by drawing a line to the beginning of the current subpath
*/
closePath(): void;
/**
* Emits the current page, but doesn't clear it
*/
copyPage(): void;
/**
* Transforms a coordinate from device space to user space
* @param x X coordinate
* @param y Y coordinate
* @returns An array with [x, y] transformed coordinates
*/
deviceToUser(x: number, y: number): [number, number];
/**
* Transforms a distance vector from device space to user space
* @param x X component of the distance vector
* @param y Y component of the distance vector
* @returns An array with [x, y] transformed distance vector
*/
deviceToUserDistance(x: number, y: number): [number, number];
/**
* Fills the current path using the current fill rule, then clears the path
*/
fill(): void;
/**
* Fills the current path using the current fill rule, but doesn't clear the path
*/
fillPreserve(): void;
/**
* Returns the current fill extents as [x1, y1, x2, y2]
* @returns An array with [x1, y1, x2, y2] fill extents
*/
fillExtents(): [number, number, number, number];
/**
* Gets the current antialiasing mode
* @returns The current antialiasing mode
*/
getAntialias(): Antialias;
/**
* Gets the current point of the current path
* @returns An array with [x, y] coordinates of the current point
*/
getCurrentPoint(): [number, number];
/**
* Gets the current dash count
* @returns The number of elements in the current dash pattern
*/
getDashCount(): number;
/**
* Gets the current fill rule
* @returns The current fill rule
*/
getFillRule(): FillRule;
/**
* Gets the current line cap style
* @returns The current line cap style
*/
getLineCap(): LineCap;
/**
* Gets the current line join style
* @returns The current line join style
*/
getLineJoin(): LineJoin;
/**
* Gets the current line width
* @returns The current line width
*/
getLineWidth(): number;
/**
* Gets the current miter limit
* @returns The current miter limit
*/
getMiterLimit(): number;
/**
* Gets the current compositing operator
* @returns The current compositing operator
*/
getOperator(): Operator;
/**
* Gets the current source pattern
* @returns The current source pattern
*/
getSource(): Pattern;
/**
* Gets the surface the Cairo context is drawing on
* @returns The target surface
*/
getTarget(): Surface;
/**
* Gets the current tolerance value
* @returns The current tolerance value
*/
getTolerance(): number;
/**
* Checks if there is a current point defined
* @returns True if there is a current point
*/
hasCurrentPoint(): boolean;
/**
* Resets the current transformation matrix to the identity matrix
*/
identityMatrix(): void;
/**
* Tests whether the given point is inside the area filled by the current path
* @param x X coordinate of the point to test
* @param y Y coordinate of the point to test
* @returns True if the point is inside the path
*/
inFill(x: number, y: number): boolean;
/**
* Tests whether the given point is inside the area that would be inked
* by the current path with the current line width and stroke parameters
* @param x X coordinate of the point to test
* @param y Y coordinate of the point to test
* @returns True if the point would be inked
*/
inStroke(x: number, y: number): boolean;
/**
* Adds a line to the current path from the current point to the given point
* @param x X coordinate of the end point
* @param y Y coordinate of the end point
*/
lineTo(x: number, y: number): void;
/**
* Sets the current mask pattern used for painting operations
* @param pattern A pattern to use as mask
*/
mask(pattern: Pattern): void;
/**
* Sets the current mask to a surface
* @param surface A surface to use as mask
* @param x X coordinate at which to place the origin of the surface
* @param y Y coordinate at which to place the origin of the surface
*/
maskSurface(surface: Surface, x: number, y: number): void;
/**
* Begins a new subpath at the given point
* @param x X coordinate of the new position
* @param y Y coordinate of the new position
*/
moveTo(x: number, y: number): void;
/**
* Clears the current path and begins a new path
*/
newPath(): void;
/**
* Begins a new subpath without changing the current point
*/
newSubPath(): void;
/**
* Paints the current source everywhere within the current clip region
*/
paint(): void;
/**
* Paints the current source everywhere within the current clip region
* using the given alpha value
* @param alpha Alpha value to use, between 0 and 1
*/
paintWithAlpha(alpha: number): void;
/**
* Returns the current path extents as [x1, y1, x2, y2]
* @returns An array with [x1, y1, x2, y2] path extents
*/
pathExtents(): [number, number, number, number];
/**
* Terminates the current pattern group and returns a new pattern
* representing everything drawn to the group
* @returns A new pattern representing the group
*/
popGroup(): Pattern;
/**
* Terminates the current pattern group and makes it the current source pattern
*/
popGroupToSource(): void;
/**
* Temporarily redirects drawing to an intermediate surface
*/
pushGroup(): void;
/**
* Temporarily redirects drawing to an intermediate surface with the given content
* @param content The content type for the group
*/
pushGroupWithContent(content: Content): void;
/**
* Adds a rectangle to the current path
* @param x X coordinate of the top-left corner
* @param y Y coordinate of the top-left corner
* @param width Width of the rectangle
* @param height Height of the rectangle
*/
rectangle(x: number, y: number, width: number, height: number): void;
/**
* Adds a cubic Bézier spline to the current path using relative coordinates
* @param dx1 X offset to the first control point from current point
* @param dy1 Y offset to the first control point from current point
* @param dx2 X offset to the second control point from current point
* @param dy2 Y offset to the second control point from current point
* @param dx3 X offset to the end point from current point
* @param dy3 Y offset to the end point from current point
*/
relCurveTo(dx1: number, dy1: number, dx2: number, dy2: number, dx3: number, dy3: number): void;
/**
* Adds a line to the current path relative to the current point
* @param dx X offset from the current point
* @param dy Y offset from the current point
*/
relLineTo(dx: number, dy: number): void;
/**
* Begins a new subpath relative to the current point
* @param dx X offset from the current point
* @param dy Y offset from the current point
*/
relMoveTo(dx: number, dy: number): void;
/**
* Resets the current clip region to its original, unrestricted state
*/
resetClip(): void;
/**
* Restores the context state from the stack
*/
restore(): void;
/**
* Rotates the current transformation matrix
* @param angle Angle of rotation in radians
*/
rotate(angle: number): void;
/**
* Saves the current context state to the stack
*/
save(): void;
/**
* Scales the current transformation matrix
* @param sx Scale factor for the X dimension
* @param sy Scale factor for the Y dimension
*/
scale(sx: number, sy: number): void;
/**
* Selects a font face
* @param family A font family name
* @param slant A font slant
* @param weight A font weight
*/
selectFontFace(family: string, slant: number, weight: number): void;
/**
* Sets the antialiasing mode
* @param antialias The new antialiasing mode
*/
setAntialias(antialias: Antialias): void;
/**
* Sets the dash pattern to be used by stroke()
* @param dashes Array of dash lengths
* @param offset Offset into the dash pattern
*/
setDash(dashes: number[], offset: number): void;
/**
* Sets the current font size in user space units
* @param size Font size in user space units
*/
setFontSize(size: number): void;
/**
* Sets the current fill rule
* @param fillRule The new fill rule
*/
setFillRule(fillRule: FillRule): void;
/**
* Sets the current line cap style
* @param lineCap The new line cap style
*/
setLineCap(lineCap: LineCap): void;
/**
* Sets the current line join style
* @param lineJoin The new line join style
*/
setLineJoin(lineJoin: LineJoin): void;
/**
* Sets the current line width
* @param width The new line width
*/
setLineWidth(width: number): void;
/**
* Sets the current miter limit
* @param limit The new miter limit
*/
setMiterLimit(limit: number): void;
/**
* Sets the current compositing operator
* @param op The new compositing operator
*/
setOperator(op: Operator): void;
/**
* Sets the current source pattern
* @param pattern The new source pattern
*/
setSource(pattern: Pattern): void;
/**
* Sets the source pattern to an RGB opaque color
* @param red Red component, between 0 and 1
* @param green Green component, between 0 and 1
* @param blue Blue component, between 0 and 1
*/
setSourceRGB(red: number, green: number, blue: number): void;
/**
* Sets the source pattern to an RGBA color
* @param red Red component, between 0 and 1
* @param green Green component, between 0 and 1
* @param blue Blue component, between 0 and 1
* @param alpha Alpha component, between 0 and 1
*/
setSourceRGBA(red: number, green: number, blue: number, alpha: number): void;
/**
* Sets the source pattern to the given surface
* @param surface The new source surface
* @param x X coordinate where to place the surface origin
* @param y Y coordinate where to place the surface origin
*/
setSourceSurface(surface: Surface, x: number, y: number): void;
/**
* Sets the tolerance used when converting paths to trapezoids
* @param tolerance The new tolerance value
*/
setTolerance(tolerance: number): void;
/**
* Emits the current page and clears it
*/
showPage(): void;
/**
* Draws text at the current position
* @param utf8 A string of text encoded in UTF-8
*/
showText(utf8: string): void;
/**
* Strokes the current path using the current line width, line join,
* line cap, and dash settings, then clears the path
*/
stroke(): void;
/**
* Like stroke() but preserves the current path
*/
strokePreserve(): void;
/**
* Returns the current stroke extents as [x1, y1, x2, y2]
* @returns An array with [x1, y1, x2, y2] stroke extents
*/
strokeExtents(): [number, number, number, number];
/**
* Gets the extents of the given text if it were drawn at the current point
* @param utf8 A string of text encoded in UTF-8
* @returns Text extents information
*/
textExtents(utf8: string): TextExtents;
/**
* Translates the current transformation matrix
* @param tx Translation in the X direction
* @param ty Translation in the Y direction
*/
translate(tx: number, ty: number): void;
/**
* Transforms a coordinate from user space to device space
* @param x X coordinate
* @param y Y coordinate
* @returns An array with [x, y] transformed coordinates
*/
userToDevice(x: number, y: number): [number, number];
/**
* Transforms a distance vector from user space to device space
* @param x X component of the distance vector
* @param y Y component of the distance vector
* @returns An array with [x, y] transformed distance vector
*/
userToDeviceDistance(x: number, y: number): [number, number];
/**
* Creates a copy of the current path and returns it
* @returns A copy of the current path
*/
copyPath(): Path;
/**
* Appends a path to the current path
* @param path A path to append
*/
appendPath(path: Path): void;
}
/**
* Base class for all Cairo surfaces
*/
export abstract class Surface extends Cairo.Surface {
/**
* Gets the device scale of the surface
* @returns An array with [x, y] device scale
*/
getDeviceScale(): [number, number];
/**
* Sets the device scale of the surface
* @param x X scale factor
* @param y Y scale factor
*/
setDeviceScale(x: number, y: number): void;
/**
* Gets the device offset of the surface
* @returns An array with [x, y] device offset
*/
getDeviceOffset(): [number, number];
/**
* Sets the device offset of the surface
* @param x X offset
* @param y Y offset
*/
setDeviceOffset(x: number, y: number): void;
/**
* Performs all pending drawing operations
*/
flush(): void;
/**
* Finishes the surface and drops all references to external resources
*/
finish(): void;
}
/**
* A surface that uses in-memory image data buffers
*/
export class ImageSurface extends Surface {
/**
* Creates a new image surface
* @param format The format of pixels in the surface
* @param width Width of the surface in pixels
* @param height Height of the surface in pixels
*/
constructor(format: Format, width: number, height: number);
/**
* Creates a new image surface from a PNG file
* @param filename Path to a PNG file
* @returns A new image surface
*/
static createFromPNG(filename: string): ImageSurface;
/**
* Gets the format of the surface
* @returns The format of the surface
*/
getFormat(): Format;
/**
* Gets the width of the surface in pixels
* @returns The width of the surface
*/
getWidth(): number;
/**
* Gets the height of the surface in pixels
* @returns The height of the surface
*/
getHeight(): number;
/**
* Writes the contents of the surface to a PNG file
* @param filename Path to the PNG file to write
*/
writeToPNG(filename: string): void;
}
/**
* A surface that produces output in the PDF format
*/
export class PDFSurface extends Surface {
/**
* Creates a new PDF surface
* @param filename Path to the PDF file to write to
* @param width Width of the surface in points (1 point = 1/72 inch)
* @param height Height of the surface in points (1 point = 1/72 inch)
*/
constructor(filename: string, width: number, height: number);
}
/**
* A surface that produces output in the PostScript format
*/
export class PSSurface extends Surface {
/**
* Creates a new PostScript surface
* @param filename Path to the PostScript file to write to
* @param width Width of the surface in points (1 point = 1/72 inch)
* @param height Height of the surface in points (1 point = 1/72 inch)
*/
constructor(filename: string, width: number, height: number);
}
/**
* A surface that produces output in the SVG format
*/
export class SVGSurface extends Surface {
/**
* Creates a new SVG surface
* @param filename Path to the SVG file to write to
* @param width Width of the surface in points (1 point = 1/72 inch)
* @param height Height of the surface in points (1 point = 1/72 inch)
*/
constructor(filename: string, width: number, height: number);
}
/**
* Base class for all Cairo patterns
*/
export class Pattern extends Cairo.Pattern {}
/**
* Base class for all gradient patterns
*/
export class Gradient extends Pattern {
/**
* Adds a color stop to the gradient at the given offset
* @param offset Offset position of the stop, between 0 and 1
* @param red Red component, between 0 and 1
* @param green Green component, between 0 and 1
* @param blue Blue component, between 0 and 1
* @param alpha Alpha component, between 0 and 1
*/
addColorStopRGBA(offset: number, red: number, green: number, blue: number, alpha: number): void;
/**
* Adds an opaque color stop to the gradient at the given offset
* @param offset Offset position of the stop, between 0 and 1
* @param red Red component, between 0 and 1
* @param green Green component, between 0 and 1
* @param blue Blue component, between 0 and 1
*/
addColorStopRGB(offset: number, red: number, green: number, blue: number): void;
}
/**
* A pattern for linear gradients
*/
export class LinearGradient extends Gradient {
/**
* Creates a new linear gradient pattern
* @param x0 X coordinate of the start point
* @param y0 Y coordinate of the start point
* @param x1 X coordinate of the end point
* @param y1 Y coordinate of the end point
*/
constructor(x0: number, y0: number, x1: number, y1: number);
}
/**
* A pattern for radial gradients
*/
export class RadialGradient extends Gradient {
/**
* Creates a new radial gradient pattern
* @param cx0 X coordinate of the start circle
* @param cy0 Y coordinate of the start circle
* @param radius0 Radius of the start circle
* @param cx1 X coordinate of the end circle
* @param cy1 Y coordinate of the end circle
* @param radius1 Radius of the end circle
*/
constructor(cx0: number, cy0: number, radius0: number, cx1: number, cy1: number, radius1: number);
}
/**
* A pattern that uses a surface as its source
*/
export class SurfacePattern extends Pattern {
/**
* Creates a new pattern for the given surface
* @param surface The surface to use
*/
constructor(surface: Surface);
}
/**
* A pattern for solid colors
*/
export class SolidPattern extends Pattern {
/**
* Creates a new solid pattern with an opaque color
* @param red Red component, between 0 and 1
* @param green Green component, between 0 and 1
* @param blue Blue component, between 0 and 1
* @returns A new solid pattern
*/
static createRGB(red: number, green: number, blue: number): SolidPattern;
/**
* Creates a new solid pattern with a transparent color
* @param red Red component, between 0 and 1
* @param green Green component, between 0 and 1
* @param blue Blue component, between 0 and 1
* @param alpha Alpha component, between 0 and 1
* @returns A new solid pattern
*/
static createRGBA(red: number, green: number, blue: number, alpha: number): SolidPattern;
}
export class Path extends Cairo.Path {}
/**
* A rectangle
*/
export class Rectangle extends Cairo.Rectangle {}
/**
* A rectangle integer
*/
export class RectangleInt extends Cairo.RectangleInt {}
/**
* A region object used for representing a set of pixels
*/
export class Region extends Cairo.Region {}
/**
* A matrix object used for transforming coordinates
*/
export class Matrix extends Cairo.Matrix {}
/**
* A font face object used for storing and manipulating font faces
*/
export class FontFace extends Cairo.FontFace {}
/**
* A scaled font object used for storing and manipulating scaled fonts
*/
export class ScaledFont extends Cairo.ScaledFont {}
/**
* A glyph object used for storing and manipulating glyphs
*/
export class Glyph extends Cairo.Glyph {}
/**
* A text cluster object used for storing and manipulating text clusters
*/
export class TextCluster extends Cairo.TextCluster {}
/**
* A font options object used for storing and manipulating font options
*/
export class FontOptions extends Cairo.FontOptions {}
/**
* A device object used for storing and manipulating devices
*/
export class Device extends Cairo.Device {}
}
export default giCairo;
@@ -0,0 +1,6 @@
import Cairo from 'cairo';
// cairo doesn't have named exports, see https://gitlab.gnome.org/GNOME/gjs/-/blob/c2a714f348d6848037f072063e0a914fd537c4f4/installed-tests/js/testCairoModule.js#L14
export default Cairo;
@@ -0,0 +1,21 @@
/**
* @param logDomain the GLib log domain this Console should print
* with. Defaults to 'Gjs-Console'.
*/
export function setConsoleLogDomain(logDomain: string): void;
/**
* @param logDomain the GLib log domain this Console should print
* with. Defaults to 'Gjs-Console'.
*/
export function getConsoleLogDomain(): string;
export declare const DEFAULT_LOG_DOMAIN: string;
declare const Console: {
setConsoleLogDomain: typeof setConsoleLogDomain;
getConsoleLogDomain: typeof getConsoleLogDomain;
DEFAULT_LOG_DOMAIN: typeof DEFAULT_LOG_DOMAIN;
};
export default Console;
@@ -0,0 +1,6 @@
import Console, { getConsoleLogDomain, setConsoleLogDomain, DEFAULT_LOG_DOMAIN } from 'console';
export { getConsoleLogDomain, setConsoleLogDomain, DEFAULT_LOG_DOMAIN }
export default Console;
@@ -0,0 +1,304 @@
/**
* Gjs has implemented some functionality from the DOM API,
* this leads to a conflict when all DOM (`lib.dom.d.ts`) should be used.
* This should normally not be the case, since the other - not yet reimplemented - API's cannot be used in GJS anyway.
*
* If for some reason the entire DOM types should still be used,
* this file can be ignored and `lib.dom.d.ts` used instead, otherwise this file should be imported in your project.
*
* See also https://github.com/microsoft/TypeScript/blob/main/lib/lib.dom.d.ts
*/
import type GLib from '@girs/glib-2.0';
import type GObject from '@girs/gobject-2.0';
declare global {
interface ImportMeta {
/**
* The absolute file: or resource: URL of the module.
*
* @see https://gitlab.gnome.org/GNOME/gjs/-/blob/master/doc/ESModules.md#importmetaurl
*/
url: string; // with readonly this type is incompatible with e.g. https://github.com/vitejs/vite/blob/main/packages/vite/types/importMeta.d.ts
}
// Timers
// See https://gitlab.gnome.org/GNOME/gjs/-/blob/master/modules/esm/_timers.js
/**
* @version Gjs 1.71.1
* @param callback a callback function
* @param delay the duration in milliseconds to wait before running callback
* @param args arguments to pass to callback
*/
function setTimeout(callback: (...args: any[]) => any, delay?: number, ...args: any[]): GLib.Source;
/**
* @version Gjs 1.71.1
* @param callback a callback function
* @param delay the duration in milliseconds to wait between calling callback
* @param args arguments to pass to callback
*/
function setInterval(callback: (...args: any[]) => any, delay?: number, ...args: any[]): GLib.Source;
/**
* @version Gjs 1.71.1
* @param timeout the timeout to clear
*/
function clearTimeout(timeout: GLib.Source): void;
/**
* @version Gjs 1.71.1
* @param timeout the timeout to clear
*/
function clearInterval(timeout: GLib.Source): void;
interface Console {
/**
* Logs a critical message if the condition is not truthy.
* {@link console.error()} for additional information.
*
* @param condition a boolean condition which, if false, causes
* the log to print
* @param data formatting substitutions, if applicable
* @returns
*/
assert(condition: boolean, ...data: any[]): void;
/**
* Resets grouping and clears the terminal on systems supporting ANSI
* terminal control sequences.
*
* In file-based stdout or systems which do not support clearing,
* console.clear() has no visual effect.
*
*/
clear(): void;
/**
* Logs a message with severity equal to {@link GLib.LogLevelFlags.DEBUG}.
*
* @param {...any} data formatting substitutions, if applicable
*/
debug(...data: any[]): void;
/**
* Logs a message with severity equal to {@link GLib.LogLevelFlags.CRITICAL}.
* Does not use {@link GLib.LogLevelFlags.ERROR} to avoid asserting and
* forcibly shutting down the application.
*
* @param data formatting substitutions, if applicable
*/
error(...data: any[]): void;
/**
* Logs a message with severity equal to {@link GLib.LogLevelFlags.INFO}.
*
* @param data formatting substitutions, if applicable
*/
info(...data: any[]): void;
/**
* Logs a message with severity equal to {@link GLib.LogLevelFlags.MESSAGE}.
*
* @param data formatting substitutions, if applicable
*/
log(...data: any[]): void;
// 1.1.7 table(tabularData, properties)
table(tabularData: any, _properties: never): void;
/**
* @param data formatting substitutions, if applicable
*/
trace(...data: any[]): void;
/**
* @param data formatting substitutions, if applicable
*/
warn(...data: any[]): void;
/**
* @param item an item to format generically
* @param [options] any additional options for the formatter. Unused
* in our implementation.
*/
dir(item: object, options: never): void;
/**
* @param data formatting substitutions, if applicable
*/
dirxml(...data: any[]): void;
// 1.2 Counting functions
// https://console.spec.whatwg.org/#counting
/**
* Logs how many times console.count(label) has been called with a given
* label.
* {@link console.countReset()} for resetting a count.
*
* @param label unique identifier for this action
*/
count(label: string): void;
/**
* @param label the unique label to reset the count for
*/
countReset(label: string): void;
// 1.3 Grouping functions
// https://console.spec.whatwg.org/#grouping
/**
* @param data formatting substitutions, if applicable
*/
group(...data: any[]): void;
/**
* Alias for console.group()
*
* @param {...any} data formatting substitutions, if applicable
*/
groupCollapsed(...data: any[]): void;
/**
*/
groupEnd(): void;
// 1.4 Timing functions
// https://console.spec.whatwg.org/#timing
/**
* @param label unique identifier for this action, pass to
* console.timeEnd() to complete
*/
time(label: string): void;
/**
* Logs the time since the last call to console.time(label) where label is
* the same.
*
* @param label unique identifier for this action, pass to
* console.timeEnd() to complete
* @param data string substitutions, if applicable
*/
timeLog(label: string, ...data: any[]): void;
/**
* Logs the time since the last call to console.time(label) and completes
* the action.
* Call console.time(label) again to re-measure.
*
* @param label unique identifier for this action
*/
timeEnd(label: string): void;
// Non-standard functions which are de-facto standards.
// Similar to Node, we define these as no-ops for now.
/**
* @deprecated Not implemented in GJS
*
* @param _label unique identifier for this action, pass to
* console.profileEnd to complete
*/
profile(_label: string): void;
/**
* @deprecated Not implemented in GJS
*
* @param _label unique identifier for this action
*/
profileEnd(_label: string): void;
/**
* @deprecated Not implemented in GJS
*
* @param _label unique identifier for this action
*/
timeStamp(_label: string): void;
}
interface TextDecodeOptions {
// As of Gjs 1.73.2 stream mode is not supported yet.
// stream?: boolean
}
interface TextDecoderOptions {
/** Indicates whether the error mode is fatal. */
fatal?: boolean;
/** Indicates whether whether the byte order mark is ignored. */
ignoreBOM?: boolean;
}
/**
* The TextDecoder interface represents a decoder for a specific text encoding.
* It takes a stream of bytes as input and emits a stream of code points.
*
* @version Gjs 1.69.2
*/
interface TextDecoder {
/** A string containing the name of the decoder, that is a string describing the method the TextDecoder will use. */
readonly encoding: TextDecoderEncoding;
/** A Boolean indicating whether the error mode is fatal. */
readonly fatal: boolean;
/** A Boolean indicating whether the byte order mark is ignored. */
readonly ignoreBOM: boolean;
/**
* Returns a string containing the text decoded with the method of the specific TextDecoder object.
*
* If the error mode is "fatal" and the encoder method encounter an error it WILL THROW a TypeError.
*
* @param input Buffer containing the text to decode
* @param options Object defining the decode options
*/
decode(input?: ArrayBufferView | ArrayBuffer, options?: TextDecodeOptions): string;
}
interface TextEncoderEncodeIntoResult {
read?: number;
written?: number;
}
/**
* TextEncoder takes a stream of code points as input and emits a stream of bytes.
*
* @version Gjs 1.69.2
*/
interface TextEncoder {
readonly encoding: 'utf-8';
/**
* Takes a string as input, and returns a buffer containing the text given in parameters encoded with the UTF-8 method.
*
* @param input Text to encode.
*/
encode(input?: string): Uint8Array;
/**
* Takes a string to encode and a destination Uint8Array to put resulting UTF-8 encoded text into,
* and returns a dictionary object indicating the progress of the encoding.
*
* This is potentially more performant than the older encode() method.
*
* @param source Text to encode.
* @param destination Buffer where to place the resulting UTF-8 encoded text into.
*/
encodeInto(source: string, destination: Uint8Array): TextEncoderEncodeIntoResult;
}
const console: Console;
const TextDecoder: {
prototype: TextDecoder;
new (label?: TextDecoderEncoding, options?: TextDecoderOptions): TextDecoder;
};
const TextEncoder: {
prototype: TextEncoder;
new (): TextEncoder;
};
}
export {};
@@ -0,0 +1,3 @@
export {};
@@ -0,0 +1,41 @@
export enum LocaleCategory {
ALL,
COLLATE,
CTYPE,
MESSAGES,
MONETARY,
NUMERIC,
TIME,
}
export function setlocale(category: number, locale: string | null): string;
export function textdomain(domainname: string | null): string;
export function bindtextdomain(domainname: string, dirname: string | null): string;
export function gettext(msgid: string): string;
export function dgettext(domainname: string | null, msgid: string): string;
export function dcgettext(domainname: string | null, msgid: string, category: number): string;
export function ngettext(msgid: string, msgid_plural: string, n: number): string;
export function dngettext(domainname: string, msgid: string, msgid_plural: string, n: number): string;
export function pgettext(context: string, msgid: string): string;
export function dpgettext(dom: string | null, context: string, msgid: string): string;
export function domain(domainName: string): {
gettext: (msgid: string) => string;
ngettext: (msgid: string, msgid_plural: string, n: number) => string;
pgettext: (context: string, msgid: string) => string;
};
declare const Gettext: {
LocaleCategory: typeof LocaleCategory;
setlocale: typeof setlocale;
textdomain: typeof textdomain;
bindtextdomain: typeof bindtextdomain;
gettext: typeof gettext;
dgettext: typeof dgettext;
dcgettext: typeof dcgettext;
ngettext: typeof ngettext;
dngettext: typeof dngettext;
pgettext: typeof pgettext;
dpgettext: typeof dpgettext;
domain: typeof domain;
};
export default Gettext;
@@ -0,0 +1,6 @@
import Gettext, { setlocale, textdomain, bindtextdomain, gettext, dgettext, dcgettext, ngettext, dngettext, pgettext, dpgettext, domain } from 'gettext';
export { setlocale, textdomain, bindtextdomain, gettext, dgettext, dcgettext, ngettext, dngettext, pgettext, dpgettext, domain }
export default Gettext;
@@ -0,0 +1,25 @@
// https://www.typescriptlang.org/docs/handbook/modules.html#ambient-modules
// https://stackoverflow.com/questions/45099605/ambient-declaration-with-an-imported-type-in-typescript
declare module 'gettext' {
export * from '@girs/gjs/gettext';
import Gettext from '@girs/gjs/gettext';
export default Gettext;
}
declare module 'system' {
export * from '@girs/gjs/system';
import System from '@girs/gjs/system';
export default System;
}
declare module 'cairo' {
import Cairo from '@girs/gjs/cairo';
export default Cairo;
}
declare module 'console' {
import Console, { setConsoleLogDomain, getConsoleLogDomain, DEFAULT_LOG_DOMAIN } from '@girs/gjs/console';
export { setConsoleLogDomain, getConsoleLogDomain, DEFAULT_LOG_DOMAIN };
export default Console;
}
@@ -0,0 +1,3 @@
export {};
@@ -0,0 +1,732 @@
/**
* Type Definitions for Gjs (https://gjs.guide/)
*
* These type definitions are automatically generated, do not edit them by hand.
* If you found a bug fix it in ts-for-gir itself or create a bug report on https://github.com/gjsify/ts-for-gir
*/
import type GObject from '@girs/gobject-2.0';
import type GLib from '@girs/glib-2.0';
import gettext from './gettext.js';
import system from './system.js';
import cairo from './cairo.js';
// https://gitlab.gnome.org/GNOME/gjs/-/blob/1.72.0/modules/script/package.js
declare namespace package {
/**
* Although there are references in the documentation of more properties that
* this object should accepts, only the following are actually used in the init code,
* and all the other have their values derived from them.
*/
interface PackageInitParams {
/** The base name of the entry point (eg. org.foo.Bar.App) */
name: string;
/** The version of the package */
version: string;
/** The prefix of the package */
prefix: string;
/**
* The final datadir and libdir when installed;
* usually, these would be prefix + '/share' and
* and prefix + '/lib' (or '/lib64')
*/
libdir: string;
/**
* The final datadir and libdir when installed;
* usually, these would be prefix + '/share' and
* and prefix + '/lib' (or '/lib64')
*/
datadir?: string;
}
/**
* The base name of the entry point (eg. org.foo.Bar.App)
*
* Note: Run `pkg.init()` before accessing this property.
*/
export const name: string;
/**
* The version of the package
*
* Note: Run `pkg.init()` before accessing this property.
*/
export const version: string;
/**
* The prefix of the package
*
* Note: Run `pkg.init()` before accessing this property.
*/
export const prefix: string;
/**
* The final datadir when installed; usually, these would be prefix + '/share'
*
* Note: Run `pkg.init()` before accessing this property.
*/
export const datadir: string;
/**
* The final libdir when installed; usually, these would be prefix + '/lib' (or '/lib64')
*
* Note: Run `pkg.init()` before accessing this property.
*/
export const libdir: string;
/**
* The final pkglibdir when installed; usually, this would be prefix + '/lib' (or '/lib64')
*
* Note: Run `pkg.init()` before accessing this property.
*/
export const pkglibdir: string;
/**
* The final moduledir when installed; usually, this would be prefix + '/lib' (or '/lib64')
*
* Note: Run `pkg.init()` before accessing this property.
*/
export const moduledir: string;
/**
* The directory containing gettext translation files; this will be datadir + '/locale' when installed and './po' in the source tree
*
* Note: Run `pkg.init()` before accessing this property.
*/
export const localedir: string;
/**
* Initialize directories and global variables. Must be called
* before any of other API in Package is used.
* `params` must be an object with at least the following keys:
* - name: the package name ($(PACKAGE_NAME) in autotools,
* eg. org.foo.Bar)
* - version: the package version
* - prefix: the installation prefix
*
* init() will take care to check if the program is running from
* the source directory or not, by looking for a 'src' directory.
*
* At the end, the global variable 'pkg' will contain the
* Package module (imports.package). Additionally, the following
* module variables will be available:
* - name: the base name of the entry point (eg. org.foo.Bar.App)
* - version: same as in @params
* - prefix: the installation prefix (as passed in @params)
* - datadir, libdir: the final datadir and libdir when installed;
* usually, these would be prefix + '/share' and
* and prefix + '/lib' (or '/lib64')
* - pkgdatadir: the directory to look for private data files, such as
* images, stylesheets and UI definitions;
* this will be datadir + name when installed and
* './data' when running from the source tree
* - pkglibdir: the directory to look for private typelibs and C
* libraries;
* this will be libdir + name when installed and
* './lib' when running from the source tree
* - moduledir: the directory to look for JS modules;
* this will be pkglibdir when installed and
* './src' when running from the source tree
* - localedir: the directory containing gettext translation files;
* this will be datadir + '/locale' when installed
* and './po' in the source tree
*
* All paths are absolute and will not end with '/'.
*
* As a side effect, init() calls GLib.set_prgname().
*
* @param {object} params package parameters
*/
export function init(params: PackageInitParams): void;
/**
* This is the function to use if you want to have multiple
* entry points in one package.
* You must define a main(ARGV) function inside the passed
* in module, and then the launcher would be
*
* imports.package.init(...);
* imports.package.run(imports.entrypoint);
*
* @param module the module to run
* @returns the exit code of the module's main() function
*/
export function run(module: { main: (argv: string[]) => void }): number | undefined;
/**
* This is a convenience function if your package has a
* single entry point.
* You must define a main(ARGV) function inside a main.js
* module in moduledir.
*
* @param params see init()
*/
export function start(params: PackageInitParams): void;
/**
* Mark a dependency on a specific version of one or more
* external GI typelibs.
* `libs` must be an object whose keys are a typelib name,
* and values are the respective version. The empty string
* indicates any version.
* @param deps The external dependencies to import
*/
export function require(deps: Record<string, string>): void;
/**
* As checkSymbol(), but exit with an error if the
* dependency cannot be satisfied.
*
* @param lib an external dependency to import
* @param ver version of the dependency
* @param symbol symbol to check for
*/
export function requireSymbol(lib: string, ver?: string, symbol?: string): void;
/**
* Check whether an external GI typelib can be imported
* and provides @symbol.
*
* Symbols may refer to
* - global functions ('main_quit')
* - classes ('Window')
* - class / instance methods ('IconTheme.get_default' / 'IconTheme.has_icon')
* - GObject properties ('Window.default_height')
*
* @param lib an external dependency to import
* @param ver version of the dependency
* @param symbol symbol to check for
* @returns true if `lib` can be imported and provides `symbol`, false
* otherwise
*/
export function checkSymbol(lib: string, ver: string, symbol: string): boolean;
/**
* Initialize `gettext`.
* After calling this method `globalThis._`, `globalThis.C_` and `globalThis.N_` will be available.
*/
export function initGettext(): void;
/**
* Initializes string formatting capabilities by adding a format() method to String.prototype.
*
* After calling this method, you can use a printf-style string formatting by calling
* the format() method on any string:
*
* @example
* ```ts
* pkg.initFormat();
*
* // Now you can use format() on any string
* const name = "User";
* const count = 5;
* const formatted = "Hello %s, you have %d items".format(name, count);
* // formatted = "Hello User, you have 5 items"
*
* // Format numbers with precision
* const price = 10.5;
* const priceStr = "Price: $%.2f".format(price);
* // priceStr = "Price: $10.50"
*
* // Pad with zeros
* const id = 42;
* const idStr = "ID: %05d".format(id);
* // idStr = "ID: 00042"
* ```
*/
export function initFormat(): void;
/**
* As checkSymbol(), but exit with an error if the
* dependency cannot be satisfied.
*
* @param lib an external dependency to import
* @param ver version of the dependency
* @param symbol symbol to check for
*/
export function initSubmodule(lib: string, ver?: string, symbol?: string): void;
/**
* Load and register a GResource named @name. @name is optional and defaults to ${package-name}
* @param name The name of the GResource to load
*/
export function loadResource(name?: string): void;
}
declare namespace byteArray {
export class ByteArray {
static get(target: any, property: string, receiver: any): any;
static set(target: any, property: string, value: any, receiver: any): boolean;
length: number;
protected _array: Uint8Array;
constructor(x: Uint8Array | number);
toString(encoding?: TextDecoderEncoding): string;
fromString(input: string, encoding?: TextDecoderEncoding): ByteArray;
toGBytes(): GLib.Bytes;
}
/** @deprecated Use {@link TextEncoder.encode} instead */
export function fromString(input: string, encoding?: TextDecoderEncoding): Uint8Array;
/** @deprecated Use {@link GLib.Bytes.toArray} instead */
export function fromGBytes(input: GLib.Bytes): Uint8Array;
/** @deprecated Use {@link TextDecoder.decode} instead */
export function toString(x: Uint8Array, encoding?: TextDecoderEncoding): string;
/** @deprecated Use {@link GLib.Bytes new GLib.Bytes() } instead */
export function toGBytes(x: Uint8Array): GLib.Bytes;
/** @deprecated Use {@link ByteArray new ByteArray()} instead */
export function fromArray(array: Iterable<number>): ByteArray;
}
declare namespace lang {
// TODO: There is a lot more in Lang
export function Class(props: any): void;
}
declare namespace format {
/**
* Formats a string using printf-style format specifiers.
*
* @param str The format string
* @param args The arguments to be formatted
* @returns The formatted string
*/
export function vprintf(str: string, args: (string | number | boolean | null | undefined)[]): string;
/**
* Prints a formatted string to the console.
* Similar to C's printf function.
*
* @param fmt The format string
* @param args The arguments to be formatted
*/
export function printf(fmt: string, ...args: (string | number | boolean | null | undefined)[]): void;
/**
* Formats a string with the given arguments.
* This is the implementation that backs String.prototype.format
* when pkg.initFormat() is called.
*
* Supported format specifiers:
* - %s: Formats as a string
* - %d: Formats as an integer
* - %x: Formats as a hexadecimal number
* - %f: Formats as a floating point number, optionally with precision (e.g. %.2f)
*
* All specifiers can be prefixed with a minimum field width, e.g. "%5s" will pad with spaces.
* If the width is prefixed with '0', it will pad with zeroes instead of spaces.
*
* @example
* ```ts
* format.format("Hello %s, you have %d items", "User", 5);
* // Returns: "Hello User, you have 5 items"
* ```
*
* @param fmt The format string
* @param args The arguments to format the string with
* @returns The formatted string
*/
export function format(fmt: string, ...args: (string | number | boolean | null | undefined)[]): string;
}
declare namespace mainloop {
export function quit(name: string): void;
export function idle_source(handler: any, priority?: number): any;
export function idle_add(handler: any, priority?: number): any;
export function timeout_source(timeout: any, handler: any, priority?: number): any;
export function timeout_seconds_source(timeout: any, handler: any, priority?: number): any;
export function timeout_add(timeout: any, handler: any, priority?: number): any;
export function timeout_add_seconds(timeout: any, handler: any, priority?: number): any;
export function source_remove(id: any): any;
export function run(name: string): void;
}
/**
* You can use the `Signals.addSignalMethods` method to apply the `Signals` convenience methods to an `Object`.
* Generally, this is called on an object prototype, but may also be called on an object instance.
* You can use this Interface for this object or prototype to make the methods in typescript known
* @example
* ```ts
* const Signals = imports.signals;
*
* // Define an interface with the same name of your class to make the methods known
* interface Events extends Signals.Methods {}
*
* class Events {}
* Signals.addSignalMethods(Events.prototype);
*
* const events = new Events();
*
* // Typescript will not complain here
* events.emit("test-signal", "test argument");
* ```
*/
export interface SignalMethods {
/**
* Connects a callback to a signal for an object. Pass the returned ID to
* `disconnect()` to remove the handler.
*
* If `callback` returns `true`, emission will stop and no other handlers will be
* invoked.
*
* > Warning: Unlike GObject signals, `this` within a signal callback will always
* > refer to the global object (ie. `globalThis`).
*
* @param sigName A signal name
* @param callback A callback function
* @returns A handler ID
*/
connect(sigName: string, callback: (self: any, ...args: any[]) => void): number;
/**
* Emits a signal for an object. Emission stops if a signal handler returns `true`.
*
* Unlike GObject signals, it is not necessary to declare signals or define their
* signature. Simply call `emit()` with whatever signal name you wish, with
* whatever arguments you wish.
* @param sigName A signal name
* @param args Any number of arguments, of any type
*/
emit(sigName: string, ...args: any[]): void;
/**
* Disconnects a handler for a signal.
* @param id The ID of the handler to be disconnected
*/
disconnect(id: number): void;
/**
* Disconnects all signal handlers for an object.
*/
disconnectAll(): void;
/**
* Checks if a handler ID is connected.
* @param id The ID of the handler to be disconnected
* @returns `true` if connected, or `false` if not
*/
signalHandlerIsConnected(id: number): boolean;
}
declare namespace signals {
export function addSignalMethods<T = any>(proto: T): proto is T & SignalMethods;
}
declare global {
// https://gitlab.gnome.org/GNOME/gjs/-/blob/1.73.2/modules/esm/_encoding/encodingMap.js#L7-232
type TextDecoderEncoding =
| 'unicode-1-1-utf-8'
| 'unicode11utf8'
| 'unicode20utf8'
| 'utf-8'
| 'utf8'
| 'x-unicode20utf8'
| '866'
| 'cp866'
| 'csibm866'
| 'ibm866'
| 'csisolatin2'
| 'iso-8859-2'
| 'iso-ir-101'
| 'iso8859-2'
| 'iso88592'
| 'iso_8859-2'
| 'iso_8859-2:1987'
| 'l2'
| 'latin2'
| 'csisolatin3'
| 'iso-8859-3'
| 'iso-ir-109'
| 'iso8859-3'
| 'iso88593'
| 'iso_8859-3'
| 'iso_8859-3:1988'
| 'l3'
| 'latin3'
| 'csisolatin4'
| 'iso-8859-4'
| 'iso-ir-110'
| 'iso8859-4'
| 'iso88594'
| 'iso_8859-4'
| 'iso_8859-4:1988'
| 'l4'
| 'latin4'
| 'csisolatincyrillic'
| 'cyrillic'
| 'iso-8859-5'
| 'iso-ir-144'
| 'iso8859-5'
| 'iso88595'
| 'iso_8859-5'
| 'iso_8859-5:1988'
| 'arabic'
| 'asmo-708'
| 'csiso88596e'
| 'csiso88596i'
| 'csisolatinarabic'
| 'ecma-114'
| 'iso-8859-6'
| 'iso-8859-6-e'
| 'iso-8859-6-i'
| 'iso-ir-127'
| 'iso8859-6'
| 'iso88596'
| 'iso_8859-6'
| 'iso_8859-6:1987'
| 'csisolatingreek'
| 'ecma-118'
| 'elot_928'
| 'greek'
| 'greek8'
| 'iso-8859-7'
| 'iso-ir-126'
| 'iso8859-7'
| 'iso88597'
| 'iso_8859-7'
| 'iso_8859-7:1987'
| 'sun_eu_greek'
| 'csiso88598e'
| 'csisolatinhebrew'
| 'hebrew'
| 'iso-8859-8'
| 'iso-8859-8-e'
| 'iso-ir-138'
| 'iso8859-8'
| 'iso88598'
| 'iso_8859-8'
| 'iso_8859-8:1988'
| 'visual'
| 'csiso88598i'
| 'iso-8859-8-i'
| 'logical'
| 'csisolatin6'
| 'iso-8859-10'
| 'iso-ir-157'
| 'iso8859-10'
| 'iso885910'
| 'l6'
| 'latin6'
| 'iso-8859-13'
| 'iso8859-13'
| 'iso885913'
| 'iso-8859-14'
| 'iso8859-14'
| 'iso885914'
| 'csisolatin9'
| 'iso-8859-15'
| 'iso8859-15'
| 'iso885915'
| 'iso_8859-15'
| 'l9'
| 'iso-8859-16'
| 'cskoi8r'
| 'koi'
| 'koi8'
| 'koi8-r'
| 'koi8_r'
| 'koi8-ru'
| 'koi8-u'
| 'csmacintosh'
| 'mac'
| 'macintosh'
| 'x-mac-roman'
| 'dos-874'
| 'iso-8859-11'
| 'iso8859-11'
| 'iso885911'
| 'tis-620'
| 'windows-874'
| 'cp1250'
| 'windows-1250'
| 'x-cp1250'
| 'cp1251'
| 'windows-1251'
| 'x-cp1251'
| 'ansi_x3.4-1968'
| 'ascii'
| 'cp1252'
| 'cp819'
| 'csisolatin1'
| 'ibm819'
| 'iso-8859-1'
| 'iso-ir-100'
| 'iso8859-1'
| 'iso88591'
| 'iso_8859-1'
| 'iso_8859-1:1987'
| 'l1'
| 'latin1'
| 'us-ascii'
| 'windows-1252'
| 'x-cp1252'
| 'cp1253'
| 'windows-1253'
| 'x-cp1253'
| 'cp1254'
| 'csisolatin5'
| 'iso-8859-9'
| 'iso-ir-148'
| 'iso8859-9'
| 'iso88599'
| 'iso_8859-9'
| 'iso_8859-9:1989'
| 'l5'
| 'latin5'
| 'windows-1254'
| 'x-cp1254'
| 'cp1255'
| 'windows-1255'
| 'x-cp1255'
| 'cp1256'
| 'windows-1256'
| 'x-cp1256'
| 'cp1257'
| 'windows-1257'
| 'x-cp1257'
| 'cp1258'
| 'windows-1258'
| 'x-cp1258'
| 'x-mac-cyrillic'
| 'x-mac-ukrainian'
| 'chinese'
| 'csgb2312'
| 'csiso58gb231280'
| 'gb2312'
| 'gb_2312'
| 'gb_2312-80'
| 'gbk'
| 'iso-ir-58'
| 'x-gbk'
| 'gb18030'
| 'big5'
| 'cn-big5'
| 'csbig5'
| 'x-x-big5'
| 'cseucpkdfmtjapanese'
| 'euc-jp'
| 'x-euc-jp'
| 'csiso2022jp'
| 'iso-2022-jp'
| 'csshiftjis'
| 'ms932'
| 'ms_kanji'
| 'shift-jis'
| 'shift_jis'
| 'sjis'
| 'windows-31j'
| 'x-sjis'
| 'cseuckr'
| 'csksc56011987'
| 'euc-kr'
| 'iso-ir-149'
| 'korean'
| 'ks_c_5601-1987'
| 'ks_c_5601-1989'
| 'ksc5601'
| 'ksc_5601'
| 'windows-949'
| 'unicodefffe'
| 'utf-16be'
| 'csunicode'
| 'iso-10646-ucs-2'
| 'ucs-2'
| 'unicode'
| 'unicodefeff'
| 'utf-16'
| 'utf-16le';
interface GjsGiImports {
// Will be extended by the import of more gir types
versions: {
[namespace: string]: string;
};
}
interface GjsImports {
gi: GjsGiImports;
lang: typeof lang;
system: typeof system;
signals: typeof signals;
package: typeof package;
mainloop: typeof mainloop;
searchPath: string[];
gettext: typeof gettext;
byteArray: typeof byteArray;
format: typeof format;
cairo: typeof cairo;
}
// Overwrites, see https://gitlab.gnome.org/GNOME/gjs/-/blob/master/modules/script/package.js
/**
* Run `pkg.initGettext()` before using this.
* See {@link gettext.gettext}
*/
const _: typeof gettext.gettext;
/**
* Run `pkg.initGettext()` before using this.
* See {@link gettext.pgettext}
*/
const C_: typeof gettext.pgettext;
/**
* Run `pkg.initGettext()` before using this.
* Currently not implemented.
*/
const N_: (x: string) => string;
function print(...args: any[]): void;
function printerr(...args: any[]): void;
function log(obj: object, others?: object[]): void;
function log(msg: string, substitutions?: any[]): void;
function logError(exception: object, message?: any): void;
function logError(message?: any): void;
const pkg: typeof package;
interface BooleanConstructor {
$gtype: GObject.GType<boolean>;
}
interface NumberConstructor {
$gtype: GObject.GType<number>;
}
interface StringConstructor {
$gtype: GObject.GType<string>;
}
interface StringConstructor {
$gtype: GObject.GType<string>;
}
interface ObjectConstructor {
$gtype: GObject.GType<Object>;
}
const imports: GjsImports;
const ARGV: string[];
interface String {
/**
* Formats a string with the given arguments.
* This method is made available by calling `pkg.initFormat()`.
*
* Supported format specifiers:
* - %s: Formats as a string
* - %d: Formats as an integer
* - %x: Formats as a hexadecimal number
* - %f: Formats as a floating point number, optionally with precision (e.g. %.2f)
*
* All specifiers can be prefixed with a minimum field width, e.g. "%5s" will pad with spaces.
* If the width is prefixed with '0', it will pad with zeroes instead of spaces.
*
* @example
* ```ts
* // After calling pkg.initFormat()
* "Hello %s, you have %d items".format("User", 5);
* // Returns: "Hello User, you have 5 items"
*
* "Price: $%.2f".format(10.5);
* // Returns: "Price: $10.50"
*
* "ID: %05d".format(42);
* // Returns: "ID: 00042"
* ```
*
* @param args The arguments to format the string with
* @returns The formatted string
*/
format(...args: (string | number | boolean | null | undefined)[]): string;
}
}
declare const _imports: GjsImports;
export default _imports;
export { _imports as imports };
@@ -0,0 +1,6 @@
const imports = globalThis.imports || {};
export { imports }
export default imports;
@@ -0,0 +1,13 @@
/**
* Type Definitions for Gjs (https://gjs.guide/)
*
* These type definitions are automatically generated, do not edit them by hand.
* If you found a bug fix it in `ts-for-gir` or create a bug report on https://github.com/gjsify/ts-for-gir
*
* This template is used to generate the index.d.ts file of each GIR module like Gtk-4.0, GObject-2.0, ...
*/
import './gjs-ambient.d.ts';
import gjs from './gjs.js';
export default gjs;
@@ -0,0 +1,5 @@
// @ts-expect-error
import gjs from './gjs.js';
export default gjs;
@@ -0,0 +1,74 @@
{
"name": "@girs/gjs",
"version": "4.0.0-beta.38",
"description": "GJS TypeScript type definitions for Gjs",
"type": "module",
"module": "gjs.js",
"main": "gjs.js",
"exports": {
"./ambient": {
"types": "./gjs-ambient.d.ts",
"import": "./gjs-ambient.js",
"default": "./gjs-ambient.js"
},
"./dom": {
"types": "./dom.d.ts",
"import": "./dom.js",
"default": "./dom.js"
},
"./gettext": {
"types": "./gettext.d.ts",
"import": "./gettext.js",
"default": "./gettext.js"
},
"./system": {
"types": "./system.d.ts",
"import": "./system.js",
"default": "./system.js"
},
"./cairo": {
"types": "./cairo.d.ts",
"import": "./cairo.js",
"default": "./cairo.js"
},
"./console": {
"types": "./console.d.ts",
"import": "./console.js",
"default": "./console.js"
},
"./gjs": {
"types": "./gjs.d.ts",
"import": "./gjs.js",
"default": "./gjs.js"
},
".": {
"types": "./index.d.ts",
"import": "./index.js",
"default": "./index.js"
}
},
"scripts": {
"test": "tsc --project tsconfig.json"
},
"dependencies": {
"@girs/gobject-2.0": "2.86.0-4.0.0-beta.38",
"@girs/glib-2.0": "2.86.0-4.0.0-beta.38",
"@girs/gio-2.0": "2.86.0-4.0.0-beta.38",
"@girs/cairo-1.0": "1.0.0-4.0.0-beta.38" },
"devDependencies": {
"typescript": "*"
},
"keywords": ["Gir", "TypeScript", "types", "GObject-Introspection", "GJS", "Gjs"],
"author": "ts-for-gir",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/gjsify/types.git"
},
"bugs": {
"url": "https://github.com/gjsify/ts-for-gir/issues"
},
"homepage": "https://github.com/gjsify/types/tree/main/gjs#readme"
}
@@ -0,0 +1,174 @@
import type GObject from '@girs/gobject-2.0';
/**
* This property contains the name of the script as it was invoked from the command
* line. In C and other languages, this information is contained in the first element of
* the platform's equivalent of argv, but GJS's ARGV only contains the
* subsequent command-line arguments. In other words, `ARGV[0]` in GJS is the same as `argv[1]` in C.
* @version Gjs 1.68
*/
export const programInvocationName: string;
/**
* This property contains version information about GJS.
*/
export const version: number;
/**
* The full path of the executed program.
* @version Gjs 1.68
*/
export const programPath: string | null;
/**
* A list of arguments passed to the current process.
* This is effectively an alias for the global `ARGV`, which is misleading in that
* it is not equivalent to the platform'`s` argv.
* @version Gjs 1.68
*/
export const programArgs: string[];
/**
* Return the memory address of any object as a string.
* This is the address of memory being managed by the JavaScript engine, which may
* represent a wrapper around memory elsewhere.
* **Caution**, don't use this as a unique identifier!
* JavaScript's garbage collector can move objects around in memory, or
* deduplicate identical objects, so this value may change during the execution
* of a program.
* @param o Any Object
* @returns A hexadecimal string (e.g. `0xb4f170f0`)
*/
export function addressOf(o: object): string;
/**
* Return the memory address of any GObject as a string.
* See also {@link addressOf}
* @param o Any {@link GObject.Object}-derived instance
* @returns A hexadecimal string (e.g. `0xb4f170f0`)
* @version Gjs 1.58
*/
export function addressOfGObject(o: GObject.Object): string;
/**
* Inserts a breakpoint instruction into the code.
* **Warning**: Using this function in code run outside of GDB will abort the process.
* With `System.breakpoint()` calls in your code, a GJS program can be debugged by
* running it in GDB:
* ```bash
* gdb --args gjs script.js
* ```
* Once GDB has started, you can start the program with run. When the debugger
* hits a breakpoint it will pause execution of the process and return to the
* prompt. You can then use the standard `backtrace` command to print a C++ stack
* trace, or use `call gjs_dumpstack()` to print a JavaScript stack trace:
* ```bash
* (gdb) run
* tarting program: /usr/bin/gjs -m script.js
* ...
* Thread 1 "gjs" received signal SIGTRAP, Trace/breakpoint trap.
* (gdb) call gjs_dumpstack()
* == Stack trace for context 0x5555555b7180 ==
* #0 555555640548 i file:///path/to/script.js:4 (394b8c3cc060 @ 12)
* #1 5555556404c8 i file:///path/to/script.js:7 (394b8c3cc0b0 @ 6)
* #2 7fffffffd3a0 b self-hosted:2408 (394b8c3a9650 @ 753)
* #3 5555556403e8 i self-hosted:2355 (394b8c3a9600 @ 375)
* (gdb)
* ```
* To continue executing the program, you can use the `continue` (or `cont`) to
* resume the process and debug further.
* Remember that if you run the program outside of GDB, it will abort at the
* breakpoint, so make sure to remove any calls to `System.breakpoint()` when
* you're done debugging.
*/
export function breakpoint(): void;
/**
* Clears the timezone cache.
* This is a workaround for SpiderMonkey Bug [#1004706](https://bugzilla.mozilla.org/show_bug.cgi?id=1004706).
*/
export function clearDateCaches(): void;
/** Runs the garbage collector */
export function gc(): void;
/**
* Return the reference count of any GObject-derived type. When an object's
* reference count is zero, it is cleaned up and erased from memory.
* @param o A {@link GObject.Object}
*/
export function refcount(o: GObject.Object): number;
/**
* See also: The [heapgraph](https://gitlab.gnome.org/GNOME/gjs/blob/HEAD/tools/heapgraph.md) utility in the GJS repository.
* Dump a representation of internal heap memory. If `path` is not given, GJS will
* write the contents to `stdout`.
* @param path Optional file path
*/
export function dumpHeap(path?: string): void;
/**
* Dump internal garbage collector statistics. If `path` is not given, GJS will
* write the contents to `stdout`.
* @param path Optional file path
* @version Gjs 1.70
* @example Output:
* ```json
* {
* "gcBytes": 794624,
* "gcMaxBytes": 4294967295,
* "mallocBytes": 224459,
* "gcIsHighFrequencyMode": true,
* "gcNumber": 1,
* "majorGCCount": 1,
* "minorGCCount": 1,
* "sliceCount": 1,
* "zone": {
* "gcBytes": 323584,
* "gcTriggerBytes": 42467328,
* "gcAllocTrigger": 36097228.8,
* "mallocBytes": 120432,
* "mallocTriggerBytes": 59768832,
* "gcNumber": 1
* }
* }
* ```
*
*/
export function dumpMemoryInfo(path?: string): void;
/**
* This works the same as C's exit() function; exits the program, passing a
* certain error code to the shell. The shell expects the error code to be zero if
* there was no error, or non-zero (any value you please) to indicate an error.
*
* This value is used by other tools such as `make`; if `make` calls a program that
* returns a non-zero error code, then `make` aborts the build.
* @param code An exit code
*/
export function exit(code: number): never;
/**
* The System module provides common low-level facilities such as access to
* process arguments and exit(), as well as a number of useful functions and
* properties for debugging.
*
* Note that the majority of the functions and properties in this module should not
* be used in normal operation of a GJS application.
*/
declare const System: {
programInvocationName: typeof programInvocationName;
version: typeof version;
programPath: typeof programPath;
programArgs: typeof programArgs;
addressOf: typeof addressOf;
addressOfGObject: typeof addressOfGObject;
breakpoint: typeof breakpoint;
clearDateCaches: typeof clearDateCaches;
gc: typeof gc;
refcount: typeof refcount;
dumpHeap: typeof dumpHeap;
dumpMemoryInfo: typeof dumpMemoryInfo;
exit: typeof exit;
};
export default System;
@@ -0,0 +1,5 @@
import System, { programInvocationName, version, programPath, programArgs, exit, addressOfGObject, addressOf, gc, refcount, dumpHeap, dumpMemoryInfo } from 'system';
export { programInvocationName, version, programPath, programArgs, exit, addressOfGObject, addressOf, gc, refcount, dumpHeap, dumpMemoryInfo };
export default System;
@@ -0,0 +1,25 @@
{
"compilerOptions": {
// General settings for code interpretation
"target": "ESNext",
"module": "NodeNext",
"lib": ["ESNext"],
"types": [],
"experimentalDecorators": true,
"moduleResolution": "NodeNext",
"noEmit": true,
"noEmitOnError": false,
"baseUrl": "./",
"rootDir": ".",
// General settings for code generation
"removeComments": false,
"inlineSourceMap": false,
"inlineSources": false,
"newLine": "LF",
// Show diagnostics
"diagnostics": true
},
"include": ["./dom.d.ts","./gjs.d.ts"]
}
@@ -0,0 +1,7 @@
{
"entryPoints": ["./gjs.d.ts"],
"readme": "./README.md",
"name": "Gjs",
"tsconfig": "./tsconfig.json"
}
@@ -0,0 +1,85 @@
# GLib-2.0
![version](https://img.shields.io/npm/v/@girs/glib-2.0)
![downloads/week](https://img.shields.io/npm/dw/@girs/glib-2.0)
GJS TypeScript type definitions for GLib-2.0, generated from library version 2.86.0 using [ts-for-gir](https://github.com/gjsify/ts-for-gir) v4.0.0-beta.38.
## Install
To use this type definitions, install them with NPM:
```bash
npm install @girs/glib-2.0
```
## Usage
You can import this package into your project like this:
```ts
import GLib from '@girs/glib-2.0';
```
### Ambient Modules
You can also use [ambient modules](https://github.com/gjsify/ts-for-gir/tree/main/packages/cli#ambient-modules) to import this module like you would do this in JavaScript.
For this you need to include `@girs/glib-2.0` or `@girs/glib-2.0/ambient` in your `tsconfig` or entry point Typescript file:
`index.ts`:
```ts
import '@girs/glib-2.0'
```
`tsconfig.json`:
```json
{
"compilerOptions": {
...
},
"include": ["@girs/glib-2.0"],
...
}
```
Now you can import the ambient module with TypeScript support:
```ts
import GLib from 'gi://GLib?version=2.0';
```
### Global import
You can also import the module with Typescript support using the global `imports.gi` object of GJS.
For this you need to include `@girs/glib-2.0` or `@girs/glib-2.0/import` in your `tsconfig` or entry point Typescript file:
`index.ts`:
```ts
import '@girs/glib-2.0'
```
`tsconfig.json`:
```json
{
"compilerOptions": {
...
},
"include": ["@girs/glib-2.0"],
...
}
```
Now you have also type support for this, too:
```ts
const GLib = imports.gi.GLib;
```
### Bundle
Depending on your project configuration, it is recommended to use a bundler like [esbuild](https://esbuild.github.io/). You can find examples using different bundlers [here](https://github.com/gjsify/ts-for-gir/tree/main/examples).
## Other packages
All existing pre-generated packages can be found on [gjsify/types](https://github.com/gjsify/types).
@@ -0,0 +1,9 @@
declare module 'gi://GLib?version=2.0' {
import GLib20 from '@girs/glib-2.0';
export default GLib20;
}
declare module 'gi://GLib' {
import GLib20 from 'gi://GLib?version=2.0';
export default GLib20;
}
@@ -0,0 +1,2 @@
export {}
@@ -0,0 +1,9 @@
import type GLib20 from '@girs/glib-2.0';
declare global {
export interface GjsGiImports {
GLib: typeof GLib20;
}
}
export default GjsGiImports;
@@ -0,0 +1,3 @@
const gi = globalThis.imports?.gi || {};
export default gi;
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,5 @@
// @ts-expect-error
import GLib from 'gi://GLib?version=2.0';
export default GLib;
@@ -0,0 +1,15 @@
/**
* Type Definitions for Gjs (https://gjs.guide/)
*
* These type definitions are automatically generated, do not edit them by hand.
* If you found a bug fix it in `ts-for-gir` or create a bug report on https://github.com/gjsify/ts-for-gir
*
* This template is used to generate the index.d.ts file of each GIR module like Gtk-4.0, GObject-2.0, ...
*/
import './glib-2.0-ambient.d.ts';
import './glib-2.0-import.d.ts';
import GLib from './glib-2.0.js';
export default GLib;
@@ -0,0 +1,5 @@
// @ts-expect-error
import GLib from './glib-2.0.js';
export default GLib;
@@ -0,0 +1,52 @@
{
"name": "@girs/glib-2.0",
"version": "2.86.0-4.0.0-beta.38",
"description": "GJS TypeScript type definitions for GLib-2.0, generated from library version 2.86.0",
"type": "module",
"module": "glib-2.0.js",
"main": "glib-2.0.js",
"exports": {
"./ambient": {
"types": "./glib-2.0-ambient.d.ts",
"import": "./glib-2.0-ambient.js",
"default": "./glib-2.0-ambient.js"
},
"./import": {
"types": "./glib-2.0-import.d.ts",
"import": "./glib-2.0-import.js",
"default": "./glib-2.0-import.js"
},
"./glib-2.0": {
"types": "./glib-2.0.d.ts",
"import": "./glib-2.0.js",
"default": "./glib-2.0.js"
},
".": {
"types": "./index.d.ts",
"import": "./index.js",
"default": "./index.js"
}
},
"scripts": {
"test": "tsc --project tsconfig.json"
},
"dependencies": {
"@girs/gjs": "4.0.0-beta.38",
"@girs/gobject-2.0": "2.86.0-4.0.0-beta.38" },
"devDependencies": {
"typescript": "*"
},
"keywords": ["Gir", "TypeScript", "types", "GObject-Introspection", "GJS", "GLib-2.0"],
"author": "ts-for-gir",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/gjsify/types.git"
},
"bugs": {
"url": "https://github.com/gjsify/ts-for-gir/issues"
},
"homepage": "https://github.com/gjsify/types/tree/main/glib-2.0#readme"
}
@@ -0,0 +1,25 @@
{
"compilerOptions": {
// General settings for code interpretation
"target": "ESNext",
"module": "NodeNext",
"lib": ["ESNext"],
"types": [],
"experimentalDecorators": true,
"moduleResolution": "NodeNext",
"noEmit": true,
"noEmitOnError": false,
"baseUrl": "./",
"rootDir": ".",
// General settings for code generation
"removeComments": false,
"inlineSourceMap": false,
"inlineSources": false,
"newLine": "LF",
// Show diagnostics
"diagnostics": true
},
"include": ["./glib-2.0.d.ts"]
}
@@ -0,0 +1,7 @@
{
"entryPoints": ["./glib-2.0.d.ts"],
"readme": "./README.md",
"name": "GLib-2.0",
"tsconfig": "./tsconfig.json"
}
@@ -0,0 +1,85 @@
# GModule-2.0
![version](https://img.shields.io/npm/v/@girs/gmodule-2.0)
![downloads/week](https://img.shields.io/npm/dw/@girs/gmodule-2.0)
GJS TypeScript type definitions for GModule-2.0, generated from library version 2.0.0 using [ts-for-gir](https://github.com/gjsify/ts-for-gir) v4.0.0-beta.38.
## Install
To use this type definitions, install them with NPM:
```bash
npm install @girs/gmodule-2.0
```
## Usage
You can import this package into your project like this:
```ts
import GModule from '@girs/gmodule-2.0';
```
### Ambient Modules
You can also use [ambient modules](https://github.com/gjsify/ts-for-gir/tree/main/packages/cli#ambient-modules) to import this module like you would do this in JavaScript.
For this you need to include `@girs/gmodule-2.0` or `@girs/gmodule-2.0/ambient` in your `tsconfig` or entry point Typescript file:
`index.ts`:
```ts
import '@girs/gmodule-2.0'
```
`tsconfig.json`:
```json
{
"compilerOptions": {
...
},
"include": ["@girs/gmodule-2.0"],
...
}
```
Now you can import the ambient module with TypeScript support:
```ts
import GModule from 'gi://GModule?version=2.0';
```
### Global import
You can also import the module with Typescript support using the global `imports.gi` object of GJS.
For this you need to include `@girs/gmodule-2.0` or `@girs/gmodule-2.0/import` in your `tsconfig` or entry point Typescript file:
`index.ts`:
```ts
import '@girs/gmodule-2.0'
```
`tsconfig.json`:
```json
{
"compilerOptions": {
...
},
"include": ["@girs/gmodule-2.0"],
...
}
```
Now you have also type support for this, too:
```ts
const GModule = imports.gi.GModule;
```
### Bundle
Depending on your project configuration, it is recommended to use a bundler like [esbuild](https://esbuild.github.io/). You can find examples using different bundlers [here](https://github.com/gjsify/ts-for-gir/tree/main/examples).
## Other packages
All existing pre-generated packages can be found on [gjsify/types](https://github.com/gjsify/types).
@@ -0,0 +1,9 @@
declare module 'gi://GModule?version=2.0' {
import GModule20 from '@girs/gmodule-2.0';
export default GModule20;
}
declare module 'gi://GModule' {
import GModule20 from 'gi://GModule?version=2.0';
export default GModule20;
}
@@ -0,0 +1,2 @@
export {}
@@ -0,0 +1,9 @@
import type GModule20 from '@girs/gmodule-2.0';
declare global {
export interface GjsGiImports {
GModule: typeof GModule20;
}
}
export default GjsGiImports;
@@ -0,0 +1,3 @@
const gi = globalThis.imports?.gi || {};
export default gi;
@@ -0,0 +1,200 @@
/**
* Type Definitions for Gjs (https://gjs.guide/)
*
* These type definitions are automatically generated, do not edit them by hand.
* If you found a bug fix it in `ts-for-gir` or create a bug report on https://github.com/gjsify/ts-for-gir
*
* The based EJS template file is used for the generated .d.ts file of each GIR module like Gtk-4.0, GObject-2.0, ...
*/
import '@girs/gjs';
// Module dependencies
import type GLib from '@girs/glib-2.0';
import type GObject from '@girs/gobject-2.0';
export namespace GModule {
/**
* GModule-2.0
*/
/**
* Errors returned by g_module_open_full().
*/
class ModuleError extends GLib.Error {
static $gtype: GObject.GType<ModuleError>;
// Static fields
/**
* there was an error loading or opening a module file
*/
static FAILED: number;
/**
* a module returned an error from its `g_module_check_init()` function
*/
static CHECK_FAILED: number;
// Constructors
constructor(options: { message: string; code: number });
_init(...args: any[]): void;
}
const MODULE_IMPL_AR: number;
const MODULE_IMPL_DL: number;
const MODULE_IMPL_NONE: number;
const MODULE_IMPL_WIN32: number;
/**
* A portable way to build the filename of a module. The platform-specific
* prefix and suffix are added to the filename, if needed, and the result
* is added to the directory, using the correct separator character.
*
* The directory should specify the directory where the module can be found.
* It can be %NULL or an empty string to indicate that the module is in a
* standard platform-specific directory, though this is not recommended
* since the wrong module may be found.
*
* For example, calling g_module_build_path() on a Linux system with a
* `directory` of `/lib` and a `module_name` of "mylibrary" will return
* `/lib/libmylibrary.so`. On a Windows system, using `\Windows` as the
* directory it will return `\Windows\mylibrary.dll`.
* @param directory the directory where the module is. This can be %NULL or the empty string to indicate that the standard platform-specific directories will be used, though that is not recommended
* @param module_name the name of the module
* @returns the complete path of the module, including the standard library prefix and suffix. This should be freed when no longer needed
*/
function module_build_path(directory: string | null, module_name: string): string;
/**
* Gets a string describing the last module error.
* @returns a string describing the last module error
*/
function module_error(): string;
function module_error_quark(): GLib.Quark;
/**
* Checks if modules are supported on the current platform.
* @returns %TRUE if modules are supported
*/
function module_supported(): boolean;
interface ModuleCheckInit {
(module: Module): string;
}
interface ModuleUnload {
(module: Module): void;
}
/**
* Flags passed to g_module_open().
* Note that these flags are not supported on all platforms.
*/
/**
* Flags passed to g_module_open().
* Note that these flags are not supported on all platforms.
*/
export namespace ModuleFlags {
export const $gtype: GObject.GType<ModuleFlags>;
}
enum ModuleFlags {
/**
* specifies that symbols are only resolved when
* needed. The default action is to bind all symbols when the module
* is loaded.
*/
LAZY,
/**
* specifies that symbols in the module should
* not be added to the global name space. The default action on most
* platforms is to place symbols in the module in the global name space,
* which may cause conflicts with existing symbols.
*/
LOCAL,
/**
* mask for all flags.
*/
MASK,
}
/**
* The #GModule struct is an opaque data structure to represent a
* [dynamically-loaded module](modules.html#dynamic-loading-of-modules).
* It should only be accessed via the following functions.
*/
abstract class Module {
static $gtype: GObject.GType<Module>;
// Constructors
_init(...args: any[]): void;
// Static methods
/**
* A portable way to build the filename of a module. The platform-specific
* prefix and suffix are added to the filename, if needed, and the result
* is added to the directory, using the correct separator character.
*
* The directory should specify the directory where the module can be found.
* It can be %NULL or an empty string to indicate that the module is in a
* standard platform-specific directory, though this is not recommended
* since the wrong module may be found.
*
* For example, calling g_module_build_path() on a Linux system with a
* `directory` of `/lib` and a `module_name` of "mylibrary" will return
* `/lib/libmylibrary.so`. On a Windows system, using `\Windows` as the
* directory it will return `\Windows\mylibrary.dll`.
* @param directory the directory where the module is. This can be %NULL or the empty string to indicate that the standard platform-specific directories will be used, though that is not recommended
* @param module_name the name of the module
*/
static build_path(directory: string | null, module_name: string): string;
/**
* Gets a string describing the last module error.
*/
static error(): string;
static error_quark(): GLib.Quark;
/**
* Checks if modules are supported on the current platform.
*/
static supported(): boolean;
// Methods
/**
* Closes a module.
* @returns %TRUE on success
*/
close(): boolean;
/**
* Ensures that a module will never be unloaded.
* Any future g_module_close() calls on the module will be ignored.
*/
make_resident(): void;
/**
* Returns the filename that the module was opened with.
*
* If `module` refers to the application itself, "main" is returned.
* @returns the filename of the module
*/
name(): string;
/**
* Gets a symbol pointer from a module, such as one exported
* by %G_MODULE_EXPORT. Note that a valid symbol can be %NULL.
* @param symbol_name the name of the symbol to find
* @returns %TRUE on success
*/
symbol(symbol_name: string): [boolean, any];
}
/**
* Name of the imported GIR library
* `see` https://gitlab.gnome.org/GNOME/gjs/-/blob/master/gi/ns.cpp#L188
*/
const __name__: string;
/**
* Version of the imported GIR library
* `see` https://gitlab.gnome.org/GNOME/gjs/-/blob/master/gi/ns.cpp#L189
*/
const __version__: string;
}
export default GModule;
// END
@@ -0,0 +1,5 @@
// @ts-expect-error
import GModule from 'gi://GModule?version=2.0';
export default GModule;

Some files were not shown because too many files have changed in this diff Show More