diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 0476cfe4..11e34535 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -25,6 +25,8 @@ A clear and concise description of what you expected to happen.
- Desktop Env [e.g. Gnome, KDE]
- Version [e.g. 2.0.3]
+**Flatpak issues**: If you experience any issue with flatpak, first please ensure that the bug is present in the [native package](https://github.com/slgobinath/SafeEyes?tab=readme-ov-file#installation-guide), and it is not a flatpak-only bug. Flatpak-only bugs should be reported at https://github.com/flathub/io.github.slgobinath.SafeEyes. (**Please erase this paragraph before creating the bug report**)
+
**Debug Log**
Run the Safe Eyes using `safeeyes --debug` command attach the ~/safeeyes.log` file.
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 00000000..9af2b10d
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,5 @@
+## Description
+
+Describe your changes here, and link to related issues if available.
+
+Reminder to run `python validate_po.py --extract` if you have added new translatable strings.
diff --git a/README.md b/README.md
index 68603b63..84e5871b 100644
--- a/README.md
+++ b/README.md
@@ -43,7 +43,7 @@ Safe Eyes is available on the official repositories of many popular the distribu
-It is also available in Ubuntu PPA, Arch AUR, Gentoo and Python PyPI. You can choose any installation source and install on any Linux system with Python 3.
+It is also available in Ubuntu PPA, Arch AUR and Python PyPI. You can choose any installation source and install on any Linux system with Python 3.
### Ubuntu, Linux Mint and other Ubuntu Derivatives
@@ -79,13 +79,15 @@ sudo apt-get install safeeyes
```
### Fedora
-
+ If you want to use Smart Pause plugin, install the latest xprintidle from: [alonid/xprintidle](https://copr.fedorainfracloud.org/coprs/alonid/xprintidle/)
```bash
sudo dnf install python3-psutil python3-packaging cairo-devel python3-devel gobject-introspection-devel cairo-gobject-devel
sudo pip3 install safeeyes
sudo gtk-update-icon-cache /usr/share/icons/hicolor
```
+We are looking for an official package maintainer for Fedora. Please [contact us](https://github.com/slgobinath/SafeEyes/issues/611) if you are interested.
+
### OpenSUSE Tumbleweed
```bash
@@ -100,7 +102,7 @@ sudo apk add safeeyes
```
### Flatpak
-
+**Warning**: Many plugins and features don't work well in the flatpak. We recommend that you use one of the native packages listed above. Flatpak-only bugs should be reported at https://github.com/flathub/io.github.slgobinath.SafeEyes.
```bash
flatpak install flathub io.github.slgobinath.SafeEyes
```
@@ -184,14 +186,22 @@ For more details, please check the issue: [#329](https://github.com/slgobinath/S
Thirdparty plugins are available at another GitHub repository: [safeeyes-plugins](https://github.com/slgobinath/safeeyes-plugins). More details about how to write your own plugin and how to install third-party plugin are available there.
+## Local development
+
+When adding new translatable strings in the source code, make sure to run `python validate_po.py --extract` to add them to the translation template. You will need to install `python3-polib` for this.
+
+Examples for translatable strings are `_("This is a string")` in Python code, or `This is a label` in Glade/xml files.
+
+To ensure the new strings are well-formed, you can use `python validate_po.py --validate`.
+
## How to Release?
0. Run `update-po.sh` to generate new translation files (which will be eventually updated by translators). Commit and push the changes to the master branch.
1. Checkout the latest commits from the `master` branch
2. Run `python3 -m safeeyes` to make sure nothing is broken
3. Update the Safe Eyes version in the following places (Open the project in VSCode and search for the current version):
- - [setup.py](https://github.com/slgobinath/SafeEyes/blob/master/setup.py#L83)
- - [setup.py](https://github.com/slgobinath/SafeEyes/blob/master/setup.py#L90)
+ - [setup.py](https://github.com/slgobinath/SafeEyes/blob/master/setup.py#L82)
+ - [setup.py](https://github.com/slgobinath/SafeEyes/blob/master/setup.py#L89)
- [safeeyes.py](https://github.com/slgobinath/SafeEyes/blob/master/safeeyes/safeeyes.py#L42)
- [io.github.slgobinath.SafeEyes.metainfo.xml](https://github.com/slgobinath/SafeEyes/blob/master/safeeyes/platform/io.github.slgobinath.SafeEyes.metainfo.xml#L56)
- [about_dialog.glade](https://github.com/slgobinath/SafeEyes/blob/master/safeeyes/glade/about_dialog.glade#L74)
@@ -200,6 +210,12 @@ Thirdparty plugins are available at another GitHub repository: [safeeyes-plugins
6. Create a pull-request from `master` to `release`
7. Merge the PR to release **with merge commit** (Important to merge with merge commit)
+## How you can help improving translation of Safe Eyes
+
+First check if translations for your language are already available on [Weblate](https://hosted.weblate.org/engage/safe-eyes/), which is the cloud based translation platform we use.
+
+- If the language is already there, feel free to add new translations or improve the existing ones.
+- If it is not there, please [open an issue](https://github.com/slgobinath/SafeEyes/issues) in Github so that we can add your language to Weblate.
## License
diff --git a/debian/changelog b/debian/changelog
index e3691908..fadf0d8f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,24 @@
+safeeyes (2.2.3) jammy; urgency=medium
+
+ * Translations
+
+ * Make config and stylesheet files non-executable
+
+ * Retry loading trayicon plugin to fix races on startup
+
+ * Fix "Show next break time in tray icon" for desktops support tray icons
+ with labels
+
+ * Fix next break time in tray icon when disabling SafeEyes
+
+ * Make SafeEyes compatible with Python 3.6 again
+
+ * Add 'hyprland' to the list of recognized desktop sessions
+
+ * Remove hard dependency on X11
+
+ -- Mel Dafert Wed, 25 Dec 2024 11:46:00 +0000
+
safeeyes (2.2.2) jammy; urgency=medium
* Fixed translations
diff --git a/safeeyes/config/locale/ar/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/ar/LC_MESSAGES/safeeyes.po
index 50496bf5..64d6b798 100644
--- a/safeeyes/config/locale/ar/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/ar/LC_MESSAGES/safeeyes.po
@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2024-07-26 11:09+0000\n"
-"Last-Translator: RDWN IT \n"
+"PO-Revision-Date: 2024-09-17 01:09+0000\n"
+"Last-Translator: Barman Anonymous Please \n"
"Language-Team: Arabic \n"
"Language: ar\n"
@@ -16,11 +16,11 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
-"X-Generator: Weblate 5.7-dev\n"
+"X-Generator: Weblate 5.8-dev\n"
# Short break
msgid "Gently close your eyes"
-msgstr ""
+msgstr "أغمض عينيك بلطف"
# Short break
msgid "Roll your eyes a few times to each side"
@@ -40,7 +40,7 @@ msgstr "اغمز بعينيك"
# Short break
msgid "Focus on a point in the far distance"
-msgstr "ركّز على نقطة في المدى البعيد"
+msgstr "ركّز على نقطة بعيدة"
# Short break
msgid "Have some water"
@@ -76,7 +76,7 @@ msgstr "إظهار لوحة اﻹعدادات"
# Commandline arg description
msgid "start safeeyes in debug mode"
-msgstr "ابدأ عيون سليمة في وضع التنقيح"
+msgstr "ابدأ safeeyes في وضع التنقيح (debug)"
# Commandline arg description
msgid "print the status of running safeeyes instance and exit"
@@ -109,7 +109,11 @@ msgstr "الرخصة"
# About dialog
msgid "List of Contributors"
-msgstr ""
+msgstr "قائمة المساهمين"
+
+# About dialog
+msgid "Help us translate this app"
+msgstr "ساعدنا في ترجمة هذا التطبيق"
# Break screen
msgid "Skip"
@@ -535,36 +539,36 @@ msgstr "أوقِف الوسائط"
# plugin/limitconsecutiveskipping
msgid "Limit Consecutive Skipping"
-msgstr ""
+msgstr "تقييد التخطي المتتالي"
# plugin/limitconsecutiveskipping
msgid "How many skips or postpones are allowed in a row"
-msgstr ""
+msgstr "عدد مرات التخطي أو التأجيل المسموح بها على التوالي"
# plugin/limitconsecutiveskipping
msgid "Limit how many breaks can be skipped or postponed in a row"
-msgstr ""
+msgstr "حدد عدد فترات الاستراحة التي يمكن تخطيها أو تأجيلها على التوالي"
# plugin/limitconsecutiveskipping
#, python-format
msgid "Skipped or postponed %(num)d/%(allowed)d breaks in a row"
-msgstr ""
+msgstr "تم تخطي أو تأجيل %(num)d/%(allowed)d من فترات الاستراحة على التوالي"
# safeeyes/platform/io.github.slgobinath.SafeEyes.desktop
msgid "RSI Prevention"
-msgstr ""
+msgstr "الوقاية من الإصابات الناتجة عن الإجهاد المتكرر للعينين"
msgid ""
"Please install service providing tray icons for your desktop environment."
-msgstr ""
+msgstr "يرجى تثبيت خدمة توفر أيقونات في علبة النظام لبيئة سطح المكتب الخاصة بك."
#, python-format
msgid "Next long break at %s"
-msgstr ""
+msgstr "الاستراحة الطويلة القادمة في %s"
#, python-format
msgid "Next breaks at %(short)s/%(long)s"
-msgstr ""
+msgstr "الاستراحة القادمة في %(short)s/%(long)s"
#, python-format
msgid "The required plugin '%s' is missing dependencies!"
diff --git a/safeeyes/config/locale/bg/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/bg/LC_MESSAGES/safeeyes.po
index 0c86021d..81112bb8 100644
--- a/safeeyes/config/locale/bg/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/bg/LC_MESSAGES/safeeyes.po
@@ -110,6 +110,10 @@ msgstr "Лиценз"
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr "Пропускане"
diff --git a/safeeyes/config/locale/bn/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/bn/LC_MESSAGES/safeeyes.po
new file mode 100644
index 00000000..37e7b70e
--- /dev/null
+++ b/safeeyes/config/locale/bn/LC_MESSAGES/safeeyes.po
@@ -0,0 +1,578 @@
+# SAFE EYES ENGLISH TRANSLATION.
+# Copyright (C) 2017 Gobinath
+# Gobinath slgobinath@gmail.com, 2017.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: \n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: 2024-08-16 15:09+0000\n"
+"Last-Translator: Archisman Panigrahi \n"
+"Language-Team: Bengali \n"
+"Language: bn\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n==0 || n==1);\n"
+"X-Generator: Weblate 5.7\n"
+
+# Short break
+msgid "Gently close your eyes"
+msgstr "আলতো করে চোখ বন্ধ করুন"
+
+# Short break
+msgid "Roll your eyes a few times to each side"
+msgstr ""
+
+# Short break
+msgid "Rotate your eyes in clockwise direction"
+msgstr ""
+
+# Short break
+msgid "Rotate your eyes in counterclockwise direction"
+msgstr ""
+
+# Short break
+msgid "Blink your eyes"
+msgstr ""
+
+# Short break
+msgid "Focus on a point in the far distance"
+msgstr ""
+
+# Short break
+msgid "Have some water"
+msgstr "একটু জল খেয়ে নিন"
+
+# Long break
+msgid "Walk for a while"
+msgstr "একটু হেঁটে আসুন"
+
+# Long break
+msgid "Lean back at your seat and relax"
+msgstr ""
+
+# Commandline arg description
+msgid "show the about dialog"
+msgstr ""
+
+# Commandline arg description
+msgid "disable the currently running safeeyes instance"
+msgstr ""
+
+# Commandline arg description
+msgid "enable the currently running safeeyes instance"
+msgstr ""
+
+# Commandline arg description
+msgid "quit the running safeeyes instance and exit"
+msgstr ""
+
+# Commandline arg description
+msgid "show the settings dialog"
+msgstr ""
+
+# Commandline arg description
+msgid "start safeeyes in debug mode"
+msgstr ""
+
+# Commandline arg description
+msgid "print the status of running safeeyes instance and exit"
+msgstr ""
+
+# Status message
+msgid "Safe Eyes is not running"
+msgstr "Safe Eyes চলছে না"
+
+# RPC not enabled message
+msgid ""
+"Safe Eyes is running without an RPC server. Turn it on to use command-line "
+"arguments."
+msgstr ""
+
+# About dialog
+msgid "Close"
+msgstr ""
+
+# Description in about dialog
+# Safe Eyes protects your eyes from eye strain (asthenopia) by reminding you to take breaks while you're working long hours at the computer
+msgid ""
+"Safe Eyes protects your eyes from eye strain (asthenopia) by reminding you "
+"to take breaks while you're working long hours at the computer"
+msgstr ""
+
+# About dialog
+msgid "License"
+msgstr "অনুমতিপত্র"
+
+# About dialog
+msgid "List of Contributors"
+msgstr ""
+
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
+# Break screen
+msgid "Skip"
+msgstr ""
+
+# Break screen
+msgid "Postpone"
+msgstr ""
+
+# Settings dialog
+msgid "Break duration (in seconds)"
+msgstr ""
+
+# Settings dialog
+msgid "Interval between two breaks (in minutes)"
+msgstr ""
+
+# Settings dialog
+msgid "Time to prepare for a break (in seconds)"
+msgstr ""
+
+# Settings dialog
+msgid "Keyboard shortcuts disabled period (in seconds)"
+msgstr ""
+
+# Settings dialog
+msgid "Postponement duration (in minutes)"
+msgstr ""
+
+# Settings dialog
+msgid "Show breaks in random order"
+msgstr ""
+
+# Settings dialog
+msgid "Strict break (No way to skip breaks)"
+msgstr ""
+
+# Settings dialog
+msgid "Allow postponing breaks"
+msgstr ""
+
+# Settings dialog
+msgid "Persist the internal state"
+msgstr ""
+
+# Settings dialog
+msgid "Use RPC server to receive runtime commands"
+msgstr ""
+
+# Settings dialog
+msgid "Without the RPC server, command-line commands may not work"
+msgstr ""
+
+# Settings dialog
+msgid "Long break interval must be a multiple of short break interval"
+msgstr ""
+
+# Settings dialog
+msgid "Reset"
+msgstr ""
+
+# Settings dialog
+msgid "Are you sure you want to reset all settings to default?"
+msgstr ""
+
+# Settings dialog
+msgid "Options"
+msgstr ""
+
+# Settings dialog
+msgid "Short Breaks"
+msgstr ""
+
+# Settings dialog
+msgid "Long Breaks"
+msgstr ""
+
+# Settings dialog
+msgid "Delete"
+msgstr ""
+
+# Settings dialog
+msgid "Are you sure you want to delete this break?"
+msgstr ""
+
+# Settings dialog
+msgid "You can't undo this action."
+msgstr ""
+
+# Settings dialog
+msgid "Break"
+msgstr ""
+
+# Settings dialog
+msgid "Breaks"
+msgstr ""
+
+# Settings dialog
+msgid "Plugins"
+msgstr ""
+
+# Settings dialog
+msgid "Type"
+msgstr ""
+
+# Settings dialog
+msgid "Short"
+msgstr ""
+
+# Settings dialog
+msgid "Long"
+msgstr ""
+
+# Settings dialog
+msgid "Image"
+msgstr ""
+
+# Settings dialog
+msgid "Select"
+msgstr ""
+
+# Settings dialog
+msgid "Please select an image"
+msgstr ""
+
+# Settings dialog
+msgid "Duration"
+msgstr ""
+
+# Settings dialog
+msgid "Time to wait"
+msgstr ""
+
+# Settings dialog
+msgid "Override"
+msgstr ""
+
+# Settings dialog
+msgid "Time (in seconds)"
+msgstr "সময় (সেকেন্ডে)"
+
+# Settings dialog
+msgid "Time (in minutes)"
+msgstr "সময় (মিনিটে)"
+
+# Settings dialog
+msgid "Break Settings"
+msgstr ""
+
+# Settings dialog
+msgid "Plugin Settings"
+msgstr ""
+
+# Settings dialog
+#, python-format
+msgid "Plugin does not support %s desktop environment"
+msgstr ""
+
+# Settings dialog
+#, python-format
+msgid "Please install the Python module '%s'"
+msgstr ""
+
+# Settings dialog
+#, python-format
+msgid "Please install the command-line tool '%s'"
+msgstr ""
+
+# Settings dialog
+msgid "Invalid cron expression '%s'"
+msgstr ""
+
+# Settings dialog
+#, python-format
+msgid "Please add the resource %(resource)s to %(config_resource)s directory"
+msgstr ""
+
+# Settings dialog
+msgid "New Break"
+msgstr ""
+
+# Settings dialog
+msgid "Remove"
+msgstr ""
+
+# Settings dialog
+msgid "Discard"
+msgstr ""
+
+# Settings dialog
+msgid "Save"
+msgstr ""
+
+# plugin/audiblealert
+msgid "Audible Alert"
+msgstr ""
+
+# plugin/audiblealert
+msgid "Play audible alert before and after breaks"
+msgstr ""
+
+# plugin/audiblealert
+msgid "Play audible alert before breaks"
+msgstr ""
+
+# plugin/audiblealert
+msgid "Play audible alert after breaks"
+msgstr ""
+
+# plugin/donotdisturb
+msgid "Do Not Disturb"
+msgstr ""
+
+# plugin/donotdisturb
+msgid "Skip break if the active window is in fullscreen mode"
+msgstr ""
+
+# plugin/donotdisturb
+msgid "Do not interrupt these windows anytime"
+msgstr ""
+
+# plugin/donotdisturb
+msgid "Interrupt these windows regardless of their state"
+msgstr ""
+
+# plugin/donotdisturb
+msgid "Switch the interruptible windows to normal mode"
+msgstr ""
+
+# plugin/donotdisturb
+msgid "Do not disturb while on battery"
+msgstr ""
+
+# plugin/healthstats
+msgid "Health Statistics"
+msgstr ""
+
+# plugin/healthstats
+msgid "Show statistics based on how you use Safe Eyes"
+msgstr ""
+
+# plugin/healthstats
+msgid "Statistics reset interval (cron expression)"
+msgstr ""
+
+# plugin/notification
+msgid "Notification"
+msgstr ""
+
+# plugin/notification
+msgid "Show a system notification before breaks"
+msgstr ""
+
+# plugin/notification
+#, python-format
+msgid "Ready for a short break in %s seconds"
+msgstr ""
+
+# plugin/notification
+#, python-format
+msgid "Ready for a long break in %s seconds"
+msgstr ""
+
+# plugin/screensaver
+msgid "Screensaver"
+msgstr ""
+
+# plugin/screensaver
+msgid "Lock the screen after long breaks by starting screensaver"
+msgstr ""
+
+# plugin/screensaver
+msgid "Custom screensaver command"
+msgstr ""
+
+# plugin/screensaver
+msgid "Minimum seconds to skip without screensaver"
+msgstr ""
+
+# plugin/screensaver
+msgid "Lock screen"
+msgstr ""
+
+# plugin/smartpause
+msgid "Smart Pause"
+msgstr ""
+
+# plugin/smartpause
+msgid "Pause Safe Eyes if the system is idle"
+msgstr ""
+
+# plugin/smartpause
+msgid "Minimum idle time to pause Safe Eyes (in seconds)"
+msgstr ""
+
+# plugin/smartpause
+msgid "Interpret idle time equivalent to upcoming break duration as a break"
+msgstr ""
+
+# plugin/smartpause
+msgid "Postpone the next break until the system becomes idle"
+msgstr ""
+
+#: plugins/trayicon
+msgid "Tray Icon"
+msgstr ""
+
+#: plugins/trayicon
+msgid "Show a tray icon in the notification area"
+msgstr ""
+
+#: plugins/trayicon
+msgid "Show next break time in tray icon"
+msgstr ""
+
+#: plugins/trayicon
+msgid "Allow disabling Safe Eyes"
+msgstr ""
+
+#: plugins/trayicon
+msgid "About"
+msgstr ""
+
+#: plugins/trayicon
+msgid "Disable Safe Eyes"
+msgstr ""
+
+#: plugins/trayicon
+#, python-format
+msgid "Disabled until %s"
+msgstr ""
+
+#: plugins/trayicon
+msgid "Disabled until restart"
+msgstr ""
+
+#: plugins/trayicon
+msgid "Enable Safe Eyes"
+msgstr ""
+
+#: plugins/trayicon
+#, python-format
+msgid "For %(num)d Hour"
+msgid_plural "For %(num)d Hours"
+msgstr[0] ""
+msgstr[1] ""
+
+#: plugins/trayicon
+#, python-format
+msgid "For %(num)d Minute"
+msgid_plural "For %(num)d Minutes"
+msgstr[0] ""
+msgstr[1] ""
+
+#: plugins/trayicon
+#, python-format
+msgid "For %(num)d Second"
+msgid_plural "For %(num)d Seconds"
+msgstr[0] ""
+msgstr[1] ""
+
+#: plugins/trayicon
+#, python-format
+msgid "Next break at %s"
+msgstr ""
+
+#: plugins/trayicon
+msgid "No Breaks Available"
+msgstr ""
+
+#: plugins/trayicon
+msgid "Settings"
+msgstr ""
+
+#: plugins/trayicon
+msgid "Take a break now"
+msgstr ""
+
+#: plugins/trayicon
+msgid "Any break"
+msgstr ""
+
+#: plugins/trayicon
+msgid "Short break"
+msgstr ""
+
+#: plugins/trayicon
+msgid "Long break"
+msgstr ""
+
+#: plugins/trayicon
+msgid "Until restart"
+msgstr ""
+
+#: plugins/trayicon
+msgid "Quit"
+msgstr ""
+
+# plugin/mediacontrol
+msgid "Media Control"
+msgstr ""
+
+# plugin/mediacontrol
+msgid "Pause media players from the break screen"
+msgstr ""
+
+# plugin/mediacontrol
+msgid "Pause media"
+msgstr ""
+
+# plugin/limitconsecutiveskipping
+msgid "Limit Consecutive Skipping"
+msgstr ""
+
+# plugin/limitconsecutiveskipping
+msgid "How many skips or postpones are allowed in a row"
+msgstr ""
+
+# plugin/limitconsecutiveskipping
+msgid "Limit how many breaks can be skipped or postponed in a row"
+msgstr ""
+
+# plugin/limitconsecutiveskipping
+#, python-format
+msgid "Skipped or postponed %(num)d/%(allowed)d breaks in a row"
+msgstr ""
+
+# safeeyes/platform/io.github.slgobinath.SafeEyes.desktop
+msgid "RSI Prevention"
+msgstr ""
+
+msgid ""
+"Please install service providing tray icons for your desktop environment."
+msgstr ""
+
+#, python-format
+msgid "Next long break at %s"
+msgstr ""
+
+#, python-format
+msgid "Next breaks at %(short)s/%(long)s"
+msgstr ""
+
+#, python-format
+msgid "The required plugin '%s' is missing dependencies!"
+msgstr ""
+
+msgid ""
+"Please install the dependencies or disable the plugin. To hide this message, "
+"you can also deactivate the plugin in the settings."
+msgstr ""
+
+msgid "Click here for more information"
+msgstr ""
+
+msgid "Disable plugin temporarily"
+msgstr ""
+
+msgid "Disable permanently"
+msgstr ""
+
+msgid "License:"
+msgstr ""
diff --git a/safeeyes/config/locale/ca/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/ca/LC_MESSAGES/safeeyes.po
index 78468aac..1ec09e5d 100644
--- a/safeeyes/config/locale/ca/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/ca/LC_MESSAGES/safeeyes.po
@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-08-08 21:25+0000\n"
-"Last-Translator: calbasi \n"
+"PO-Revision-Date: 2024-09-27 12:16+0000\n"
+"Last-Translator: Andrés Martínez \n"
"Language-Team: Catalan \n"
"Language: ca\n"
@@ -15,11 +15,11 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.14-dev\n"
+"X-Generator: Weblate 5.8-dev\n"
# Short break
msgid "Gently close your eyes"
-msgstr ""
+msgstr "Tanqueu els ulls suaument"
# Short break
msgid "Roll your eyes a few times to each side"
@@ -90,6 +90,8 @@ msgid ""
"Safe Eyes is running without an RPC server. Turn it on to use command-line "
"arguments."
msgstr ""
+"Safe Eyes s'està executant sense un servidor RPC. Engegueu-lo per usar els "
+"arguments de la línia de comandaments."
# About dialog
msgid "Close"
@@ -111,7 +113,11 @@ msgstr "Llicència"
# About dialog
msgid "List of Contributors"
-msgstr ""
+msgstr "Llista de col·laboradors"
+
+# About dialog
+msgid "Help us translate this app"
+msgstr "Ajuda'ns a traduir aquesta aplicació"
# Break screen
msgid "Skip"
@@ -135,7 +141,7 @@ msgstr "Temps per preparar-se per a una pausa (en segons)"
# Settings dialog
msgid "Keyboard shortcuts disabled period (in seconds)"
-msgstr ""
+msgstr "Període d'inhabilitació de les dreceres de teclat (en segons)"
# Settings dialog
msgid "Postponement duration (in minutes)"
@@ -155,19 +161,21 @@ msgstr "Permet posposar les pauses"
# Settings dialog
msgid "Persist the internal state"
-msgstr ""
+msgstr "Persisteix l'estat intern"
# Settings dialog
msgid "Use RPC server to receive runtime commands"
-msgstr ""
+msgstr "Empra el servidor RPC per a rebre els comandaments del temps d'execució"
# Settings dialog
msgid "Without the RPC server, command-line commands may not work"
-msgstr ""
+msgstr "Sense el servidor RPC, és possible que els comandaments no funcionen"
# Settings dialog
msgid "Long break interval must be a multiple of short break interval"
msgstr ""
+"Cal que l'interval de pauses llargues siga múltiple de l'interval de pauses "
+"curtes"
# Settings dialog
msgid "Reset"
@@ -192,7 +200,7 @@ msgstr "Pauses llargues"
# Settings dialog
msgid "Delete"
-msgstr "Suprimeix"
+msgstr "Esborra"
# Settings dialog
msgid "Are you sure you want to delete this break?"
@@ -236,7 +244,7 @@ msgstr "Trieu"
# Settings dialog
msgid "Please select an image"
-msgstr "Si us plau, trieu una imatge"
+msgstr "Trieu una imatge"
# Settings dialog
msgid "Duration"
@@ -269,26 +277,26 @@ msgstr "Preferències del complement"
# Settings dialog
#, python-format
msgid "Plugin does not support %s desktop environment"
-msgstr ""
+msgstr "El complement no admet l'entorn d'escriptori %s"
# Settings dialog
#, python-format
msgid "Please install the Python module '%s'"
-msgstr ""
+msgstr "Instal·leu el mòdul de Python '%s'"
# Settings dialog
#, python-format
msgid "Please install the command-line tool '%s'"
-msgstr ""
+msgstr "Instal·leu la ferramenta de la línia de comandament '%s'"
# Settings dialog
msgid "Invalid cron expression '%s'"
-msgstr ""
+msgstr "Expressió cron no vàlida '%s'"
# Settings dialog
#, python-format
msgid "Please add the resource %(resource)s to %(config_resource)s directory"
-msgstr ""
+msgstr "Afegiu el recurs %(resource)s al directori %(config_resource)s"
# Settings dialog
msgid "New Break"
@@ -312,15 +320,15 @@ msgstr "Alerta audible"
# plugin/audiblealert
msgid "Play audible alert before and after breaks"
-msgstr ""
+msgstr "Reprodueix una alerta audible abans i després de les pauses"
# plugin/audiblealert
msgid "Play audible alert before breaks"
-msgstr ""
+msgstr "Reprodueix una alerta audible abans de les pauses"
# plugin/audiblealert
msgid "Play audible alert after breaks"
-msgstr ""
+msgstr "Reprodueix una alerta audible després de les pauses"
# plugin/donotdisturb
msgid "Do Not Disturb"
@@ -328,23 +336,23 @@ msgstr "No molesteu"
# plugin/donotdisturb
msgid "Skip break if the active window is in fullscreen mode"
-msgstr ""
+msgstr "Omet la pausa si la finestra activa està en mode pantalla completa"
# plugin/donotdisturb
msgid "Do not interrupt these windows anytime"
-msgstr ""
+msgstr "No interrompis aquestes finestres mai"
# plugin/donotdisturb
msgid "Interrupt these windows regardless of their state"
-msgstr ""
+msgstr "Interromp aquestes finestres independentment del seu estat"
# plugin/donotdisturb
msgid "Switch the interruptible windows to normal mode"
-msgstr ""
+msgstr "Canviar les finestres interruptibles al mode normal"
# plugin/donotdisturb
msgid "Do not disturb while on battery"
-msgstr ""
+msgstr "No molestar quan s'utilitza la bateria"
# plugin/healthstats
msgid "Health Statistics"
@@ -352,24 +360,24 @@ msgstr "Estadístiques de salut"
# plugin/healthstats
msgid "Show statistics based on how you use Safe Eyes"
-msgstr ""
+msgstr "Mostra estadístiques de com useu Safe Eyes"
# plugin/healthstats
msgid "Statistics reset interval (cron expression)"
-msgstr ""
+msgstr "Interval de reinici de les estadístiques (expressió cron)"
# plugin/notification
msgid "Notification"
-msgstr ""
+msgstr "Notificació"
# plugin/notification
msgid "Show a system notification before breaks"
-msgstr ""
+msgstr "Mostra una notificació del sistema abans de les pauses"
# plugin/notification
#, python-format
msgid "Ready for a short break in %s seconds"
-msgstr ""
+msgstr "Preparat per a una pausa breu en %s segons"
# plugin/notification
#, python-format
diff --git a/safeeyes/config/locale/cs/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/cs/LC_MESSAGES/safeeyes.po
index 2af07cc2..d166beba 100644
--- a/safeeyes/config/locale/cs/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/cs/LC_MESSAGES/safeeyes.po
@@ -6,20 +6,20 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2023-10-31 16:04+0000\n"
-"Last-Translator: Kryštof Jelínek \n"
+"PO-Revision-Date: 2024-08-27 19:09+0000\n"
+"Last-Translator: vikdevelop \n"
"Language-Team: Czech \n"
"Language: cs\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
-"X-Generator: Weblate 5.2-dev\n"
+"Plural-Forms: nplurals=3; plural=((n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2);\n"
+"X-Generator: Weblate 5.7.1-dev\n"
# Short break
msgid "Gently close your eyes"
-msgstr ""
+msgstr "Jemně zavřete své oči"
# Short break
msgid "Roll your eyes a few times to each side"
@@ -112,7 +112,11 @@ msgstr "Licence"
# About dialog
msgid "List of Contributors"
-msgstr ""
+msgstr "Seznam přispěvatelů"
+
+# About dialog
+msgid "Help us translate this app"
+msgstr "Pomozte nám přeložit tuto aplikaci"
# Break screen
msgid "Skip"
@@ -499,15 +503,15 @@ msgstr "Udělat si přestávku"
#: plugins/trayicon
msgid "Any break"
-msgstr ""
+msgstr "Jakákoliv přestávka"
#: plugins/trayicon
msgid "Short break"
-msgstr ""
+msgstr "Krátká přestávka"
#: plugins/trayicon
msgid "Long break"
-msgstr ""
+msgstr "Dlouhá přestávka"
#: plugins/trayicon
msgid "Until restart"
@@ -531,57 +535,61 @@ msgstr "Pozastavit média"
# plugin/limitconsecutiveskipping
msgid "Limit Consecutive Skipping"
-msgstr ""
+msgstr "Omezení po sobě jdoucích přeskočení"
# plugin/limitconsecutiveskipping
msgid "How many skips or postpones are allowed in a row"
-msgstr ""
+msgstr "Kolik přeskočení nebo odložení je povoleno v řadě za sebou"
# plugin/limitconsecutiveskipping
msgid "Limit how many breaks can be skipped or postponed in a row"
-msgstr ""
+msgstr "Omezit počet přestávek, které lze vynechat nebo odložit za sebou"
# plugin/limitconsecutiveskipping
#, python-format
msgid "Skipped or postponed %(num)d/%(allowed)d breaks in a row"
-msgstr ""
+msgstr "Vynechané nebo odložené %(num)d/%(allowed)d přestávky za sebou"
# safeeyes/platform/io.github.slgobinath.SafeEyes.desktop
msgid "RSI Prevention"
-msgstr ""
+msgstr "Prevence poranění z opakovaného namáhání (RSI)"
msgid ""
"Please install service providing tray icons for your desktop environment."
msgstr ""
+"Nainstalujte prosím službu poskytující ikony na panelu pro vaše desktopové "
+"prostředí."
#, python-format
msgid "Next long break at %s"
-msgstr ""
+msgstr "Další dlouhá přestávka za %s"
#, python-format
msgid "Next breaks at %(short)s/%(long)s"
-msgstr ""
+msgstr "Další přestávky za %(short)s/%(long)s"
#, python-format
msgid "The required plugin '%s' is missing dependencies!"
-msgstr ""
+msgstr "Požadovanému zásuvnému modulu '%s' chybí závislosti!"
msgid ""
"Please install the dependencies or disable the plugin. To hide this message, "
"you can also deactivate the plugin in the settings."
msgstr ""
+"Nainstalujte prosím požadované závislosti nebo zakažte tento zásuvný modul. "
+"Pro skrytí této zprávy, můžete také deaktivovat zásuvný modul v nastavení."
msgid "Click here for more information"
-msgstr ""
+msgstr "Klikněte zde pro více informací"
msgid "Disable plugin temporarily"
-msgstr ""
+msgstr "Zakázat zásuvný modul dočasně"
msgid "Disable permanently"
-msgstr ""
+msgstr "Zakázat permanentně"
msgid "License:"
-msgstr ""
+msgstr "Licence:"
# Short break
#~ msgid "Tightly close your eyes"
diff --git a/safeeyes/config/locale/da/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/da/LC_MESSAGES/safeeyes.po
index 8fddb464..eefa676e 100644
--- a/safeeyes/config/locale/da/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/da/LC_MESSAGES/safeeyes.po
@@ -112,6 +112,10 @@ msgstr "Licens"
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr "Spring over"
diff --git a/safeeyes/config/locale/de/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/de/LC_MESSAGES/safeeyes.po
index 52084f63..13eeadcd 100644
--- a/safeeyes/config/locale/de/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/de/LC_MESSAGES/safeeyes.po
@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2024-07-28 15:09+0000\n"
-"Last-Translator: Ettore Atalan \n"
+"PO-Revision-Date: 2024-09-21 15:40+0000\n"
+"Last-Translator: Erik Michelson \n"
"Language-Team: German \n"
"Language: de\n"
@@ -15,11 +15,11 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 5.7-dev\n"
+"X-Generator: Weblate 5.8-dev\n"
# Short break
msgid "Gently close your eyes"
-msgstr ""
+msgstr "Schließe sanft deine Augen"
# Short break
msgid "Roll your eyes a few times to each side"
@@ -115,6 +115,10 @@ msgstr "Lizenz"
msgid "List of Contributors"
msgstr "Liste der Mitwirkenden"
+# About dialog
+msgid "Help us translate this app"
+msgstr "Hilf mit die Anwendung zu übersetzen"
+
# Break screen
msgid "Skip"
msgstr "Überspringen"
@@ -549,7 +553,8 @@ msgstr ""
# plugin/limitconsecutiveskipping
#, python-format
msgid "Skipped or postponed %(num)d/%(allowed)d breaks in a row"
-msgstr "%(num)d/%(allowed)d Pausen hintereinander übersprungen oder aufgeschoben"
+msgstr ""
+"%(num)d/%(allowed)d Pausen hintereinander übersprungen oder aufgeschoben"
# safeeyes/platform/io.github.slgobinath.SafeEyes.desktop
msgid "RSI Prevention"
@@ -591,7 +596,7 @@ msgid "Disable permanently"
msgstr "Permanent ausschalten"
msgid "License:"
-msgstr ""
+msgstr "Lizenz:"
# Short break
#~ msgid "Tightly close your eyes"
diff --git a/safeeyes/config/locale/en_US/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/en_US/LC_MESSAGES/safeeyes.po
index 18206b1b..dca10177 100644
--- a/safeeyes/config/locale/en_US/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/en_US/LC_MESSAGES/safeeyes.po
@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2017-09-17 07:59-0400\n"
-"PO-Revision-Date: 2021-07-04 07:32+0000\n"
-"Last-Translator: J. Lavoie \n"
+"PO-Revision-Date: 2024-08-07 15:09+0000\n"
+"Last-Translator: Archisman Panigrahi \n"
"Language-Team: English (United States) \n"
"Language: en_US\n"
@@ -15,12 +15,12 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.8-dev\n"
+"X-Generator: Weblate 5.7-dev\n"
"Generated-By: pygettext.py 1.5\n"
# Short break
msgid "Gently close your eyes"
-msgstr ""
+msgstr "Gently close your eyes"
# Short break
msgid "Roll your eyes a few times to each side"
@@ -115,6 +115,10 @@ msgstr "License"
msgid "List of Contributors"
msgstr "List of Contributors"
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr "Skip"
diff --git a/safeeyes/config/locale/eo/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/eo/LC_MESSAGES/safeeyes.po
index c59ff715..aea50168 100644
--- a/safeeyes/config/locale/eo/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/eo/LC_MESSAGES/safeeyes.po
@@ -113,6 +113,10 @@ msgstr "Licenco"
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr "Preterpasi"
diff --git a/safeeyes/config/locale/es/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/es/LC_MESSAGES/safeeyes.po
index ecdc2fce..d5da4c82 100644
--- a/safeeyes/config/locale/es/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/es/LC_MESSAGES/safeeyes.po
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2024-08-05 23:09+0000\n"
+"PO-Revision-Date: 2024-09-02 07:09+0000\n"
"Last-Translator: gallegonovato \n"
"Language-Team: Spanish \n"
@@ -15,11 +15,11 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 5.7-dev\n"
+"X-Generator: Weblate 5.8-dev\n"
# Short break
msgid "Gently close your eyes"
-msgstr ""
+msgstr "Cierra los ojos suavemente"
# Short break
msgid "Roll your eyes a few times to each side"
@@ -114,6 +114,10 @@ msgstr "Licencia"
msgid "List of Contributors"
msgstr "Colaboradores"
+# About dialog
+msgid "Help us translate this app"
+msgstr "Ayúdanos a traducir esta aplicación"
+
# Break screen
msgid "Skip"
msgstr "Saltar"
diff --git a/safeeyes/config/locale/et/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/et/LC_MESSAGES/safeeyes.po
index fc11c99e..97276086 100644
--- a/safeeyes/config/locale/et/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/et/LC_MESSAGES/safeeyes.po
@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-02-18 00:50+0000\n"
-"Last-Translator: Kristjan Räts \n"
+"PO-Revision-Date: 2024-11-12 23:00+0000\n"
+"Last-Translator: Priit Jõerüüt \n"
"Language-Team: Estonian \n"
"Language: et\n"
@@ -15,11 +15,11 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.5\n"
+"X-Generator: Weblate 5.9-dev\n"
# Short break
msgid "Gently close your eyes"
-msgstr ""
+msgstr "Sulge õrnalt oma silmad"
# Short break
msgid "Roll your eyes a few times to each side"
@@ -103,7 +103,7 @@ msgid ""
"Safe Eyes protects your eyes from eye strain (asthenopia) by reminding you "
"to take breaks while you're working long hours at the computer"
msgstr ""
-"Safe Eyes aitab vähendada arvutiga töötamisel silmade väsimust, tuletades "
+"Safe Eyes aitab arvutiga töötamisel vähendada silmade väsimust, tuletades "
"meelde puhkepause"
# About dialog
@@ -112,7 +112,11 @@ msgstr "Litsents"
# About dialog
msgid "List of Contributors"
-msgstr ""
+msgstr "Kaasautorite loend"
+
+# About dialog
+msgid "Help us translate this app"
+msgstr "Aita meil seda rakendust tõlkida"
# Break screen
msgid "Skip"
@@ -124,7 +128,7 @@ msgstr "Lükka edasi"
# Settings dialog
msgid "Break duration (in seconds)"
-msgstr "Pausi kestvus (sekundites)"
+msgstr "Pausi kestus (sekundites)"
# Settings dialog
msgid "Interval between two breaks (in minutes)"
@@ -240,7 +244,7 @@ msgstr "Palun vali pilt"
# Settings dialog
msgid "Duration"
-msgstr "Kestvus"
+msgstr "Kestus"
# Settings dialog
msgid "Time to wait"
@@ -252,11 +256,11 @@ msgstr "Muuda vaikimisi seadeid"
# Settings dialog
msgid "Time (in seconds)"
-msgstr "Kestvus (sekundites)"
+msgstr "Kestus (sekundites)"
# Settings dialog
msgid "Time (in minutes)"
-msgstr "Kestvus (minutites)"
+msgstr "Kestus (minutites)"
# Settings dialog
msgid "Break Settings"
@@ -493,15 +497,15 @@ msgstr "Tee nüüd paus"
#: plugins/trayicon
msgid "Any break"
-msgstr ""
+msgstr "Iga puhkepaus"
#: plugins/trayicon
msgid "Short break"
-msgstr ""
+msgstr "Lühike puhkepaus"
#: plugins/trayicon
msgid "Long break"
-msgstr ""
+msgstr "Pikk puhkepaus"
#: plugins/trayicon
msgid "Until restart"
@@ -525,57 +529,61 @@ msgstr "Peata meedia"
# plugin/limitconsecutiveskipping
msgid "Limit Consecutive Skipping"
-msgstr ""
+msgstr "Piira järjest vahelejätmisi"
# plugin/limitconsecutiveskipping
msgid "How many skips or postpones are allowed in a row"
-msgstr ""
+msgstr "Kui mitu edasilükkamist või vahelejätmist võid järjest teha"
# plugin/limitconsecutiveskipping
msgid "Limit how many breaks can be skipped or postponed in a row"
-msgstr ""
+msgstr "Kui mitu pausi võid järjest vahele jätta või edasi lükata"
# plugin/limitconsecutiveskipping
#, python-format
msgid "Skipped or postponed %(num)d/%(allowed)d breaks in a row"
-msgstr ""
+msgstr "Järjest vahelejäetud või edasilükatatud %(num)d/%(allowed)d pausi"
# safeeyes/platform/io.github.slgobinath.SafeEyes.desktop
msgid "RSI Prevention"
-msgstr ""
+msgstr "RSI ennetus"
msgid ""
"Please install service providing tray icons for your desktop environment."
msgstr ""
+"Palun paigalda teenus, mis võimaldab sinu töölauakeskkonnas kasutada "
+"süsteemisalve."
#, python-format
msgid "Next long break at %s"
-msgstr ""
+msgstr "Järgmine pikk puhkepaus %s"
#, python-format
msgid "Next breaks at %(short)s/%(long)s"
-msgstr ""
+msgstr "Järgmised puhkepausid %(short)s/%(long)s"
#, python-format
msgid "The required plugin '%s' is missing dependencies!"
-msgstr ""
+msgstr "Vajalikul „%s“ pluginal puuduvad sõltuvad komponendid!"
msgid ""
"Please install the dependencies or disable the plugin. To hide this message, "
"you can also deactivate the plugin in the settings."
msgstr ""
+"Palun lisa vajalikud komponendid või lülita plugin välja. Viimast saad teha "
+"seadistustest ja sellega ei teki enam ka antud teadet."
msgid "Click here for more information"
-msgstr ""
+msgstr "Lisateabeks klõpsi siin"
msgid "Disable plugin temporarily"
-msgstr ""
+msgstr "Lülita plugin ajutiselt välja"
msgid "Disable permanently"
-msgstr ""
+msgstr "Lülita püsivalt välja"
msgid "License:"
-msgstr ""
+msgstr "Litsents:"
# Short break
#~ msgid "Tightly close your eyes"
diff --git a/safeeyes/config/locale/eu/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/eu/LC_MESSAGES/safeeyes.po
index 9cb9138e..399796f4 100644
--- a/safeeyes/config/locale/eu/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/eu/LC_MESSAGES/safeeyes.po
@@ -114,6 +114,10 @@ msgstr "Lizentzia"
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr "Saltatu"
diff --git a/safeeyes/config/locale/fa/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/fa/LC_MESSAGES/safeeyes.po
index 1eb96c89..817384ce 100644
--- a/safeeyes/config/locale/fa/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/fa/LC_MESSAGES/safeeyes.po
@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2024-07-28 15:09+0000\n"
-"Last-Translator: Parsa Nobahari \n"
+"PO-Revision-Date: 2024-09-20 00:40+0000\n"
+"Last-Translator: Danial Behzadi \n"
"Language-Team: Persian \n"
"Language: fa\n"
@@ -15,11 +15,11 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 5.7-dev\n"
+"X-Generator: Weblate 5.8-dev\n"
# Short break
msgid "Gently close your eyes"
-msgstr ""
+msgstr "چشمانتان را آرام ببندید"
# Short break
msgid "Roll your eyes a few times to each side"
@@ -114,6 +114,10 @@ msgstr "پروانه"
msgid "List of Contributors"
msgstr "لیست مشارکتکنندگان"
+# About dialog
+msgid "Help us translate this app"
+msgstr "کمک به ترجمهٔ این کاره"
+
# Break screen
msgid "Skip"
msgstr "ردکن"
@@ -577,7 +581,7 @@ msgid "Disable permanently"
msgstr "غیرفعال کردن دائمی"
msgid "License:"
-msgstr ""
+msgstr "پروانه:"
# Short break
#~ msgid "Tightly close your eyes"
diff --git a/safeeyes/config/locale/fr/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/fr/LC_MESSAGES/safeeyes.po
index 66816dde..4cfc6cfb 100644
--- a/safeeyes/config/locale/fr/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/fr/LC_MESSAGES/safeeyes.po
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-01-11 15:55+0000\n"
+"PO-Revision-Date: 2024-11-12 23:00+0000\n"
"Last-Translator: AO Localisation Lab \n"
"Language-Team: French \n"
@@ -15,11 +15,11 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.10.1\n"
+"X-Generator: Weblate 5.9-dev\n"
# Short break
msgid "Gently close your eyes"
-msgstr ""
+msgstr "Fermez doucement les yeux"
# Short break
msgid "Roll your eyes a few times to each side"
@@ -113,7 +113,11 @@ msgstr "Licence"
# About dialog
msgid "List of Contributors"
-msgstr ""
+msgstr "Liste des contributeurs"
+
+# About dialog
+msgid "Help us translate this app"
+msgstr "Aidez-nous à traduire cette appli"
# Break screen
msgid "Skip"
@@ -506,15 +510,15 @@ msgstr "Prendre une pause maintenant"
#: plugins/trayicon
msgid "Any break"
-msgstr ""
+msgstr "N’importe quelle pause"
#: plugins/trayicon
msgid "Short break"
-msgstr ""
+msgstr "Pause courte"
#: plugins/trayicon
msgid "Long break"
-msgstr ""
+msgstr "Pause longue"
#: plugins/trayicon
msgid "Until restart"
@@ -522,7 +526,7 @@ msgstr "Jusqu’au redémarrage"
#: plugins/trayicon
msgid "Quit"
-msgstr "Fermer"
+msgstr "Quitter"
# plugin/mediacontrol
msgid "Media Control"
@@ -538,57 +542,61 @@ msgstr "Mettre le contenu multimédia en pause"
# plugin/limitconsecutiveskipping
msgid "Limit Consecutive Skipping"
-msgstr ""
+msgstr "Limiter les sauts de pause consécutifs"
# plugin/limitconsecutiveskipping
msgid "How many skips or postpones are allowed in a row"
-msgstr ""
+msgstr "Nombre de sauts ou de reports autorisés d’affilée"
# plugin/limitconsecutiveskipping
msgid "Limit how many breaks can be skipped or postponed in a row"
-msgstr ""
+msgstr "Limiter le nombre de pauses sautées ou reportées d’affilée"
# plugin/limitconsecutiveskipping
#, python-format
msgid "Skipped or postponed %(num)d/%(allowed)d breaks in a row"
-msgstr ""
+msgstr "%(num)d/%(allowed)d pauses sautées ou reportées d’affilée"
# safeeyes/platform/io.github.slgobinath.SafeEyes.desktop
msgid "RSI Prevention"
-msgstr ""
+msgstr "Prévention des lésions attribuables au travail répétitif"
msgid ""
"Please install service providing tray icons for your desktop environment."
msgstr ""
+"Installez le service qui fournit les icônes de la barre d’état pour votre "
+"environnement de bureau."
#, python-format
msgid "Next long break at %s"
-msgstr ""
+msgstr "Prochaine pause longue à %s"
#, python-format
msgid "Next breaks at %(short)s/%(long)s"
-msgstr ""
+msgstr "Prochaines pauses à %(short)s/%(long)s"
#, python-format
msgid "The required plugin '%s' is missing dependencies!"
-msgstr ""
+msgstr "Il manque des dépendances pour le greffon « %s » nécessaire"
msgid ""
"Please install the dependencies or disable the plugin. To hide this message, "
"you can also deactivate the plugin in the settings."
msgstr ""
+"Installez les dépendances ou désactivez le greffon. Pour ne plus afficher ce "
+"message, vous pouvez aussi désactiver le greffon dans les paramètres."
msgid "Click here for more information"
-msgstr ""
+msgstr "Cliquer ici pour plus de précisions"
msgid "Disable plugin temporarily"
-msgstr ""
+msgstr "Désactivation temporaire du greffon"
msgid "Disable permanently"
-msgstr ""
+msgstr "Désactivation permanente"
msgid "License:"
-msgstr ""
+msgstr "Licence :"
# Short break
#~ msgid "Tightly close your eyes"
diff --git a/safeeyes/config/locale/he/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/he/LC_MESSAGES/safeeyes.po
index f716ad1e..1634d09d 100644
--- a/safeeyes/config/locale/he/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/he/LC_MESSAGES/safeeyes.po
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-05-23 09:32+0000\n"
+"PO-Revision-Date: 2024-11-11 13:00+0000\n"
"Last-Translator: Yaron Shahrabani \n"
"Language-Team: Hebrew \n"
@@ -15,11 +15,11 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Weblate 4.7-dev\n"
+"X-Generator: Weblate 5.8.2\n"
# Short break
msgid "Gently close your eyes"
-msgstr ""
+msgstr "לעצום את העיניים בעדינות"
# Short break
msgid "Roll your eyes a few times to each side"
@@ -110,7 +110,11 @@ msgstr "רישיון"
# About dialog
msgid "List of Contributors"
-msgstr ""
+msgstr "רשימת תורמים"
+
+# About dialog
+msgid "Help us translate this app"
+msgstr "נשמח לסיוע בתרגום היישום הזה"
# Break screen
msgid "Skip"
@@ -491,15 +495,15 @@ msgstr "לקחת הפסקה עכשיו"
#: plugins/trayicon
msgid "Any break"
-msgstr ""
+msgstr "כל הפסקה שהיא"
#: plugins/trayicon
msgid "Short break"
-msgstr ""
+msgstr "הפסקה קצרה"
#: plugins/trayicon
msgid "Long break"
-msgstr ""
+msgstr "הפסקה ארוכה"
#: plugins/trayicon
msgid "Until restart"
@@ -523,57 +527,59 @@ msgstr "השהיית מדיה"
# plugin/limitconsecutiveskipping
msgid "Limit Consecutive Skipping"
-msgstr ""
+msgstr "הגבלת דילוג מחזורי"
# plugin/limitconsecutiveskipping
msgid "How many skips or postpones are allowed in a row"
-msgstr ""
+msgstr "כמה דילוגים או השהיות מותר ברצף"
# plugin/limitconsecutiveskipping
msgid "Limit how many breaks can be skipped or postponed in a row"
-msgstr ""
+msgstr "הגבלת כמות ההפסקות שאפשר לדלג או להשהות ברצף"
# plugin/limitconsecutiveskipping
#, python-format
msgid "Skipped or postponed %(num)d/%(allowed)d breaks in a row"
-msgstr ""
+msgstr "דילגת או השהית %(num)d/%(allowed)d הפסקות ברצף"
# safeeyes/platform/io.github.slgobinath.SafeEyes.desktop
msgid "RSI Prevention"
-msgstr ""
+msgstr "מניעת פציעת מאמץ חוזרני"
msgid ""
"Please install service providing tray icons for your desktop environment."
-msgstr ""
+msgstr "נא להתקין שירות שמספק סמלי שורת מערכת לסביבת שולחן העבודה שלך."
#, python-format
msgid "Next long break at %s"
-msgstr ""
+msgstr "ההפסקה הארוכה הבאה ב־%s"
#, python-format
msgid "Next breaks at %(short)s/%(long)s"
-msgstr ""
+msgstr "ההפסקות הבאות ב־%(short)s/%(long)s"
#, python-format
msgid "The required plugin '%s' is missing dependencies!"
-msgstr ""
+msgstr "לתוסף ההכרחי ‚%s’ חסרות תלויות!"
msgid ""
"Please install the dependencies or disable the plugin. To hide this message, "
"you can also deactivate the plugin in the settings."
msgstr ""
+"נא להתקין את התלויות או להשבית את התוסף. כדי להסתיר את ההודעה הזאת ניתן גם "
+"להשבית את התוסף בהגדרות."
msgid "Click here for more information"
-msgstr ""
+msgstr "לחיצה כאן תציג מידע נוסף"
msgid "Disable plugin temporarily"
-msgstr ""
+msgstr "השבתת תוסף זמנית"
msgid "Disable permanently"
-msgstr ""
+msgstr "השבתה לצמיתות"
msgid "License:"
-msgstr ""
+msgstr "רישיון:"
# Short break
#~ msgid "Tightly close your eyes"
diff --git a/safeeyes/config/locale/hi/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/hi/LC_MESSAGES/safeeyes.po
index cb6101a7..d2e4ecab 100644
--- a/safeeyes/config/locale/hi/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/hi/LC_MESSAGES/safeeyes.po
@@ -110,6 +110,10 @@ msgstr "लाइसेंस"
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr "छोड़ें"
diff --git a/safeeyes/config/locale/hu/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/hu/LC_MESSAGES/safeeyes.po
index 6abb5c61..c7017ada 100644
--- a/safeeyes/config/locale/hu/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/hu/LC_MESSAGES/safeeyes.po
@@ -110,6 +110,10 @@ msgstr "Licensz"
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr "Kihagyás"
diff --git a/safeeyes/config/locale/id/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/id/LC_MESSAGES/safeeyes.po
index 54eda328..4d5db377 100644
--- a/safeeyes/config/locale/id/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/id/LC_MESSAGES/safeeyes.po
@@ -112,6 +112,10 @@ msgstr "Lisensi"
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr "Lewati"
diff --git a/safeeyes/config/locale/it/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/it/LC_MESSAGES/safeeyes.po
index 09584d2b..b8d830ab 100644
--- a/safeeyes/config/locale/it/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/it/LC_MESSAGES/safeeyes.po
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2024-07-02 12:09+0000\n"
+"PO-Revision-Date: 2024-08-27 19:09+0000\n"
"Last-Translator: albanobattistella \n"
"Language-Team: Italian \n"
@@ -15,11 +15,11 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 5.7-dev\n"
+"X-Generator: Weblate 5.7.1-dev\n"
# Short break
msgid "Gently close your eyes"
-msgstr ""
+msgstr "Chiudi dolcemente gli occhi"
# Short break
msgid "Roll your eyes a few times to each side"
@@ -114,6 +114,10 @@ msgstr "Licenza"
msgid "List of Contributors"
msgstr "Elenco dei contributori"
+# About dialog
+msgid "Help us translate this app"
+msgstr "Aiutaci a tradurre questa app"
+
# Break screen
msgid "Skip"
msgstr "Salta"
@@ -587,7 +591,7 @@ msgid "Disable permanently"
msgstr "Disattivare in modo permanente"
msgid "License:"
-msgstr ""
+msgstr "Licenza:"
# Short break
#~ msgid "Tightly close your eyes"
diff --git a/safeeyes/config/locale/kn/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/kn/LC_MESSAGES/safeeyes.po
index e829bec9..407426d9 100644
--- a/safeeyes/config/locale/kn/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/kn/LC_MESSAGES/safeeyes.po
@@ -112,6 +112,10 @@ msgstr "ಪರವಾನಿಗೆ"
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr ""
diff --git a/safeeyes/config/locale/ko/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/ko/LC_MESSAGES/safeeyes.po
index bbdc5af6..43b678bf 100644
--- a/safeeyes/config/locale/ko/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/ko/LC_MESSAGES/safeeyes.po
@@ -112,6 +112,10 @@ msgstr "라이선스"
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr "넘기기"
diff --git a/safeeyes/config/locale/lt/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/lt/LC_MESSAGES/safeeyes.po
index c712d85d..6f826377 100644
--- a/safeeyes/config/locale/lt/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/lt/LC_MESSAGES/safeeyes.po
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2024-07-02 12:09+0000\n"
+"PO-Revision-Date: 2024-10-14 06:16+0000\n"
"Last-Translator: openSUSE Lietuviškai \n"
"Language-Team: Lithuanian \n"
@@ -14,13 +14,13 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
-"(n%100<10 || n%100>=20) ? 1 : 2);\n"
-"X-Generator: Weblate 5.7-dev\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && ("
+"n%100<10 || n%100>=20) ? 1 : 2);\n"
+"X-Generator: Weblate 5.8-dev\n"
# Short break
msgid "Gently close your eyes"
-msgstr ""
+msgstr "Švelniai užsimerkite"
# Short break
msgid "Roll your eyes a few times to each side"
@@ -113,7 +113,11 @@ msgstr "Licencija"
# About dialog
msgid "List of Contributors"
-msgstr ""
+msgstr "Talkininkų sąrašas"
+
+# About dialog
+msgid "Help us translate this app"
+msgstr "Padėkite mums išversti šią programą"
# Break screen
msgid "Skip"
@@ -533,57 +537,60 @@ msgstr "Pristabdyti mediją"
# plugin/limitconsecutiveskipping
msgid "Limit Consecutive Skipping"
-msgstr ""
+msgstr "Apriboti nuoseklų praleidinėjimą"
# plugin/limitconsecutiveskipping
msgid "How many skips or postpones are allowed in a row"
-msgstr ""
+msgstr "Kiek leidžiama praleisti arba atidėti kartų iš eilės"
# plugin/limitconsecutiveskipping
msgid "Limit how many breaks can be skipped or postponed in a row"
-msgstr ""
+msgstr "Apriboti, kiek kartų galima iš eilės praleisti arba atidėti pertraukų"
# plugin/limitconsecutiveskipping
#, python-format
msgid "Skipped or postponed %(num)d/%(allowed)d breaks in a row"
-msgstr ""
+msgstr "Paeiliui praleistos arba atidėtos pertraukos: %(num)d/%(allowed)d"
# safeeyes/platform/io.github.slgobinath.SafeEyes.desktop
msgid "RSI Prevention"
-msgstr ""
+msgstr "Apsaugokite savo akis nuo įtampos"
msgid ""
"Please install service providing tray icons for your desktop environment."
msgstr ""
+"Prašome įdiegti savo darbalaukio aplinkos sistemos ženkliukų dėklo paslaugą."
#, python-format
msgid "Next long break at %s"
-msgstr ""
+msgstr "Kita ilga pertrauka: %s"
#, python-format
msgid "Next breaks at %(short)s/%(long)s"
-msgstr ""
+msgstr "Kitos pertraukos: %(short)s/%(long)s"
#, python-format
msgid "The required plugin '%s' is missing dependencies!"
-msgstr ""
+msgstr "Reikalingam papildiniui „%s“ trūksta priklausomybių!"
msgid ""
"Please install the dependencies or disable the plugin. To hide this message, "
"you can also deactivate the plugin in the settings."
msgstr ""
+"Prašome įdiegti priklausomybes arba pašalinti papildinį. Norėdami paslėpti "
+"šį pranešimą, taip pat galite išjungti šį papildinį nuostatose."
msgid "Click here for more information"
-msgstr ""
+msgstr "Norėdami sužinoti daugiau, spauskite čia"
msgid "Disable plugin temporarily"
-msgstr ""
+msgstr "Laikinai išjungti papildinį"
msgid "Disable permanently"
-msgstr ""
+msgstr "Išjungti visam laikui"
msgid "License:"
-msgstr ""
+msgstr "Licencija:"
# Short break
#~ msgid "Tightly close your eyes"
diff --git a/safeeyes/config/locale/lv/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/lv/LC_MESSAGES/safeeyes.po
index 28bcc6b1..149e29d7 100644
--- a/safeeyes/config/locale/lv/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/lv/LC_MESSAGES/safeeyes.po
@@ -94,6 +94,10 @@ msgstr "Licence"
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
msgid "Skip"
msgstr "Izlaist"
diff --git a/safeeyes/config/locale/mk/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/mk/LC_MESSAGES/safeeyes.po
index 6c717b35..db3007e8 100644
--- a/safeeyes/config/locale/mk/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/mk/LC_MESSAGES/safeeyes.po
@@ -112,6 +112,10 @@ msgstr ""
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr ""
diff --git a/safeeyes/config/locale/mr/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/mr/LC_MESSAGES/safeeyes.po
index 53406939..add11499 100644
--- a/safeeyes/config/locale/mr/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/mr/LC_MESSAGES/safeeyes.po
@@ -111,6 +111,10 @@ msgstr ""
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr ""
diff --git a/safeeyes/config/locale/nb/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/nb/LC_MESSAGES/safeeyes.po
index 9dcde6ad..5d99e1e4 100644
--- a/safeeyes/config/locale/nb/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/nb/LC_MESSAGES/safeeyes.po
@@ -113,6 +113,10 @@ msgstr "Lisens"
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr "Hopp over"
diff --git a/safeeyes/config/locale/nl/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/nl/LC_MESSAGES/safeeyes.po
index a0dba578..790fc155 100644
--- a/safeeyes/config/locale/nl/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/nl/LC_MESSAGES/safeeyes.po
@@ -115,6 +115,10 @@ msgstr "Licentie"
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr "Overslaan"
diff --git a/safeeyes/config/locale/pl/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/pl/LC_MESSAGES/safeeyes.po
index 227bd122..18696bef 100644
--- a/safeeyes/config/locale/pl/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/pl/LC_MESSAGES/safeeyes.po
@@ -115,6 +115,10 @@ msgstr "Licencja"
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr "Pomiń"
diff --git a/safeeyes/config/locale/pt/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/pt/LC_MESSAGES/safeeyes.po
index 7a51a0e0..197a99ce 100644
--- a/safeeyes/config/locale/pt/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/pt/LC_MESSAGES/safeeyes.po
@@ -115,6 +115,10 @@ msgstr "Licença"
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr "Ignorar"
diff --git a/safeeyes/config/locale/pt_BR/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/pt_BR/LC_MESSAGES/safeeyes.po
index b8eedf57..e3f0d322 100644
--- a/safeeyes/config/locale/pt_BR/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/pt_BR/LC_MESSAGES/safeeyes.po
@@ -114,6 +114,10 @@ msgstr "Licença"
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr "Pular"
diff --git a/safeeyes/config/locale/ru/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/ru/LC_MESSAGES/safeeyes.po
index f8794c53..f0bd9a8b 100644
--- a/safeeyes/config/locale/ru/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/ru/LC_MESSAGES/safeeyes.po
@@ -6,21 +6,21 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2023-11-26 00:02+0000\n"
-"Last-Translator: Almaz Mannanov \n"
+"PO-Revision-Date: 2024-09-06 22:09+0000\n"
+"Last-Translator: AircGroup \n"
"Language-Team: Russian \n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
-"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 5.2.1-rc\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
+"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"X-Generator: Weblate 5.8-dev\n"
# Short break
msgid "Gently close your eyes"
-msgstr ""
+msgstr "Аккуратно закройте глаза"
# Short break
msgid "Roll your eyes a few times to each side"
@@ -113,7 +113,11 @@ msgstr "Лицензия"
# About dialog
msgid "List of Contributors"
-msgstr ""
+msgstr "Список участников проекта"
+
+# About dialog
+msgid "Help us translate this app"
+msgstr "Помоги нам перевести приложение"
# Break screen
msgid "Skip"
@@ -500,15 +504,15 @@ msgstr "Отдохнуть сейчас"
#: plugins/trayicon
msgid "Any break"
-msgstr ""
+msgstr "Сделайте перерыв на что угодно"
#: plugins/trayicon
msgid "Short break"
-msgstr ""
+msgstr "Небольшой перерыв"
#: plugins/trayicon
msgid "Long break"
-msgstr ""
+msgstr "Долгий перерыв"
#: plugins/trayicon
msgid "Until restart"
@@ -532,57 +536,61 @@ msgstr "Приостановить воспроизведение"
# plugin/limitconsecutiveskipping
msgid "Limit Consecutive Skipping"
-msgstr ""
+msgstr "Ограничение пропусков подряд"
# plugin/limitconsecutiveskipping
msgid "How many skips or postpones are allowed in a row"
-msgstr ""
+msgstr "Сколько пропусков или переносов разрешено подряд"
# plugin/limitconsecutiveskipping
msgid "Limit how many breaks can be skipped or postponed in a row"
-msgstr ""
+msgstr "Какое количество перерывов можно пропустить или отложить подряд"
# plugin/limitconsecutiveskipping
#, python-format
msgid "Skipped or postponed %(num)d/%(allowed)d breaks in a row"
-msgstr ""
+msgstr "Пропущенные или отложенные %(num)d/%(allowed)d перерывы подряд"
# safeeyes/platform/io.github.slgobinath.SafeEyes.desktop
msgid "RSI Prevention"
-msgstr ""
+msgstr "Профилактика RSI"
msgid ""
"Please install service providing tray icons for your desktop environment."
msgstr ""
+"Пожалуйста, установите ПО предоставляющий иконки в трее для вашего рабочего "
+"стола."
#, python-format
msgid "Next long break at %s"
-msgstr ""
+msgstr "Следующий длительный перерыв в %s"
#, python-format
msgid "Next breaks at %(short)s/%(long)s"
-msgstr ""
+msgstr "Следующие перерывы %(short)s/%(long)s"
#, python-format
msgid "The required plugin '%s' is missing dependencies!"
-msgstr ""
+msgstr "В требуемом плагине '%s' отсутствуют зависимости!"
msgid ""
"Please install the dependencies or disable the plugin. To hide this message, "
"you can also deactivate the plugin in the settings."
msgstr ""
+"Пожалуйста, установите зависимости или отключите плагин. Чтобы скрыть это "
+"сообщение, вы также можете отключить плагин в настройках."
msgid "Click here for more information"
-msgstr ""
+msgstr "Нажмите здесь для получения дополнительной информации"
msgid "Disable plugin temporarily"
-msgstr ""
+msgstr "Временно отключите плагин"
msgid "Disable permanently"
-msgstr ""
+msgstr "Отключить навсегда"
msgid "License:"
-msgstr ""
+msgstr "Лицензия:"
# Short break
#~ msgid "Tightly close your eyes"
diff --git a/safeeyes/config/locale/safeeyes.pot b/safeeyes/config/locale/safeeyes.pot
index 521c894e..d9fe78c7 100644
--- a/safeeyes/config/locale/safeeyes.pot
+++ b/safeeyes/config/locale/safeeyes.pot
@@ -94,6 +94,10 @@ msgstr ""
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr ""
diff --git a/safeeyes/config/locale/sk/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/sk/LC_MESSAGES/safeeyes.po
index d0e7a3c1..62b479b9 100644
--- a/safeeyes/config/locale/sk/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/sk/LC_MESSAGES/safeeyes.po
@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2024-07-10 11:09+0000\n"
-"Last-Translator: menom \n"
+"PO-Revision-Date: 2024-11-02 20:00+0000\n"
+"Last-Translator: Milan Šalka \n"
"Language-Team: Slovak \n"
"Language: sk\n"
@@ -15,11 +15,11 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=((n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2);\n"
-"X-Generator: Weblate 5.7-dev\n"
+"X-Generator: Weblate 5.8.2\n"
# Short break
msgid "Gently close your eyes"
-msgstr ""
+msgstr "Jemne zavrite oči"
# Short break
msgid "Roll your eyes a few times to each side"
@@ -113,7 +113,11 @@ msgstr "Licencia"
# About dialog
msgid "List of Contributors"
-msgstr ""
+msgstr "Zoznam Prispievateľov"
+
+# About dialog
+msgid "Help us translate this app"
+msgstr "Pomôžte nám preložiť túto aplikáciu"
# Break screen
msgid "Skip"
@@ -529,57 +533,61 @@ msgstr "Pozastaviť média"
# plugin/limitconsecutiveskipping
msgid "Limit Consecutive Skipping"
-msgstr ""
+msgstr "Limit Konzekutívne lyžovanie"
# plugin/limitconsecutiveskipping
msgid "How many skips or postpones are allowed in a row"
-msgstr ""
+msgstr "Koľko preskokov alebo odložiek je povolené v rade"
# plugin/limitconsecutiveskipping
msgid "Limit how many breaks can be skipped or postponed in a row"
-msgstr ""
+msgstr "Limit, koľko prestávky je možné preskočiť alebo odložiť v rade"
# plugin/limitconsecutiveskipping
#, python-format
msgid "Skipped or postponed %(num)d/%(allowed)d breaks in a row"
-msgstr ""
+msgstr "Sklo alebo odložené %(num)d/%(allowed)d prestávky v rade"
# safeeyes/platform/io.github.slgobinath.SafeEyes.desktop
msgid "RSI Prevention"
-msgstr ""
+msgstr "Prevencia RSI"
msgid ""
"Please install service providing tray icons for your desktop environment."
msgstr ""
+"Prosím, nainštalujte službu poskytujúce zásobníkové ikony pre vaše "
+"desktopové prostredie."
#, python-format
msgid "Next long break at %s"
-msgstr ""
+msgstr "Najdlhšia prestávka na %s"
#, python-format
msgid "Next breaks at %(short)s/%(long)s"
-msgstr ""
+msgstr "Ďalšie prestávky na %(short)s/%(long)s"
#, python-format
msgid "The required plugin '%s' is missing dependencies!"
-msgstr ""
+msgstr "Požadovaný plugin '%s chýba závislosti!"
msgid ""
"Please install the dependencies or disable the plugin. To hide this message, "
"you can also deactivate the plugin in the settings."
msgstr ""
+"Prosím, nainštalujte záhady alebo vypnúť plugin. Ak chcete skryť túto "
+"správu, môžete tiež deaktivovať plugin v nastavení."
msgid "Click here for more information"
-msgstr ""
+msgstr "Kliknite tu pre viac informácií"
msgid "Disable plugin temporarily"
-msgstr ""
+msgstr "Disable plugin dočasne"
msgid "Disable permanently"
-msgstr ""
+msgstr "Zakázať trvalo"
msgid "License:"
-msgstr ""
+msgstr "Licencia:"
# Short break
#~ msgid "Tightly close your eyes"
diff --git a/safeeyes/config/locale/sr/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/sr/LC_MESSAGES/safeeyes.po
index d714f8ec..154538ec 100644
--- a/safeeyes/config/locale/sr/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/sr/LC_MESSAGES/safeeyes.po
@@ -115,6 +115,10 @@ msgstr "Лиценца"
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr "Прескочите"
diff --git a/safeeyes/config/locale/sv/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/sv/LC_MESSAGES/safeeyes.po
index eccb600e..d004baee 100644
--- a/safeeyes/config/locale/sv/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/sv/LC_MESSAGES/safeeyes.po
@@ -112,6 +112,10 @@ msgstr "Licens"
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr "Hoppa över"
diff --git a/safeeyes/config/locale/ta/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/ta/LC_MESSAGES/safeeyes.po
index 0ed204b1..db7db2e9 100644
--- a/safeeyes/config/locale/ta/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/ta/LC_MESSAGES/safeeyes.po
@@ -115,6 +115,10 @@ msgstr "மென்பொருள் உரிமம்"
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr "தவிர்"
diff --git a/safeeyes/config/locale/tr/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/tr/LC_MESSAGES/safeeyes.po
index 355de906..830a3af3 100644
--- a/safeeyes/config/locale/tr/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/tr/LC_MESSAGES/safeeyes.po
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2024-06-28 17:09+0000\n"
+"PO-Revision-Date: 2024-09-02 07:09+0000\n"
"Last-Translator: Oğuz Ersen \n"
"Language-Team: Turkish \n"
@@ -15,11 +15,11 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 5.7-dev\n"
+"X-Generator: Weblate 5.8-dev\n"
# Short break
msgid "Gently close your eyes"
-msgstr ""
+msgstr "Yavaşça gözlerinizi kapatın"
# Short break
msgid "Roll your eyes a few times to each side"
@@ -113,7 +113,11 @@ msgstr "Lisans"
# About dialog
msgid "List of Contributors"
-msgstr ""
+msgstr "Katkıda Bulunanların Listesi"
+
+# About dialog
+msgid "Help us translate this app"
+msgstr "Bu uygulamayı çevirmemize yardım edin"
# Break screen
msgid "Skip"
@@ -529,57 +533,60 @@ msgstr "Ortamı duraklat"
# plugin/limitconsecutiveskipping
msgid "Limit Consecutive Skipping"
-msgstr ""
+msgstr "Ardışık Geçmeyi Sınırla"
# plugin/limitconsecutiveskipping
msgid "How many skips or postpones are allowed in a row"
-msgstr ""
+msgstr "Arka arkaya kaç geçmeye veya ertelemeye izin verilir"
# plugin/limitconsecutiveskipping
msgid "Limit how many breaks can be skipped or postponed in a row"
msgstr ""
+"Arka arkaya kaç molanın geçilebileceğini veya ertelenebileceğini sınırlayın"
# plugin/limitconsecutiveskipping
#, python-format
msgid "Skipped or postponed %(num)d/%(allowed)d breaks in a row"
-msgstr ""
+msgstr "Arka arkaya %(num)d/%(allowed)d mola geçildi veya ertelendi"
# safeeyes/platform/io.github.slgobinath.SafeEyes.desktop
msgid "RSI Prevention"
-msgstr ""
+msgstr "Tekrarlayan zorlanma yaralanmalarının önlenmesi"
msgid ""
"Please install service providing tray icons for your desktop environment."
-msgstr ""
+msgstr "Lütfen masaüstü ortamınız için tepsi simgeleri sağlayan hizmeti kurun."
#, python-format
msgid "Next long break at %s"
-msgstr ""
+msgstr "Sonraki uzun mola: %s"
#, python-format
msgid "Next breaks at %(short)s/%(long)s"
-msgstr ""
+msgstr "Sonraki mola: %(short)s/%(long)s"
#, python-format
msgid "The required plugin '%s' is missing dependencies!"
-msgstr ""
+msgstr "Gerekli '%s' eklentisinin bağımlılıkları eksik!"
msgid ""
"Please install the dependencies or disable the plugin. To hide this message, "
"you can also deactivate the plugin in the settings."
msgstr ""
+"Lütfen bağımlılıkları kurun veya eklentiyi devre dışı bırakın. Bu mesajı "
+"gizlemek için eklentiyi ayarlardan da devre dışı bırakabilirsiniz."
msgid "Click here for more information"
-msgstr ""
+msgstr "Daha fazla bilgi için buraya tıklayın"
msgid "Disable plugin temporarily"
-msgstr ""
+msgstr "Eklentiyi geçici olarak devre dışı bırak"
msgid "Disable permanently"
-msgstr ""
+msgstr "Kalıcı olarak devre dışı bırak"
msgid "License:"
-msgstr ""
+msgstr "Lisans:"
# Short break
#~ msgid "Tightly close your eyes"
diff --git a/safeeyes/config/locale/ug/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/ug/LC_MESSAGES/safeeyes.po
index a7e1b78a..5fe2594a 100644
--- a/safeeyes/config/locale/ug/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/ug/LC_MESSAGES/safeeyes.po
@@ -109,6 +109,10 @@ msgstr ""
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr ""
diff --git a/safeeyes/config/locale/uk/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/uk/LC_MESSAGES/safeeyes.po
index f71e5753..acaf54e3 100644
--- a/safeeyes/config/locale/uk/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/uk/LC_MESSAGES/safeeyes.po
@@ -113,6 +113,10 @@ msgstr "Ліцензія"
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr "Пропустити"
diff --git a/safeeyes/config/locale/uz_Latn/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/uz_Latn/LC_MESSAGES/safeeyes.po
index 89a7395b..bd4aab85 100644
--- a/safeeyes/config/locale/uz_Latn/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/uz_Latn/LC_MESSAGES/safeeyes.po
@@ -109,6 +109,10 @@ msgstr ""
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr ""
diff --git a/safeeyes/config/locale/vi/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/vi/LC_MESSAGES/safeeyes.po
index e0dc5528..23827c8f 100644
--- a/safeeyes/config/locale/vi/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/vi/LC_MESSAGES/safeeyes.po
@@ -114,6 +114,10 @@ msgstr "Giấy phép"
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr "Bỏ qua"
diff --git a/safeeyes/config/locale/zh_CN/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/zh_CN/LC_MESSAGES/safeeyes.po
index b427cb7c..fc25b4b3 100644
--- a/safeeyes/config/locale/zh_CN/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/zh_CN/LC_MESSAGES/safeeyes.po
@@ -113,6 +113,10 @@ msgstr "许可"
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr "跳过"
diff --git a/safeeyes/config/locale/zh_TW/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/zh_TW/LC_MESSAGES/safeeyes.po
index ab233af5..11d8252c 100644
--- a/safeeyes/config/locale/zh_TW/LC_MESSAGES/safeeyes.po
+++ b/safeeyes/config/locale/zh_TW/LC_MESSAGES/safeeyes.po
@@ -110,6 +110,10 @@ msgstr "授權"
msgid "List of Contributors"
msgstr ""
+# About dialog
+msgid "Help us translate this app"
+msgstr ""
+
# Break screen
msgid "Skip"
msgstr "跳過"
diff --git a/safeeyes/glade/about_dialog.glade b/safeeyes/glade/about_dialog.glade
index 8ee6875b..fc6ab89f 100644
--- a/safeeyes/glade/about_dialog.glade
+++ b/safeeyes/glade/about_dialog.glade
@@ -71,7 +71,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.center
10
10
- Safe Eyes 2.2.2
+ Safe Eyes 2.2.3
center
@@ -207,6 +207,23 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.1
+
+
+
+ False
+ True
+ 2
+
+
False
diff --git a/safeeyes/model.py b/safeeyes/model.py
index e57a1f79..888a6bc1 100644
--- a/safeeyes/model.py
+++ b/safeeyes/model.py
@@ -24,6 +24,7 @@
import random
from enum import Enum
from dataclasses import dataclass
+from typing import Optional, Union
from packaging.version import parse
@@ -424,10 +425,11 @@ def build(cls, name, icon_path, icon_id, action):
@dataclass
class PluginDependency:
message: str
- link: str|None = None
+ link: Optional[str] = None
+ retryable: bool = False
class RequiredPluginException(Exception):
- def __init__(self, plugin_id, plugin_name: str, message: str|PluginDependency):
+ def __init__(self, plugin_id, plugin_name: str, message: Union[str, PluginDependency]):
if isinstance(message, PluginDependency):
msg = message.message
else:
diff --git a/safeeyes/platform/io.github.slgobinath.SafeEyes.metainfo.xml b/safeeyes/platform/io.github.slgobinath.SafeEyes.metainfo.xml
index ad599ffc..408001c9 100644
--- a/safeeyes/platform/io.github.slgobinath.SafeEyes.metainfo.xml
+++ b/safeeyes/platform/io.github.slgobinath.SafeEyes.metainfo.xml
@@ -53,6 +53,7 @@
https://slgobinath.github.io/SafeEyes/
+
diff --git a/safeeyes/plugin_manager.py b/safeeyes/plugin_manager.py
index 1bc3f8f6..41ea4130 100644
--- a/safeeyes/plugin_manager.py
+++ b/safeeyes/plugin_manager.py
@@ -57,14 +57,13 @@
import sys
from safeeyes import utility
-from safeeyes.model import RequiredPluginException
+from safeeyes.model import PluginDependency, RequiredPluginException
sys.path.append(os.path.abspath(utility.SYSTEM_PLUGINS_DIR))
sys.path.append(os.path.abspath(utility.USER_PLUGINS_DIR))
HORIZONTAL_LINE_LENGTH = 64
-
class PluginManager:
"""
Imports the Safe Eyes plugins and calls the methods defined in those plugins.
@@ -73,17 +72,6 @@ class PluginManager:
def __init__(self):
logging.info('Load all the plugins')
self.__plugins = {}
- self.__plugins_on_init = []
- self.__plugins_on_start = []
- self.__plugins_on_stop = []
- self.__plugins_on_exit = []
- self.__plugins_on_pre_break = []
- self.__plugins_on_start_break = []
- self.__plugins_on_stop_break = []
- self.__plugins_on_countdown = []
- self.__plugins_update_next_break = []
- self.__widget_plugins = []
- self.__tray_actions_plugins = []
self.last_break = None
self.horizontal_line = '─' * HORIZONTAL_LINE_LENGTH
@@ -94,7 +82,8 @@ def init(self, context, config):
# Load the plugins
for plugin in config.get('plugins'):
try:
- self.__load_plugin(plugin)
+ loaded_plugin = LoadedPlugin(plugin)
+ self.__plugins[loaded_plugin.id] = loaded_plugin
except RequiredPluginException as e:
raise e
except BaseException as e:
@@ -105,42 +94,62 @@ def init(self, context, config):
logging.error('Error in loading the plugin %s: %s', plugin['id'], e)
continue
# Initialize the plugins
- for plugin in self.__plugins_on_init:
- plugin['module'].init(context, config, plugin['config'])
+ for plugin in self.__plugins.values():
+ plugin.init_plugin(context, config)
return True
+ def needs_retry(self):
+ return self.get_retryable_error() is not None
+
+ def get_retryable_error(self):
+ for plugin in self.__plugins.values():
+ if plugin.required_plugin and plugin.errored and plugin.enabled:
+ if isinstance(plugin.last_error, PluginDependency) and plugin.last_error.retryable:
+ return RequiredPluginException(
+ plugin.id,
+ plugin.get_name(),
+ plugin.last_error
+ )
+
+ return None
+
+ def retry_errored_plugins(self):
+ for plugin in self.__plugins.values():
+ if plugin.required_plugin and plugin.errored and plugin.enabled:
+ if isinstance(plugin.last_error, PluginDependency) and plugin.last_error.retryable:
+ plugin.reload_errored()
+
def start(self):
"""
Execute the on_start() function of plugins.
"""
- for plugin in self.__plugins_on_start:
- plugin['module'].on_start()
+ for plugin in self.__plugins.values():
+ plugin.call_plugin_method("on_start")
return True
def stop(self):
"""
Execute the on_stop() function of plugins.
"""
- for plugin in self.__plugins_on_stop:
- plugin['module'].on_stop()
+ for plugin in self.__plugins.values():
+ plugin.call_plugin_method("on_stop")
return True
def exit(self):
"""
Execute the on_exit() function of plugins.
"""
- for plugin in self.__plugins_on_exit:
- plugin['module'].on_exit()
+ for plugin in self.__plugins.values():
+ plugin.call_plugin_method("on_exit")
return True
def pre_break(self, break_obj):
"""
Execute the on_pre_break(break_obj) function of plugins.
"""
- for plugin in self.__plugins_on_pre_break:
- if break_obj.plugin_enabled(plugin['id'], plugin['enabled']):
- if plugin['module'].on_pre_break(break_obj):
- return False
+ for plugin in self.__plugins.values():
+ if plugin.call_plugin_method_break_obj("on_pre_break", 1, break_obj):
+ return False
return True
def start_break(self, break_obj):
@@ -148,10 +157,9 @@ def start_break(self, break_obj):
Execute the start_break(break_obj) function of plugins.
"""
self.last_break = break_obj
- for plugin in self.__plugins_on_start_break:
- if break_obj.plugin_enabled(plugin['id'], plugin['enabled']):
- if plugin['module'].on_start_break(break_obj):
- return False
+ for plugin in self.__plugins.values():
+ if plugin.call_plugin_method_break_obj("on_start_break", 1, break_obj):
+ return False
return True
@@ -159,24 +167,22 @@ def stop_break(self):
"""
Execute the stop_break() function of plugins.
"""
- for plugin in self.__plugins_on_stop_break:
- if self.last_break.plugin_enabled(plugin['id'], plugin['enabled']):
- plugin['module'].on_stop_break()
+ for plugin in self.__plugins.values():
+ plugin.call_plugin_method("on_stop_break")
def countdown(self, countdown, seconds):
"""
Execute the on_countdown(countdown, seconds) function of plugins.
"""
- for plugin in self.__plugins_on_countdown:
- if self.last_break.plugin_enabled(plugin['id'], plugin['enabled']):
- plugin['module'].on_countdown(countdown, seconds)
+ for plugin in self.__plugins.values():
+ plugin.call_plugin_method("on_countdown", 2, countdown, seconds)
def update_next_break(self, break_obj, break_time):
"""
Execute the update_next_break(break_time) function of plugins.
"""
- for plugin in self.__plugins_update_next_break:
- plugin['module'].update_next_break(break_obj, break_time)
+ for plugin in self.__plugins.values():
+ plugin.call_plugin_method_break_obj("update_next_break", 2, break_obj, break_time)
return True
def get_break_screen_widgets(self, break_obj):
@@ -185,18 +191,20 @@ def get_break_screen_widgets(self, break_obj):
The widget is generated by calling the get_widget_title and get_widget_content functions of plugins.
"""
widget = ''
- for plugin in self.__widget_plugins:
- if break_obj.plugin_enabled(plugin['id'], plugin['enabled']):
- try:
- title = plugin['module'].get_widget_title(break_obj).upper().strip()
- if title == '':
- continue
- content = plugin['module'].get_widget_content(break_obj)
- if content == '':
- continue
- widget += '{}\n{}\n{}\n\n\n'.format(title, self.horizontal_line, content)
- except BaseException:
+ for plugin in self.__plugins.values():
+ try:
+ title = plugin.call_plugin_method_break_obj("get_widget_title", 1, break_obj)
+ if title is None or not isinstance(title, str) or title == '':
+ continue
+ content = plugin.call_plugin_method_break_obj("get_widget_content", 1, break_obj)
+ if content is None or not isinstance(content, str) or content == '':
+ continue
+ title = title.upper().strip()
+ if title == '':
continue
+ widget += '{}\n{}\n{}\n\n\n'.format(title, self.horizontal_line, content)
+ except BaseException:
+ continue
return widget.strip()
def get_break_screen_tray_actions(self, break_obj):
@@ -204,151 +212,186 @@ def get_break_screen_tray_actions(self, break_obj):
Return Tray Actions.
"""
actions = []
- for plugin in self.__tray_actions_plugins:
- if break_obj.plugin_enabled(plugin['id'], plugin['enabled']):
- action = plugin['module'].get_tray_action(break_obj)
- if action:
- actions.append(action)
+ for plugin in self.__plugins.values():
+ action = plugin.call_plugin_method_break_obj("get_tray_action", 1, break_obj)
+ if action:
+ actions.append(action)
return actions
- def __load_plugin(self, plugin):
- """
- Load the given plugin.
- """
- plugin_enabled = plugin['enabled']
- if plugin['id'] in self.__plugins and not plugin_enabled:
- # A disabled plugin but that was loaded earlier
- plugin_obj = self.__plugins[plugin['id']]
- if plugin_obj['enabled']:
- # Previously enabled but now disabled
- plugin_obj['enabled'] = False
- utility.remove_if_exists(self.__plugins_on_start, plugin_obj)
- utility.remove_if_exists(self.__plugins_on_stop, plugin_obj)
- utility.remove_if_exists(self.__plugins_on_exit, plugin_obj)
- utility.remove_if_exists(self.__plugins_update_next_break, plugin_obj)
- # Call the plugin.disable method if available
- if utility.has_method(plugin_obj['module'], 'disable'):
- plugin_obj['module'].disable()
- logging.info("Successfully unloaded the plugin '%s'", plugin['id'])
-
- if not plugin_obj['break_override_allowed']:
- # Remaining methods also should be removed
- utility.remove_if_exists(self.__plugins_on_init, plugin_obj)
- utility.remove_if_exists(self.__plugins_on_pre_break, plugin_obj)
- utility.remove_if_exists(self.__plugins_on_start_break, plugin_obj)
- utility.remove_if_exists(self.__plugins_on_stop_break, plugin_obj)
- utility.remove_if_exists(self.__plugins_on_countdown, plugin_obj)
- utility.remove_if_exists(self.__widget_plugins, plugin_obj)
- utility.remove_if_exists(self.__tray_actions_plugins, plugin_obj)
- del self.__plugins[plugin['id']]
+
+class LoadedPlugin:
+ # state of the plugin
+ enabled: bool = False
+ break_override_allowed: bool = False
+ errored: bool = False
+ required_plugin: bool = False
+
+ # misc data
+ # FIXME: rename to plugin_config to plugin_json? plugin_config and config are easy to confuse
+ config = None
+ plugin_config = None
+ plugin_dir = None
+ module = None
+ last_error = None
+ id = None
+
+ def __init__(self, plugin):
+ (plugin_config, plugin_dir) = self._load_config_json(plugin['id'])
+
+ self.id = plugin['id']
+ self.plugin_config = plugin_config
+ self.plugin_dir = plugin_dir
+ self.enabled = plugin["enabled"]
+ self.break_override_allowed = plugin_config.get('break_override_allowed', False)
+ self.required_plugin = plugin_config.get("required_plugin", False)
+
+ self.config = dict(plugin.get('settings', {}))
+ self.config['path'] = os.path.join(plugin_dir, plugin['id'])
+
+ if self.enabled or self.break_override_allowed:
+ plugin_path = os.path.join(plugin_dir, self.id)
+ message = utility.check_plugin_dependencies(plugin['id'], plugin_config, plugin.get('settings', {}), plugin_path)
+
+ if message:
+ self.errored = True
+ self.last_error = message
+ if self.required_plugin and not (isinstance(message, PluginDependency) and message.retryable):
+ raise RequiredPluginException(
+ plugin['id'],
+ plugin_config['meta']['name'],
+ message
+ )
+ return
+
+ self._import_plugin()
+
+
+ def reload_config(self, plugin):
+ if self.enabled and not plugin["enabled"]:
+ self.enabled = False
+ if not self.errored and utility.has_method(self.module, 'disable'):
+ self.module.disable()
+
+ if not self.enabled and plugin["enabled"]:
+ self.enabled = True
+
+ # Update the config
+ self.config = dict(plugin.get('settings', {}))
+ self.config['path'] = os.path.join(self.plugin_dir, plugin['id'])
+
+ if self.enabled or self.break_override_allowed:
+ plugin_path = os.path.join(self.plugin_dir, self.id)
+ message = utility.check_plugin_dependencies(
+ self.id,
+ self.plugin_config,
+ self.config,
+ plugin_path
+ )
+
+ if message:
+ self.errored = True
+ self.last_error = message
+ elif self.errored:
+ self.errored = False
+ self.last_error = None
+
+ if not self.errored and self.module is None:
+ # No longer errored, import the module now
+ self._import_plugin()
+
+
+ def reload_errored(self):
+ if not self.errored:
return
+ if self.enabled or self.break_override_allowed:
+ plugin_path = os.path.join(self.plugin_dir, self.id)
+ message = utility.check_plugin_dependencies(
+ self.id,
+ self.plugin_config,
+ self.config,
+ plugin_path
+ )
+
+ if message:
+ self.errored = True
+ self.last_error = message
+ elif self.errored:
+ self.errored = False
+ self.last_error = None
+
+ if not self.errored and self.module is None:
+ # No longer errored, import the module now
+ self._import_plugin()
+
+
+ def get_name(self):
+ return self.plugin_config['meta']['name']
+
+ def _import_plugin(self):
+ if self.errored:
+ # do not try to import errored plugin
+ return
+
+ self.module = importlib.import_module((self.id + '.plugin'))
+ logging.info("Successfully loaded %s", str(self.module))
+
+ if utility.has_method(self.module, 'enable'):
+ self.module.enable()
+
+ def _load_config_json(self, plugin_id):
# Look for plugin.py
- if os.path.isfile(os.path.join(utility.SYSTEM_PLUGINS_DIR, plugin['id'], 'plugin.py')):
+ if os.path.isfile(os.path.join(utility.SYSTEM_PLUGINS_DIR, plugin_id, 'plugin.py')):
plugin_dir = utility.SYSTEM_PLUGINS_DIR
- elif os.path.isfile(os.path.join(utility.USER_PLUGINS_DIR, plugin['id'], 'plugin.py')):
+ elif os.path.isfile(os.path.join(utility.USER_PLUGINS_DIR, plugin_id, 'plugin.py')):
plugin_dir = utility.USER_PLUGINS_DIR
else:
- logging.error('plugin.py not found for the plugin: %s', plugin['id'])
- return
+ raise Exception('plugin.py not found for the plugin: %s', plugin_id)
# Look for config.json
- plugin_path = os.path.join(plugin_dir, plugin['id'])
+ plugin_path = os.path.join(plugin_dir, plugin_id)
plugin_config_path = os.path.join(plugin_path, 'config.json')
if not os.path.isfile(plugin_config_path):
- logging.error('config.json not found for the plugin: %s', plugin['id'])
- return
+ raise Exception('config.json not found for the plugin: %s', plugin_id)
plugin_config = utility.load_json(plugin_config_path)
if plugin_config is None:
+ raise Exception('config.json empty/invalid for the plugin: %s', plugin_id)
+
+ return (plugin_config, plugin_dir)
+
+ def init_plugin(self, context, safeeyes_config):
+ if self.errored:
return
+ if self.break_override_allowed or self.enabled:
+ if utility.has_method(self.module, 'init', 3):
+ self.module.init(context, safeeyes_config, self.config)
- if plugin_enabled or plugin_config.get('break_override_allowed', False):
- if plugin['id'] in self.__plugins:
- # The plugin is already enabled or partially loaded due to break_override_allowed
-
- # Validate the dependencies again
- if utility.check_plugin_dependencies(plugin['id'], plugin_config, plugin.get('settings', {}), plugin_path):
- plugin_obj['enabled'] = False
- utility.remove_if_exists(self.__plugins_on_start, plugin_obj)
- utility.remove_if_exists(self.__plugins_on_stop, plugin_obj)
- utility.remove_if_exists(self.__plugins_on_exit, plugin_obj)
- utility.remove_if_exists(self.__plugins_update_next_break, plugin_obj)
- utility.remove_if_exists(self.__plugins_on_init, plugin_obj)
- utility.remove_if_exists(self.__plugins_on_pre_break, plugin_obj)
- utility.remove_if_exists(self.__plugins_on_start_break, plugin_obj)
- utility.remove_if_exists(self.__plugins_on_stop_break, plugin_obj)
- utility.remove_if_exists(self.__plugins_on_countdown, plugin_obj)
- utility.remove_if_exists(self.__widget_plugins, plugin_obj)
- utility.remove_if_exists(self.__tray_actions_plugins, plugin_obj)
- del self.__plugins[plugin['id']]
-
- # Use the existing plugin object
- plugin_obj = self.__plugins[plugin['id']]
-
- # Update the config
- plugin_obj['config'] = dict(plugin.get('settings', {}))
- plugin_obj['config']['path'] = os.path.join(plugin_dir, plugin['id'])
-
- if plugin_obj['enabled']:
- # Already loaded completely
- return
- # Plugin was partially loaded due to break_override_allowed
- if plugin_enabled:
- # Load the rest of the methods
- plugin_obj['enabled'] = True
- module = plugin_obj['module']
- self.__init_plugin(module, plugin_obj)
- else:
- # This is the first time to load the plugin
- # Check for dependencies
- message = utility.check_plugin_dependencies(plugin['id'], plugin_config, plugin.get('settings', {}), plugin_path)
- if message:
- if plugin_config.get('required_plugin', False):
- raise RequiredPluginException(
- plugin['id'],
- plugin_config['meta']['name'],
- message
- )
- return
-
- # Load the plugin module
- module = importlib.import_module((plugin['id'] + '.plugin'))
- logging.info("Successfully loaded %s", str(module))
- plugin_obj = {'id': plugin['id'], 'module': module, 'config': dict(plugin.get(
- 'settings', {})), 'enabled': plugin_enabled,
- 'break_override_allowed': plugin_config.get('break_override_allowed', False)}
- # Inject the plugin directory into the config
- plugin_obj['config']['path'] = os.path.join(plugin_dir, plugin['id'])
- self.__plugins[plugin['id']] = plugin_obj
- if utility.has_method(module, 'enable'):
- module.enable()
- if plugin_enabled:
- self.__init_plugin(module, plugin_obj)
- if utility.has_method(module, 'init', 3):
- self.__plugins_on_init.append(plugin_obj)
- if utility.has_method(module, 'on_pre_break', 1):
- self.__plugins_on_pre_break.append(plugin_obj)
- if utility.has_method(module, 'on_start_break', 1):
- self.__plugins_on_start_break.append(plugin_obj)
- if utility.has_method(module, 'on_stop_break', 0):
- self.__plugins_on_stop_break.append(plugin_obj)
- if utility.has_method(module, 'on_countdown', 2):
- self.__plugins_on_countdown.append(plugin_obj)
- if utility.has_method(module, 'get_widget_title', 1) and utility.has_method(module,
- 'get_widget_content', 1):
- self.__widget_plugins.append(plugin_obj)
- if utility.has_method(module, 'get_tray_action', 1):
- self.__tray_actions_plugins.append(plugin_obj)
-
- def __init_plugin(self, module, plugin_obj):
- """
- Collect mandatory methods from the plugin and add them to the life cycle methods list.
- """
- if utility.has_method(module, 'on_start'):
- self.__plugins_on_start.append(plugin_obj)
- if utility.has_method(module, 'on_stop'):
- self.__plugins_on_stop.append(plugin_obj)
- if utility.has_method(module, 'on_exit'):
- self.__plugins_on_exit.append(plugin_obj)
- if utility.has_method(module, 'update_next_break', 2):
- self.__plugins_update_next_break.append(plugin_obj)
+ def call_plugin_method_break_obj(self, method_name: str, num_args, break_obj, *args, **kwargs):
+ if self.errored:
+ return None
+
+ enabled = False
+ if self.break_override_allowed:
+ enabled = break_obj.plugin_enabled(self.id, self.enabled)
+ else:
+ enabled = self.enabled
+
+ if enabled:
+ return self._call_plugin_method_internal(method_name, num_args, break_obj, *args, **kwargs)
+
+ return None
+
+ def call_plugin_method(self, method_name: str, num_args=0, *args, **kwargs):
+ if self.errored:
+ return None
+
+ if self.enabled:
+ return self._call_plugin_method_internal(method_name, num_args, *args, **kwargs)
+
+ return None
+
+ def _call_plugin_method_internal(self, method_name: str, num_args=0, *args, **kwargs):
+ # FIXME: cache if method exists
+ if utility.has_method(self.module, method_name, num_args):
+ return getattr(self.module, method_name)(*args, **kwargs)
+ return None
diff --git a/safeeyes/plugins/healthstats/plugin.py b/safeeyes/plugins/healthstats/plugin.py
index 126c1c86..5f97afe1 100644
--- a/safeeyes/plugins/healthstats/plugin.py
+++ b/safeeyes/plugins/healthstats/plugin.py
@@ -55,7 +55,8 @@ def init(ctx, safeeyes_config, plugin_config):
'total_resets': 0,
}
- session = context['session']['plugin'].get('healthstats', {}) | defaults
+ session = context['session']['plugin'].get('healthstats', {}).copy()
+ session.update(defaults)
if 'no_of_breaks' in session:
# Ignore old format session.
session = defaults
diff --git a/safeeyes/plugins/trayicon/dependency_checker.py b/safeeyes/plugins/trayicon/dependency_checker.py
index d7a92f97..574433ad 100644
--- a/safeeyes/plugins/trayicon/dependency_checker.py
+++ b/safeeyes/plugins/trayicon/dependency_checker.py
@@ -39,7 +39,8 @@ def validate(plugin_config, plugin_settings):
else:
return PluginDependency(
message=_("Please install service providing tray icons for your desktop environment."),
- link="https://github.com/slgobinath/SafeEyes/wiki/How-to-install-backend-for-Safe-Eyes-tray-icon"
+ link="https://github.com/slgobinath/SafeEyes/wiki/How-to-install-backend-for-Safe-Eyes-tray-icon",
+ retryable=True
)
command = None
diff --git a/safeeyes/plugins/trayicon/plugin.py b/safeeyes/plugins/trayicon/plugin.py
index 39766c18..42b309a5 100644
--- a/safeeyes/plugins/trayicon/plugin.py
+++ b/safeeyes/plugins/trayicon/plugin.py
@@ -49,6 +49,12 @@
+
+
+
+
+
+
""").interfaces[0]
@@ -346,6 +352,7 @@ class StatusNotifierItemService(DBusService):
IconName = 'io.github.slgobinath.SafeEyes-enabled'
IconThemePath = ''
ToolTip = ('', [], 'Safe Eyes', '')
+ XAyatanaLabel = ""
ItemIsMenu = True
Menu = None
@@ -398,6 +405,14 @@ def set_tooltip(self, title, description):
'NewTooltip'
)
+ def set_xayatanalabel(self, label):
+ self.XAyatanaLabel = label
+
+ self.emit_signal(
+ "XAyatanaNewLabel",
+ (label, "")
+ )
+
class TrayIcon:
"""
Create and show the tray icon along with the tray menu.
@@ -514,7 +529,7 @@ def get_items(self):
disable_items.append({
'id': disable_option_dynamic_id,
'label': label,
- 'callback': lambda: self.on_disable_clicked(time_in_minutes),
+ 'callback': lambda time_in_minutes=time_in_minutes: self.on_disable_clicked(time_in_minutes),
})
disable_option_dynamic_id += 1
@@ -611,6 +626,7 @@ def update_tooltip(self):
description = ''
self.sni_service.set_tooltip('Safe Eyes', description)
+ self.sni_service.set_xayatanalabel(description)
def quit_safe_eyes(self):
"""
diff --git a/safeeyes/safeeyes.py b/safeeyes/safeeyes.py
index 3188ec0b..bf94c9cc 100644
--- a/safeeyes/safeeyes.py
+++ b/safeeyes/safeeyes.py
@@ -37,9 +37,9 @@
from safeeyes.ui.settings_dialog import SettingsDialog
gi.require_version('Gtk', '3.0')
-from gi.repository import Gtk, Gio
+from gi.repository import Gtk, Gio, GLib
-SAFE_EYES_VERSION = "2.2.2"
+SAFE_EYES_VERSION = "2.2.3"
class SafeEyes(Gtk.Application):
@@ -48,6 +48,7 @@ class SafeEyes(Gtk.Application):
"""
required_plugin_dialog_active = False
+ retry_errored_plugins_count = 0
def __init__(self, system_locale, config, cli_args):
super().__init__(
@@ -119,8 +120,7 @@ def do_startup(self):
try:
self.plugins_manager.init(self.context, self.config)
except RequiredPluginException as e:
- self.show_required_plugin_dialog(e.get_plugin_id(), e.get_plugin_name(), e.get_message())
- self.required_plugin_dialog_active = True
+ self.show_required_plugin_dialog(e)
self.hold()
@@ -129,7 +129,7 @@ def do_startup(self):
if self.config.get('use_rpc_server', True):
self.__start_rpc_server()
- if not self.required_plugin_dialog_active and self.safe_eyes_core.has_breaks():
+ if not self.plugins_manager.needs_retry() and not self.required_plugin_dialog_active and self.safe_eyes_core.has_breaks():
self.active = True
self.context['state'] = State.START
self.plugins_manager.start() # Call the start method of all plugins
@@ -139,6 +139,9 @@ def do_startup(self):
def do_activate(self):
logging.info('Application activated')
+ if self.plugins_manager.needs_retry():
+ GLib.timeout_add_seconds(1, self._retry_errored_plugins)
+
if self.cli_args.about:
self.show_about()
elif self.cli_args.disable:
@@ -150,6 +153,32 @@ def do_activate(self):
elif self.cli_args.take_break:
self.take_break()
+
+ def _retry_errored_plugins(self):
+ if not self.plugins_manager.needs_retry():
+ return
+
+ logging.info(f"Retry loading errored plugin")
+ self.plugins_manager.retry_errored_plugins()
+
+ error = self.plugins_manager.get_retryable_error()
+
+ if error is None:
+ # success
+ self.restart(self.config, set_active=True)
+ return
+
+ # errored again
+ if self.retry_errored_plugins_count >= 3:
+ self.show_required_plugin_dialog(error)
+ return
+
+ timeout = pow(2, self.retry_errored_plugins_count)
+ self.retry_errored_plugins_count += 1
+
+ GLib.timeout_add_seconds(timeout, self._retry_errored_plugins)
+
+
def show_settings(self):
"""
Listen to tray icon Settings action and send the signal to Settings dialog.
@@ -161,12 +190,14 @@ def show_settings(self):
self.config.clone(), self.save_settings)
settings_dialog.show()
- def show_required_plugin_dialog(self, plugin_id, plugin_name, message):
+ def show_required_plugin_dialog(self, error: RequiredPluginException):
+ self.required_plugin_dialog_active = True
+
logging.info("Show RequiredPlugin dialog")
dialog = RequiredPluginDialog(
- plugin_id,
- plugin_name,
- message,
+ error.get_plugin_id(),
+ error.get_plugin_name(),
+ error.get_message(),
self.quit,
lambda: self.disable_plugin(plugin_id)
)
@@ -306,8 +337,7 @@ def restart(self, config, set_active=False):
try:
self.plugins_manager.init(self.context, self.config)
except RequiredPluginException as e:
- self.show_required_plugin_dialog(e.get_plugin_id(), e.get_plugin_name(), e.get_message())
- self.required_plugin_dialog_active = True
+ self.show_required_plugin_dialog(e)
return
if set_active:
diff --git a/safeeyes/ui/break_screen.py b/safeeyes/ui/break_screen.py
index 7546fd83..bc826221 100644
--- a/safeeyes/ui/break_screen.py
+++ b/safeeyes/ui/break_screen.py
@@ -44,7 +44,7 @@ class BreakScreen:
def __init__(self, context, on_skipped, on_postponed, style_sheet_path):
self.context = context
self.count_labels = []
- self.display = Display()
+ self.display = None
self.enable_postpone = False
self.enable_shortcut = False
self.is_pretified = False
@@ -56,6 +56,9 @@ def __init__(self, context, on_skipped, on_postponed, style_sheet_path):
self.strict_break = False
self.windows = []
+ if not self.context['is_wayland']:
+ self.display = Display()
+
# Initialize the theme
css_provider = Gtk.CssProvider()
css_provider.load_from_path(style_sheet_path)
@@ -131,7 +134,8 @@ def close(self):
Hide the break screen from active window and destroy all other windows
"""
logging.info("Close the break screen(s)")
- self.__release_keyboard()
+ if not self.context['is_wayland']:
+ self.__release_keyboard()
# Destroy other windows if exists
GLib.idle_add(lambda: self.__destroy_all_screens())
@@ -149,7 +153,11 @@ def __show_break_screen(self, message, image_path, widget, tray_actions):
Show an empty break screen on all screens.
"""
# Lock the keyboard
- utility.start_thread(self.__lock_keyboard)
+ if not self.context['is_wayland']:
+ utility.start_thread(self.__lock_keyboard)
+ else:
+ # TODO: Wayland keyboard locking
+ logging.warning("Keyboard locking not yet implemented for Wayland.")
display = Gdk.Display.get_default()
screen = display.get_default_screen()
@@ -243,7 +251,7 @@ def __update_count_down(self, count):
def __lock_keyboard(self):
"""
- Lock the keyboard to prevent the user from using keyboard shortcuts
+ Lock the keyboard to prevent the user from using keyboard shortcuts (X11 only)
"""
logging.info("Lock the keyboard")
self.lock_keyboard = True
diff --git a/safeeyes/utility.py b/safeeyes/utility.py
index 80cfe403..305caa84 100644
--- a/safeeyes/utility.py
+++ b/safeeyes/utility.py
@@ -265,7 +265,7 @@ def desktop_environment():
env = 'unknown'
if desktop_session is not None:
desktop_session = desktop_session.lower()
- if desktop_session in ['gnome', 'unity', 'budgie-desktop', 'cinnamon', 'mate', 'xfce4', 'lxde', 'pantheon', 'fluxbox', 'blackbox', 'openbox', 'icewm', 'jwm', 'afterstep', 'trinity', 'kde']:
+ if desktop_session in ['gnome', 'unity', 'budgie-desktop', 'cinnamon', 'mate', 'xfce4', 'lxde', 'pantheon', 'fluxbox', 'blackbox', 'openbox', 'icewm', 'jwm', 'afterstep', 'trinity', 'kde', 'hyprland']:
env = desktop_session
elif desktop_session.startswith('xubuntu') or (current_desktop is not None and 'xfce' in current_desktop):
env = 'xfce'
@@ -370,7 +370,7 @@ def initialize_safeeyes():
# Copy the safeeyes.json
shutil.copy2(SYSTEM_CONFIG_FILE_PATH, CONFIG_FILE_PATH)
- os.chmod(CONFIG_FILE_PATH, 0o777)
+ os.chmod(CONFIG_FILE_PATH, 0o666)
create_user_stylesheet_if_missing()
@@ -385,7 +385,7 @@ def create_user_stylesheet_if_missing():
# Copy the new style sheet
if not os.path.isfile(STYLE_SHEET_PATH):
shutil.copy2(SYSTEM_STYLE_SHEET_PATH, STYLE_SHEET_PATH)
- os.chmod(STYLE_SHEET_PATH, 0o777)
+ os.chmod(STYLE_SHEET_PATH, 0o666)
def create_startup_entry(force=False):
"""
@@ -493,8 +493,8 @@ def reset_config():
shutil.copy2(SYSTEM_STYLE_SHEET_PATH, STYLE_SHEET_PATH)
# Add write permission (e.g. if original file was stored in /nix/store)
- os.chmod(CONFIG_FILE_PATH, 0o777)
- os.chmod(STYLE_SHEET_PATH, 0o777)
+ os.chmod(CONFIG_FILE_PATH, 0o666)
+ os.chmod(STYLE_SHEET_PATH, 0o666)
create_startup_entry()
@@ -505,7 +505,7 @@ def replace_style_sheet():
"""
delete(STYLE_SHEET_PATH)
shutil.copy2(SYSTEM_STYLE_SHEET_PATH, STYLE_SHEET_PATH)
- os.chmod(STYLE_SHEET_PATH, 0o777)
+ os.chmod(STYLE_SHEET_PATH, 0o666)
def initialize_logging(debug):
diff --git a/setup.py b/setup.py
index 480c3ab4..8e31844e 100644
--- a/setup.py
+++ b/setup.py
@@ -79,14 +79,14 @@ def __package_data():
setuptools.setup(
name="safeeyes",
- version="2.2.2",
+ version="2.2.3",
description="Protect your eyes from eye strain using this continuous breaks reminder.",
long_description=long_description,
long_description_content_type="text/markdown",
author="Gobinath Loganathan",
author_email="slgobinath@gmail.com",
url="https://github.com/slgobinath/SafeEyes",
- download_url="https://github.com/slgobinath/SafeEyes/archive/v2.2.2.tar.gz",
+ download_url="https://github.com/slgobinath/SafeEyes/archive/v2.2.3.tar.gz",
packages=setuptools.find_packages(),
package_data={'safeeyes': __package_data()},
data_files=__data_files(),