feat: add ability to use line breaks in labels - #147
Conversation
|
Nice work! I'll try this when I have some time |
|
I changed the design a bit. The only thing bothering me is that the TextView has no placeholder support... |
Yeah, that is why i had to remove the placeholder text. You can technically add line breaks to a label without a TextView but I think it looks a bit weird where instead of adding new lines in the Entry widget it just adds this weird arrow symbol. |
|
I'll play around with different concepts for this when I have some time |
Do you have a branch with your changed design? I don't see a fittting name in the StreamController branches. |
|
So far it's just the one commit (fb00101) that I made to this PR. I definately want to keep some sort of placeholder. What do you think about simply allowing \n in the currently used entry box? |
Would be fine by me. Though I would like to mention that I asked ChatGPT about the placeholder issue with TextView and it suggested to handle it ourselves like this: import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk
class MainWindow(Gtk.Window):
def init(self):
Gtk.Window.init(self, title="TextView with Placeholder Example")
self.set_default_size(400, 300)
# VBox to arrange widgets vertically
vbox = Gtk.VBox(spacing=6)
self.add(vbox)
# Button to replace the entry with a TextView
self.button = Gtk.Button(label="Replace with TextView")
self.button.connect("clicked", self.on_button_clicked)
vbox.pack_start(self.button, False, False, 0)
# Initial single-line text entry
self.entry = Gtk.Entry()
self.entry.set_text("This is a single-line entry")
vbox.pack_start(self.entry, False, False, 0)
# Container for the TextView (will be shown later)
self.textview_scrolled_window = Gtk.ScrolledWindow()
self.textview = Gtk.TextView()
self.textview_scrolled_window.add(self.textview)
self.textview_scrolled_window.set_vexpand(True)
# Placeholder text
self.placeholder_text = "Enter your text here..."
self.is_placeholder_visible = False
def on_button_clicked(self, widget):
# Transfer text from Entry to TextView
entry_text = self.entry.get_text()
text_buffer = self.textview.get_buffer()
text_buffer.set_text(entry_text)
# Remove Entry and show TextView in the scrolled window
parent = self.entry.get_parent()
parent.remove(self.entry)
parent.pack_start(self.textview_scrolled_window, True, True, 0)
self.textview_scrolled_window.show_all()
# Connect signals for placeholder management
self.textview.connect("focus-in-event", self.on_textview_focus_in)
self.textview.connect("focus-out-event", self.on_textview_focus_out)
# Set placeholder if TextView is empty
if text_buffer.get_text(text_buffer.get_start_iter(), text_buffer.get_end_iter(), True) == "":
self.set_placeholder()
# Disable the button since replacement is already done
self.button.set_sensitive(False)
def set_placeholder(self):
buffer = self.textview.get_buffer()
buffer.set_text(self.placeholder_text)
self.textview.modify_fg(Gtk.StateFlags.NORMAL, Gdk.color_parse("gray"))
self.is_placeholder_visible = True
def remove_placeholder(self):
buffer = self.textview.get_buffer()
buffer.set_text("")
self.textview.modify_fg(Gtk.StateFlags.NORMAL, None) # Reset to default color
self.is_placeholder_visible = False
def on_textview_focus_in(self, widget, event):
if self.is_placeholder_visible:
self.remove_placeholder()
def on_textview_focus_out(self, widget, event):
buffer = self.textview.get_buffer()
text = buffer.get_text(buffer.get_start_iter(), buffer.get_end_iter(), True)
if text.strip() == "":
self.set_placeholder()
win = MainWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main() |
|
That doesn't work for me, I just get a white window. (and it's gtk3) |
|
Well yeah, ChatGPT rarely spits out code that just works. It was more meant as concept. Put in grey placeholder text by default and when entering the TextView check if the text is the placeholder - if yes, remove it. On leaving the TextView, check whether it is empty and if yes, readd the placeholder. |
But if the user want to have the placeholder text as the actual text... |
|
😆 as a placeholder is a safe bet. As a workaround, people who reeeealy want that text could add an extra space. |
|
I hope I'm not annoying, but I really don't want to just bet that no one will use the placeholder. If there's no way to add a placeholder via some workaround, I think we should use the |
|
By now it seems like you are looking for reason not to use TextView. |
|
I don't have anything against TextView, but I hope you can understand that I want to keep the placeholder. However, I'll try to find a nice workaround for the placeholder |
|
@gensyn What do you think about this placeholder solution? |
|
I played around with it a bit and it seems to be working good. Once I got to a point to where the TextView would only display one line although there were several but I couldn't reproduce it. Looks good. |
|
But maybe the color button should have a fixed height - that looks a little weird when it stretches. |
|
True. |
And while the stretched button also looks kinda weird, it at least makes sense, because it controls the color of all lines. However, maybe moving it below the textview makes sense |
|
Then it could better line up with the new outline row. Sounds like a good idea. |
|
I was actually thinking that font and color could share a line like oultine width and outline color do. That way, both color pickers would be next to each other. I thought that might look tidier. |
|
I think I would make every property take one line, separating outline width and outline color. What do you think? |
|
Yeah, sure, as long as it's consistent. |
|
That works for me. |
|
It takes up quite a lot of space, but it's consistent now. There's just one problem left: When there's a multi-line label in the textview and the revert/reset button is pressed the text gets cleared as expected, but the height doesn't shrink. |
|
Not always, but sometimes the height does get reset. I assume it's a race condition between deleting the text and the focus lost event of the TextView or something like that. |
|
I think this a minor cosmetic problem which wouldn't bother me if everything else works. So I would just go with it instead of leaving this PR in limbo. |
|
The problem is that users will think it's a bug, which it kinda is, so I'll try to fix this in coming days and if I can't fix it, I'm gonna merge it |
|
I still haven't found a way around this, what do you think about a toggle for this feature in the settings so that the users will get informed about this "bug" and don't report it? |
|
Yeah, that sounds reasonable. Although I suspect that instead user will keep asking for this feature because it's hidden. 🙃 |
What about adding an experimental section in the first start up page? |
The problem with this is that it can't be changed later on because there's no way to open the onboarding dialog a second time. |
…e of instability. The revert will be reverted for the .8 release This reverts commit 536786e.
* Added Image Layering to ActionBase (#205) * Feat(ImageLayering): Added Image layering for Buttons * Feat(ActionBase): Changed method name to be more appropriate for the feature * Feat(ActionBase): Added get_asset_path to make it easier to get the full path for an asset * Feat(ImageLayer): Added method to combine image Layers into a full ImageLayer list * Feat(ImageLayer): Added some helper methods that make Creation of the final image easier * Feat(ImageLayer): Added some logging to the ImageLayer. Now Also Skipping layers when they are None * Refactor(ImageLayer): Changed the methods behaviour slightly to be more accurate to the name. Updated docs accordingly * Refactor(ImageLayer): Changed things into a Media and Layer class that will be used independent from each other * Fix(Media): get_final_media had errors because the last image didnt get created correctly * Feat(Media): Added method to create a Media with an image directly added to it * Refactor(ActionBase): Removed set_layered_images because this method is not needed with the new approach * Feat(Media): Added parameter checking * Feat(Media): Added errors to parameter checks * Refactor(Media): Removed for loop from add_layer because this is not needed at all * Chore(MediaLayers): Small adjustments to typing, docstrings and method names --------- Co-authored-by: Core447 <[email protected]> * Fix(mainWindow): Showing "no decks available" in header when no pages * Add support for the sd-neo Squashed commit of the following: commit 6bd5ffd Author: Core447 <[email protected]> Date: Sat Sep 21 09:29:07 2024 +0200 Feat: Add new_enumerate info log commit 76ec759 Author: Core447 <[email protected]> Date: Sat Sep 21 09:23:24 2024 +0200 Fix: Not using new_enumerate with neo patch commit 1e717ed Author: Core447 <[email protected]> Date: Tue Sep 10 07:56:04 2024 +0200 Feat: Add basic sd-neo support via patcher WIP * Chore(deps): Bump nltk from 3.8.1 to 3.9 (#209) Bumps [nltk](https://github.com/nltk/nltk) from 3.8.1 to 3.9. - [Changelog](https://github.com/nltk/nltk/blob/develop/ChangeLog) - [Commits](nltk/nltk@3.8.1...3.9) --- updated-dependencies: - dependency-name: nltk dependency-type: direct:production ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Build(deps): Bump certifi from 2024.2.2 to 2024.7.4 (#155) Bumps [certifi](https://github.com/certifi/python-certifi) from 2024.2.2 to 2024.7.4. - [Commits](certifi/python-certifi@2024.02.02...2024.07.04) --- updated-dependencies: - dependency-name: certifi dependency-type: direct:production ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Update requirements.txt * Move to Gnome 47 runtime (#258) * Move to Gnome 47 runtime * Merged dev into gnome47-runtime --------- Co-authored-by: Core447 <[email protected]> * Update pypi-requirements.yaml * Chore(StoreBackend): Add official store branch info log * Bump version to 1.5.0-beta.7 * Update release notes * Chore: Add sd neo support to readmes * Fixes a typo in contribution section of README file (#262) * Feat: Add gsk warning * Chore: Fix typo in release notes * Chore: Reformat changelog * Chore: Add release to metainfo * Fix(ActionBase): Fixed using empty list in param for get_asset_path (#263) * Feat(SearchComboRow): Added new ComboRow with integrated Search, useful for big lists (#266) * Refactor: Move action permission methods into ActionPermissionManager class * Fix(BackgroundEditor): Not correctly restoring transparent colors * Feat: Add proper background permission management * Fix: Icon preview not updating under runtime 47 * Add Stream Deck NEO to udev.rules (#269) * Fix(SearchComboRow): Changed instances of ComboRowSearchItem to SearchComboRowItem (#267) * Fix(SearchComboRow): Changed instances of ComboRowSearchItem to SearchComboRowItem because that was forgotten * Fix(SearchComboRow): Added ability to set the selected item and made the selected item index be emitted as well when the item changes * Fix: Horizontal background tile gap too small on SD+ * Fix: Give first action background-control permission per default * Revert "feat: add ability to use line breaks in labels (#147)" because of instability. The revert will be reverted for the .8 release This reverts commit 536786e. * Fix: on_update may be called before on_ready * Feat(Locales): Updated PluginBase and LocaleManager for minor improvements (#271) * Feat(LocaleManager): Made Plugin still be able to load if locale is not being found * Feat(PluginBase): Updated locale_manager to either use legacy or new LocaleManager by adding two new args to the __init__ * Refactor(PluginBase): Changed use_legacy_locale from False to True as default * Fix: Loading action objects of inputs that don't exists on deck * Fix(ActionConfigurator): UI not getting hidden properly (#275) * Fix(ActionConfigurator): ConfigGroup and CustomConfig weren't properly hidden when methods are not present * Fix(ActionConfigurator): Hiding 2nd Seperator when only the CustomConfig is present * Fix(ActionConfigurator): Correctly hiding when rows are empty and when custom area is none * Refactor(ActionConfigurator): Changed the way the separator gets hidden * Fix: Unnecessary 2nd call of get_config_rows() --------- Co-authored-by: Core447 <[email protected]> * Remove sd neo patcher * Fix: Old sd neo patch import * Chore: Remove old debug prints * Update requirements * Chore: Update changelog * Feat(GtkHelper): Added a better disconnect function because adding try blocks to every ui element is tedious and to much boilerplate (#277) --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: GAPLS <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: wanderboessenkool <[email protected]> Co-authored-by: AdiHarif <[email protected]> Co-authored-by: Ming-Chuan <[email protected]>
* Added Image Layering to ActionBase (#205) * Feat(ImageLayering): Added Image layering for Buttons * Feat(ActionBase): Changed method name to be more appropriate for the feature * Feat(ActionBase): Added get_asset_path to make it easier to get the full path for an asset * Feat(ImageLayer): Added method to combine image Layers into a full ImageLayer list * Feat(ImageLayer): Added some helper methods that make Creation of the final image easier * Feat(ImageLayer): Added some logging to the ImageLayer. Now Also Skipping layers when they are None * Refactor(ImageLayer): Changed the methods behaviour slightly to be more accurate to the name. Updated docs accordingly * Refactor(ImageLayer): Changed things into a Media and Layer class that will be used independent from each other * Fix(Media): get_final_media had errors because the last image didnt get created correctly * Feat(Media): Added method to create a Media with an image directly added to it * Refactor(ActionBase): Removed set_layered_images because this method is not needed with the new approach * Feat(Media): Added parameter checking * Feat(Media): Added errors to parameter checks * Refactor(Media): Removed for loop from add_layer because this is not needed at all * Chore(MediaLayers): Small adjustments to typing, docstrings and method names --------- Co-authored-by: Core447 <[email protected]> * Fix(mainWindow): Showing "no decks available" in header when no pages * Add support for the sd-neo Squashed commit of the following: commit 6bd5ffd Author: Core447 <[email protected]> Date: Sat Sep 21 09:29:07 2024 +0200 Feat: Add new_enumerate info log commit 76ec759 Author: Core447 <[email protected]> Date: Sat Sep 21 09:23:24 2024 +0200 Fix: Not using new_enumerate with neo patch commit 1e717ed Author: Core447 <[email protected]> Date: Tue Sep 10 07:56:04 2024 +0200 Feat: Add basic sd-neo support via patcher WIP * Chore(deps): Bump nltk from 3.8.1 to 3.9 (#209) Bumps [nltk](https://github.com/nltk/nltk) from 3.8.1 to 3.9. - [Changelog](https://github.com/nltk/nltk/blob/develop/ChangeLog) - [Commits](nltk/nltk@3.8.1...3.9) --- updated-dependencies: - dependency-name: nltk dependency-type: direct:production ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Build(deps): Bump certifi from 2024.2.2 to 2024.7.4 (#155) Bumps [certifi](https://github.com/certifi/python-certifi) from 2024.2.2 to 2024.7.4. - [Commits](certifi/python-certifi@2024.02.02...2024.07.04) --- updated-dependencies: - dependency-name: certifi dependency-type: direct:production ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Update requirements.txt * Move to Gnome 47 runtime (#258) * Move to Gnome 47 runtime * Merged dev into gnome47-runtime --------- Co-authored-by: Core447 <[email protected]> * Update pypi-requirements.yaml * Chore(StoreBackend): Add official store branch info log * Bump version to 1.5.0-beta.7 * Update release notes * Chore: Add sd neo support to readmes * Fixes a typo in contribution section of README file (#262) * Feat: Add gsk warning * Chore: Fix typo in release notes * Chore: Reformat changelog * Chore: Add release to metainfo * Fix(ActionBase): Fixed using empty list in param for get_asset_path (#263) * Feat(SearchComboRow): Added new ComboRow with integrated Search, useful for big lists (#266) * Refactor: Move action permission methods into ActionPermissionManager class * Fix(BackgroundEditor): Not correctly restoring transparent colors * Feat: Add proper background permission management * Fix: Icon preview not updating under runtime 47 * Add Stream Deck NEO to udev.rules (#269) * Fix(SearchComboRow): Changed instances of ComboRowSearchItem to SearchComboRowItem (#267) * Fix(SearchComboRow): Changed instances of ComboRowSearchItem to SearchComboRowItem because that was forgotten * Fix(SearchComboRow): Added ability to set the selected item and made the selected item index be emitted as well when the item changes * Fix: Horizontal background tile gap too small on SD+ * Fix: Give first action background-control permission per default * Revert "feat: add ability to use line breaks in labels (#147)" because of instability. The revert will be reverted for the .8 release This reverts commit 536786e. * Fix: on_update may be called before on_ready * Feat(Locales): Updated PluginBase and LocaleManager for minor improvements (#271) * Feat(LocaleManager): Made Plugin still be able to load if locale is not being found * Feat(PluginBase): Updated locale_manager to either use legacy or new LocaleManager by adding two new args to the __init__ * Refactor(PluginBase): Changed use_legacy_locale from False to True as default * Fix: Loading action objects of inputs that don't exists on deck * Fix(ActionConfigurator): UI not getting hidden properly (#275) * Fix(ActionConfigurator): ConfigGroup and CustomConfig weren't properly hidden when methods are not present * Fix(ActionConfigurator): Hiding 2nd Seperator when only the CustomConfig is present * Fix(ActionConfigurator): Correctly hiding when rows are empty and when custom area is none * Refactor(ActionConfigurator): Changed the way the separator gets hidden * Fix: Unnecessary 2nd call of get_config_rows() --------- Co-authored-by: Core447 <[email protected]> * Remove sd neo patcher * Fix: Old sd neo patch import * Chore: Remove old debug prints * Update requirements * Chore: Update changelog * Feat(GtkHelper): Added a better disconnect function because adding try blocks to every ui element is tedious and to much boilerplate (#277) * Fix: Weblinks not opening on Flatpak * Feat: Add donation dialog * Fix: Donate entry of hamburger menu not working --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: GAPLS <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: wanderboessenkool <[email protected]> Co-authored-by: AdiHarif <[email protected]> Co-authored-by: Ming-Chuan <[email protected]>
commit 775eb66 Author: Astrid <[email protected]> Date: Thu Feb 27 15:41:20 2025 +0100 only return usb devices made by elgato (#344) if a pc has a lot of usb devices attached the query for all of them was very slow. we can filter it by only listing devices made by elgate and then check the (hopefully smaller) list for the actual products. commit cdc2a26 Author: jfbauer432 <[email protected]> Date: Sun Jan 12 05:38:32 2025 -0500 Enable flatpak/install.sh to create from local repo (#216) Changed the flatpak/install.sh to it can be used to create a flatpak from a source other then the official repo on github. Also optionally create a flatpak bundle (can be used to test flatpak on another system). Added a few options: -h --help Show this message --repo=path Path to StreamController repo (must be local) use 'current' for git repo in current pwd --branch=branch Name of branch in --repo to use Ignored if --repo is not specified --make-bundle Create a flatpak bundle so you can try it on another system --yes Answer yes to all questions Simplified the question answering code commit 22190cd Author: Dixon T E <[email protected]> Date: Tue Dec 24 02:06:27 2024 +1100 Using --change-page argument no longer pops up main window (#287) commit f4ed290 Author: Joe Goett <[email protected]> Date: Mon Dec 23 09:01:59 2024 -0500 Improve window grabber support for swaywm (#289) commit 45b5bc7 Author: Core447 <[email protected]> Date: Sat Nov 16 19:52:44 2024 +0100 Small changes for 1.5.0-beta.7 Release (#281) * Added Image Layering to ActionBase (#205) * Feat(ImageLayering): Added Image layering for Buttons * Feat(ActionBase): Changed method name to be more appropriate for the feature * Feat(ActionBase): Added get_asset_path to make it easier to get the full path for an asset * Feat(ImageLayer): Added method to combine image Layers into a full ImageLayer list * Feat(ImageLayer): Added some helper methods that make Creation of the final image easier * Feat(ImageLayer): Added some logging to the ImageLayer. Now Also Skipping layers when they are None * Refactor(ImageLayer): Changed the methods behaviour slightly to be more accurate to the name. Updated docs accordingly * Refactor(ImageLayer): Changed things into a Media and Layer class that will be used independent from each other * Fix(Media): get_final_media had errors because the last image didnt get created correctly * Feat(Media): Added method to create a Media with an image directly added to it * Refactor(ActionBase): Removed set_layered_images because this method is not needed with the new approach * Feat(Media): Added parameter checking * Feat(Media): Added errors to parameter checks * Refactor(Media): Removed for loop from add_layer because this is not needed at all * Chore(MediaLayers): Small adjustments to typing, docstrings and method names --------- Co-authored-by: Core447 <[email protected]> * Fix(mainWindow): Showing "no decks available" in header when no pages * Add support for the sd-neo Squashed commit of the following: commit 6bd5ffd Author: Core447 <[email protected]> Date: Sat Sep 21 09:29:07 2024 +0200 Feat: Add new_enumerate info log commit 76ec759 Author: Core447 <[email protected]> Date: Sat Sep 21 09:23:24 2024 +0200 Fix: Not using new_enumerate with neo patch commit 1e717ed Author: Core447 <[email protected]> Date: Tue Sep 10 07:56:04 2024 +0200 Feat: Add basic sd-neo support via patcher WIP * Chore(deps): Bump nltk from 3.8.1 to 3.9 (#209) Bumps [nltk](https://github.com/nltk/nltk) from 3.8.1 to 3.9. - [Changelog](https://github.com/nltk/nltk/blob/develop/ChangeLog) - [Commits](nltk/nltk@3.8.1...3.9) --- updated-dependencies: - dependency-name: nltk dependency-type: direct:production ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Build(deps): Bump certifi from 2024.2.2 to 2024.7.4 (#155) Bumps [certifi](https://github.com/certifi/python-certifi) from 2024.2.2 to 2024.7.4. - [Commits](certifi/python-certifi@2024.02.02...2024.07.04) --- updated-dependencies: - dependency-name: certifi dependency-type: direct:production ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Update requirements.txt * Move to Gnome 47 runtime (#258) * Move to Gnome 47 runtime * Merged dev into gnome47-runtime --------- Co-authored-by: Core447 <[email protected]> * Update pypi-requirements.yaml * Chore(StoreBackend): Add official store branch info log * Bump version to 1.5.0-beta.7 * Update release notes * Chore: Add sd neo support to readmes * Fixes a typo in contribution section of README file (#262) * Feat: Add gsk warning * Chore: Fix typo in release notes * Chore: Reformat changelog * Chore: Add release to metainfo * Fix(ActionBase): Fixed using empty list in param for get_asset_path (#263) * Feat(SearchComboRow): Added new ComboRow with integrated Search, useful for big lists (#266) * Refactor: Move action permission methods into ActionPermissionManager class * Fix(BackgroundEditor): Not correctly restoring transparent colors * Feat: Add proper background permission management * Fix: Icon preview not updating under runtime 47 * Add Stream Deck NEO to udev.rules (#269) * Fix(SearchComboRow): Changed instances of ComboRowSearchItem to SearchComboRowItem (#267) * Fix(SearchComboRow): Changed instances of ComboRowSearchItem to SearchComboRowItem because that was forgotten * Fix(SearchComboRow): Added ability to set the selected item and made the selected item index be emitted as well when the item changes * Fix: Horizontal background tile gap too small on SD+ * Fix: Give first action background-control permission per default * Revert "feat: add ability to use line breaks in labels (#147)" because of instability. The revert will be reverted for the .8 release This reverts commit 536786e. * Fix: on_update may be called before on_ready * Feat(Locales): Updated PluginBase and LocaleManager for minor improvements (#271) * Feat(LocaleManager): Made Plugin still be able to load if locale is not being found * Feat(PluginBase): Updated locale_manager to either use legacy or new LocaleManager by adding two new args to the __init__ * Refactor(PluginBase): Changed use_legacy_locale from False to True as default * Fix: Loading action objects of inputs that don't exists on deck * Fix(ActionConfigurator): UI not getting hidden properly (#275) * Fix(ActionConfigurator): ConfigGroup and CustomConfig weren't properly hidden when methods are not present * Fix(ActionConfigurator): Hiding 2nd Seperator when only the CustomConfig is present * Fix(ActionConfigurator): Correctly hiding when rows are empty and when custom area is none * Refactor(ActionConfigurator): Changed the way the separator gets hidden * Fix: Unnecessary 2nd call of get_config_rows() --------- Co-authored-by: Core447 <[email protected]> * Remove sd neo patcher * Fix: Old sd neo patch import * Chore: Remove old debug prints * Update requirements * Chore: Update changelog * Feat(GtkHelper): Added a better disconnect function because adding try blocks to every ui element is tedious and to much boilerplate (#277) * Fix: Weblinks not opening on Flatpak * Feat: Add donation dialog * Fix: Donate entry of hamburger menu not working --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: GAPLS <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: wanderboessenkool <[email protected]> Co-authored-by: AdiHarif <[email protected]> Co-authored-by: Ming-Chuan <[email protected]>
The fork has diverged too far from upstream StreamController to be reintegrated; give it its own identity. App id, D-Bus names/paths/ifaces, tray SNI ids, proctitle, window/about/tray strings, desktop files, flatpak manifest+metainfo, icons, and the DECKARD_* env-var namespace all move to the new name; the data path becomes ~/.var/app/io.github.nazbert.Deckard (migration of existing data lands in the follow-up commit). Kept unchanged on purpose: com_core447_*/dev_core447_* plugin and asset ids (on-disk data format + store namespace), the GNOME extension bus name, store URLs, PyPI package names, Author: Core447 headers and all upstream attribution, and the legacy-format importer. Donation surfaces stay, relabeled as supporting Core447. New scripts/deckard launcher wrapper and flatpak/deckard-app.desktop template (installed at runtime for the Wayland app_id->icon mapping). .flatpak/meson.sh (upstream dev remnant) and Dev-Planning-Board.md (upstream org board) removed. Refs StreamController#147
rebrand_migration.py moves the whole ~/.var/app tree (data/ + static/ + flatpak-era cache/,config/) from the old id to the new one and leaves a compat symlink behind -- live deck settings and pages embed absolute old paths that must keep resolving without rewriting user JSON. Called from main.py BEFORE 'import globals': globals.py (and mp4_tile_cache.py) os.makedirs() the data tree at import time on every invocation, which would poison any existence-based migration check. A stateful marker (symlink-pending/complete) is written into the OLD root immediately before the rename so it travels with it: any crash after the rename is healed on the next start, and fresh installs are never mistaken for interrupted migrations. Refuses to run while a pre-rename instance owns the old bus name (its path-based writes would recreate the old tree mid-migration and split writes across two trees), and never merges or deletes when both roots hold real files. Completion removes the stale old-identity autostart entries. quit_running gains a transition guard that asks a lingering pre-rename instance to quit before reset_all_decks() can USB-reset decks it owns. ensure_app_desktop_entry() refreshes the user-local desktop file that Wayland compositors need for the app_id -> taskbar-icon mapping. Covered by tests/scenario_rebrand_migration.py (13 cases). Closes StreamController#147
Data-integrity (migration): - Durable marker write (fsync file + dir, atomic replace) and abort the rename when the pending marker cannot be written -- a truncated/zero-length or absent marker after a crash was read as a fresh install, stranding the moved data with no compat symlink. - _is_skeleton now rejects any symlink (a directory-symlink is reported by os.walk in dirnames, unfollowed): a data-relocation symlink in the new root is no longer rmtree'd as import-time residue. A symlinked new root aborts with a clear message instead of crashing rmtree. - Detect --data argparse abbreviations (--dat, --data=...) so an override session no longer mutates the real tree. Startup: - Old-bus transition guard probes with NameHasOwner instead of get_object: get_object on the old well-known name activates it (StartServiceByName), which could launch an upstream install mid-startup. Also catch ValueError (stale owner state) so it no longer aborts startup, and poll for the name to drop instead of a flat 5s sleep. NameHasOwner==False is the effective sunset -- one cheap round trip once nothing owns the old name. Autostart / desktop: - Stale pre-rename autostart cleanup moved to autostart.remove_legacy_ autostart_entries, run from setup_autostart every launch (self-healing); the one-shot migration path could not retry it. - Generated native desktop entries self-reference an absolute Exec (falling back off the optional deckard wrapper) and compare-before-write, fixing both the dangling Exec and the every-launch mtime bump that made desktop environments rescan their app cache. Unifies the two desktop writers. Packaging: - Flatpak manifest tracks branch: main (the pinned pre-rename tag lacked the renamed files -> deterministic build failure); outward URLs (About dialog, README, install.sh, metainfo) point at the redirect-safe current repo names so they resolve before and after the Phase 4 rename. Cleanup: - New appinfo.py: single stdlib-only source for the app id and its derived spellings (D-Bus path, ayatana underscore form, suffixes), consumed by globals/main/api/tray/app/autostart/rebrand_migration/permission manager. - mem_census matches the 'Deckard' proctitle alone (setproctitle rewrites the whole cmdline, so the old main.py AND Deckard match was unsatisfiable). - set_debug_info_filename points at the real logs/logs.log. - Deleted dead permissons.py (imported nowhere, ran example code at import). - scripts/deckard exports the MALLOC_* vars so main.py skips its self-re-exec. Tests: scenario_rebrand_migration grew to 17 cases (abbreviation skip, dir-symlink, symlinked new root, undurable-marker abort); scenario_autostart_ disable covers legacy-entry cleanup. Harness 122 pass + 1 xfail. Refs StreamController#147
Post-merge steps to rename the GitLab project (id 15) and GitHub fork to deckard and repoint the local remotes. scripts/phase4-rename.sh is dry-run by default (--go to execute) and refuses to run until the rename commit is on gitlab/main. Step 7 (local checkout dir rename) stays manual -- it breaks the session cwd and the path-keyed memory dir, wrapper symlink, and desktop entries, all documented in the runbook. Refs StreamController#147
…e, Exec quoting
- Extract the argparser to cli_args.py (stdlib-only) so globals and the
rebrand migration resolve --data with the SAME parser. _data_override_active
now uses it, correctly recognising argparse abbreviations (--dat, --da) and
flag/value disambiguation instead of a fragile length heuristic that missed
--da (which would migrate the real tree during an intended-isolated session).
- Serialize migrate() under an flock on ~/.var/app so two first-run launches
cannot race os.rename/rmtree on real user data; a lock-free fast path keeps
the steady state a single marker read.
- shlex.quote the generated desktop-entry Exec paths: a checkout/venv path
containing a space no longer renders an Exec the desktop spec word-splits
into a broken argv (reintroduced dangling-launch class).
- Bound the old-instance Activate("quit") with an explicit 5s D-Bus timeout
(was inheriting dbus-python's ~25s default).
- HOME fallback consistency in setup_autostart_desktop_entry.
- Louder stuck-PENDING message (old_root reappeared) so a deferred compat
symlink is diagnosable rather than a silent stderr line.
Migration scenario covers --da; harness 122 pass + 1 xfail.
Refs StreamController#147
Rebrand fork to Deckard (io.github.nazbert.Deckard) + data migration Closes StreamController#147 See merge request naz/StreamController!61
The precondition used `git log --oneline gitlab/main | grep -q`, but under `set -o pipefail` grep -q exits on first match and SIGPIPEs git log, so the pipeline returns non-zero and the check false-negatives (it refused to run even though the rename commit was on main). Use `git log --grep` (native, no pipe). Also parse the GitLab path with python instead of `glab api --jq`, which glab does not support. Refs StreamController#147
The command/executable is lowercase per convention; the display name "Deckard", the app id, and StartupWMClass are unchanged. Coordinates the native-install desktop templates and the autostart launcher glue (autostart.py only takes this path on non-flatpak installs) with the /usr/bin/deckard the AUR package installs. Refs StreamController#147
The About dialog showed gl.app_version (1.5.0-beta.15), which stays upstream-aligned so plugin min_app_version gates and the migration system keep working -- so it never reflected a Deckard release. Add a distinct gl.deckard_version read from the root VERSION file (stamped by the CI release pipeline, StreamController#128; "dev" when unstamped) and show that instead, moving the upstream base into the About comments. app_version stays internal for plugin compatibility. Refs StreamController#128 StreamController#147
Native (non-flatpak) installs stored data at ~/.var/app/<id> -- the flatpak-era location -- which is wrong for a native app. Point native at $XDG_DATA_HOME/deckard (default ~/.local/share/deckard); flatpak keeps its per-app dir unchanged (rebrand_migration and the sandbox depend on it). Existing native trees are relocated once by a new migrate_native_var_app_to_xdg(), which reuses migrate()'s crash-safe machinery (rename + durable marker + compat symlink + lock) with its own marker. Runs after the StreamController->Deckard rename so that lands first; no-op under flatpak. migrate()/_migrate_locked() gained marker_name + running_check parameters (defaults preserve existing behaviour), and a latent bug is fixed: the pending marker was hardcoded to MARKER_NAME instead of the active migration's marker basename. Adds scenario_native_xdg_migration.py; scenario_rebrand_migration.py unchanged and still green. Refs StreamController#151 StreamController#147
The native var-app -> XDG relocation used os.rename, which raises EXDEV when ~/.var/app and ~/.local are on different filesystems (separate mounts, or btrfs subvolumes) -> migrate() aborts with SystemExit before `import globals`, so the app never starts, on every launch. - migrate_native_var_app_to_xdg() now verifies src and dest are on one filesystem (via the nearest existing ancestor) and skips the move if not, rather than letting the rename EXDEV-abort startup. - native_data_root() falls back to ~/.var/app/<id> when the XDG dir is absent but the legacy tree exists, so a skipped/deferred move keeps the app working from the old location instead of starting empty. globals.py uses it. - Replaced the overbroad "no split-writes hazard" note with the accurate residual: the microsecond rename->symlink window where a live instance's new absolute-path open gets a transient ENOENT. scenario_native_xdg_migration.py gains cross-fs-skip and fallback-resolution cases (now 8); scenario_rebrand_migration.py unchanged and green. Refs StreamController#151 StreamController#147
Replaces the cross-filesystem *skip* with an actual relocation, so native users whose ~/.var and ~/.local sit on different filesystems (separate mounts, btrfs subvolumes) get moved to the XDG dir instead of being left on ~/.var/app. os.rename cannot cross a filesystem, so the copy path stages the tree into a sibling of the destination on the destination's filesystem, fsyncs it, marks it PENDING, atomically renames the staging dir into place, and only then removes the original and creates the compat symlink. The invariant "never delete the original until a durable, complete copy exists" makes every crash point recoverable with no data loss; native_data_root() keeps the app on ~/.var/app until the copy completes. Copy/publish/cleanup failures are non-fatal (retry next start). migrate() gained a pluggable locked_fn so the copy path reuses its front-matter (pre-globals guard, --data skip, marker fast-paths, lock). Same-filesystem still takes the fast atomic-rename path. scenario_native_xdg_migration.py grows to 14 cases: copy content/symlink preservation + cleanup, idempotency, resume-after-publish (old present/absent), non-fatal copy failure, stale-staging rebuild, --data skip on the copy path. Refs StreamController#151 StreamController#147

Changes
Images