Galaxy-Flasher icon indicating copy to clipboard operation
Galaxy-Flasher copied to clipboard

Porting to LibAdwaita and publishing to Flathub

Open IverCoder opened this issue 1 year ago • 79 comments

Is your feature request related to a problem? Please describe.

I have used this app a few times and it worked pretty well for me. However, it can use a bit of UI polish and more discoverability by being published on an app store. Few people unfortunately know about this nice piece of software, a bit more public exposure would be a big help.

Describe the solution you'd like.

The app can be ported to LibAdwaita for a quick and easy UI interface, use the XDG portals File Chooser and File Transfer for accessing the files to be flashed and facilitating drag and drop, and probably the Inhibit portal as well to prevent logging out or shutting down while flashing. Then the app can be submitted to Flathub.

Describe why the feature would be helpful

Flathub is the fastest-growing app store for desktop users, and LibAdwaita guarantees a nice UI compliant with GNOME's HIG for the best user experience.

Thor GUI version

Alpha v0.4.5

IverCoder avatar Feb 21 '24 08:02 IverCoder

I hope I can help in this, but school's pretty busy and I don't think I have enough Python skills for this. Still, I hope this can be accomplished when the right time comes.

IverCoder avatar Feb 21 '24 08:02 IverCoder

I hope I can help in this, but school's pretty busy and I don't think I have enough Python skills for this. Still, I hope this can be accomplished when the right time comes.

Thanks for the info! I'll have to start looking into porting it to LibAdwaita. As for Flathub, definitely! Currently, I'm working on improving the code that interacts with Thor, and adding odin4/heimdall support. But yes, hopefully it can be done at some point.

ethical-haquer avatar Feb 21 '24 15:02 ethical-haquer

If you end up using GTK4, this guide was super helpful for me when I made GTK4 stuff in Python.

justaCasualCoder avatar Feb 21 '24 16:02 justaCasualCoder

I was looking at porting to GTK4, but had a question. Would you want the GUI to stay the same?

justaCasualCoder avatar Mar 10 '24 22:03 justaCasualCoder

I was looking at porting to GTK4, but had a question. Would you want the GUI to stay the same?

Wow, thanks for looking into it! I'm really not sure, honestly. Currently it looks similar to Odin, which could be considered a plus, as users will be able to follow tutorials that use Odin, but I do feel that it could be improved upon somehow. What do you think?

ethical-haquer avatar Mar 11 '24 00:03 ethical-haquer

I agree. I will look at this more later.

justaCasualCoder avatar Mar 11 '24 01:03 justaCasualCoder

I am currently stuck trying to position the widgets. Unfortunately, GTK does not have an equivalent to tk.Label.grid(**widget_grid_options). The GTK grid takes these arguments (from these docs):

  1. The child parameter is the Gtk.Widget to add.
  2. left is the column number to attach the left side of child to.
  3. top indicates the row number to attach the top side of child to.
  4. width and height indicate the number of columns that the child will span, and the number of rows that the child will span, respectively.

There is Gtk.Grid.add, but that just functions like Gtk.Box. This is the only way I can see to keep the current organization/creation of widgets (yes it is VERY messy; I made it in a few minutes):

import sys
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
from gi.repository import Gtk, Adw


class ToplevelWindow(Gtk.ApplicationWindow):
    def __init__(self, widgets, name):
        # INIT
        super().__init__(application=app)
        self.name = name + "_Window"
        self.widgets = widgets
        self.grid = Gtk.Grid()
        self.set_child(self.grid)
        self.create_widgets()
    def create_widgets(self):
        for widget in self.widgets:
            widget_type = widget["type"]
            widget_options = widget["options"]
            widget_grid_options = widget["grid_options"]
            if widget_type == "label":
                label = Gtk.Label()
                label.set_markup(widget_options["text"])
                self.grid.attach(label, widget_grid_options["pos1"], widget_grid_options["pos2"], widget_grid_options["pos3"], widget_grid_options["pos4"])
class ThorGUI(Adw.Application):
    def __init__(self, app_id, widgets, name):
        self.widgets = widgets
        self.name = name
        super().__init__(application_id=app_id)
        self.connect('activate', self.on_activate)
    def on_activate(self, app):
        self.win = ToplevelWindow(self.widgets, self.name)
        self.win.present()
widgets = [
    {
        "type": "label",
        "options": {
            "text": "<big>Thor Flash Utility v1.0.4</big>", 
        },
        "grid_options": {
            "pos1": 0,
            "pos2": 0,
            "pos3": 1,
            "pos4": 2,
        },
    }
]
app = ThorGUI("com.ethicalhaquer.thorgui", widgets, "Thor_GUI")
app.run(sys.argv)

justaCasualCoder avatar Mar 12 '24 17:03 justaCasualCoder

Do you think I should continue using that setup?

widgets = [
    {
        "type": "label",
        "options": {
            "text": "<big>Thor Flash Utility v1.0.4</big>", 
        },
        "grid_options": {
            "pos1": 0,
            "pos2": 0,
            "pos3": 1,
            "pos4": 2,
        },
    }
]

justaCasualCoder avatar Mar 12 '24 23:03 justaCasualCoder

I am currently stuck trying to position the widgets. Unfortunately, GTK does not have an equivalent to tk.Label.grid(**widget_grid_options). The GTK grid takes these arguments (from these docs):

1. The `child` parameter is the [Gtk.Widget](https://lazka.github.io/pgi-docs/Gtk-3.0/classes/Widget.html#Gtk.Widget) to add.

2. `left` is the column number to attach the left side of child to.

3. `top` indicates the row number to attach the top side of child to.

4. `width` and `height` indicate the number of columns that the child will span, and the number of rows that the child will span, respectively.

There is Gtk.Grid.add, but that just functions like Gtk.Box. This is the only way I can see to keep the current organization/creation of widgets (yes it is VERY messy; I made it in a few minutes):

import sys
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
from gi.repository import Gtk, Adw


class ToplevelWindow(Gtk.ApplicationWindow):
    def __init__(self, widgets, name):
        # INIT
        super().__init__(application=app)
        self.name = name + "_Window"
        self.widgets = widgets
        self.grid = Gtk.Grid()
        self.set_child(self.grid)
        self.create_widgets()
    def create_widgets(self):
        for widget in self.widgets:
            widget_type = widget["type"]
            widget_options = widget["options"]
            widget_grid_options = widget["grid_options"]
            if widget_type == "label":
                label = Gtk.Label()
                label.set_markup(widget_options["text"])
                self.grid.attach(label, widget_grid_options["pos1"], widget_grid_options["pos2"], widget_grid_options["pos3"], widget_grid_options["pos4"])
class ThorGUI(Adw.Application):
    def __init__(self, app_id, widgets, name):
        self.widgets = widgets
        self.name = name
        super().__init__(application_id=app_id)
        self.connect('activate', self.on_activate)
    def on_activate(self, app):
        self.win = ToplevelWindow(self.widgets, self.name)
        self.win.present()
widgets = [
    {
        "type": "label",
        "options": {
            "text": "<big>Thor Flash Utility v1.0.4</big>", 
        },
        "grid_options": {
            "pos1": 0,
            "pos2": 0,
            "pos3": 1,
            "pos4": 2,
        },
    }
]
app = ThorGUI("com.ethicalhaquer.thorgui", widgets, "Thor_GUI")
app.run(sys.argv)

Sorry for the late reply! I really have to read up on this. 🤣 I'm trying to think of what the proper way is for us to both work on this. I guess you'd just fork it?

Do you think I should continue using that setup?

widgets = [
    {
        "type": "label",
        "options": {
            "text": "<big>Thor Flash Utility v1.0.4</big>", 
        },
        "grid_options": {
            "pos1": 0,
            "pos2": 0,
            "pos3": 1,
            "pos4": 2,
        },
    }
]

Yeah, I think it looks good. 👍

ethical-haquer avatar Mar 12 '24 23:03 ethical-haquer

I'm not sure if you already know, but I've been working on the pyte-test branch lately. As the name suggests, I'm experimenting with using pyte to display and detect the output from Thor (and soon odin4). Also I'm working on pyautocapture which I plan on using to keep the screenshots and screen-recording up-to-date. It's probably not the highest priority, but I was delaying until I got my S5 for doing more work on the pyte-test branch (It just got here today).

ethical-haquer avatar Mar 13 '24 00:03 ethical-haquer

I just noticed your fork. 🤣

ethical-haquer avatar Mar 13 '24 00:03 ethical-haquer

Update: I'm working on this, I just don't want to update the fork until I have a solid base. I have been looking into using Gtk.Stack and Gtk.StackSwitcher for the tabs. Haha this is not super easy because there is like 0 documentation of GTK4 in Python. Update #2: This is how it's looking: Thor_GUI_GTK

justaCasualCoder avatar Mar 13 '24 18:03 justaCasualCoder

It's looking really nice, thanks again! Also, about that phone I got, It had a Verizon battery cover, but it turned out to be a G900A! :rofl: I asked you some questions on your temporary unlock XDA thread.

ethical-haquer avatar Mar 14 '24 17:03 ethical-haquer

New Update: Yay! An About dialog! image image

justaCasualCoder avatar Mar 15 '24 00:03 justaCasualCoder

New Update: Yay! An About dialog! image image

It looks like a legit app now. Wow 😮

ethical-haquer avatar Mar 15 '24 00:03 ethical-haquer

Do you think I should keep the current thor-gui.py file structure? Your implementation of thor-gui in tkinter has multiple functions that are unnecessary in GTK because it is more powerful. The structure of a GTK app is also very different... So there are 2 options:

  1. Keep the current thor-gui.py structure, deleting a few of the functions and patching the rest.
  2. Create a new thor-gui.py file, using the GTK structure.

I would prefer the latter option, but wanted your opinion.

justaCasualCoder avatar Mar 17 '24 12:03 justaCasualCoder

I think I found the perfect way to spawn thor in GTK: VTE! It auto scrolls, supports color, and allows sending commands to the child process (and reading back output).

justaCasualCoder avatar Mar 19 '24 13:03 justaCasualCoder

Do you think I should keep the current thor-gui.py file structure? Your implementation of thor-gui in tkinter has multiple functions that are unnecessary in GTK because it is more powerful. The structure of a GTK app is also very different... So there are 2 options:

1. Keep the current `thor-gui.py` structure, deleting a few of the functions and patching the rest.

2. Create a new `thor-gui.py` file, using the `GTK` structure.

I would prefer the latter option, but wanted your opinion.

First of all, sorry for my delayed reply! (I've been out in the boonies)

Yeah, there's no need to keep the current structure. Definitely option 2. It needs a re-structuring anyways.

I think I found the perfect way to spawn thor in GTK: VTE! It auto scrolls, supports color, and allows sending commands to the child process (and reading back output).

I know, it's exactly what we need! Just VTE alone makes switching to GTK a no-brainer.

ethical-haquer avatar Mar 20 '24 04:03 ethical-haquer

Currently having issues setting up VTE. There is a TON of docs for GTK3, but not 4. If anyone happens to have a example/docs for VTE in GTK4, that would be great...

justaCasualCoder avatar Mar 20 '24 17:03 justaCasualCoder

Update: Finally got VTE and GTK4 working in Python! Probably going to work on it more tomorrow...

justaCasualCoder avatar Mar 20 '24 23:03 justaCasualCoder

I updated my fork! It has a LOT of features that don't work at all. Like no dialog's etc. The basic flashing functionality is almost done. My fork is here.

justaCasualCoder avatar Mar 21 '24 18:03 justaCasualCoder

I updated my fork! It has a LOT of features that don't work at all. Like no dialog's etc. The basic flashing functionality is almost done. My fork is here.

It works great! I can't believe how much smaller the code is; GTK is definitely more powerful. You just forgot to add yourself to the credits! 😉

I sent you an invite to collaborate on Thor_GUI. I'm assuming the best course of action is to create a new Thor_GUI branch, something like "gtk", and then we can both work on it. What do you think?

ethical-haquer avatar Mar 22 '24 04:03 ethical-haquer

Yeah, that sounds like a good idea 👍

justaCasualCoder avatar Mar 22 '24 12:03 justaCasualCoder

Yeah, that sounds like a good idea 👍

Alright, the new branch is ready.

ethical-haquer avatar Mar 22 '24 15:03 ethical-haquer

Currently working on porting the scan_output and select_partitions functions. Unfortunately, VTE does not have a signal for when output is updated. The contents-changed signal kinda works, but it is also called when the terminal is scrolled, causing all kinds of issues... I have gotten the select_partitions function working pretty well, but if you scroll in the terminal while it is running, ~20 select_partitions windows pop up :stuck_out_tongue:...

justaCasualCoder avatar Mar 25 '24 17:03 justaCasualCoder

Also I just responded to your question on my XDA thread. EDIT1: Haha oops accidentally clicked the close with comment button :laughing: ...

justaCasualCoder avatar Mar 26 '24 00:03 justaCasualCoder

Just added flashing functionality to the gtk branch! If anyone want's to help, just look for # TODO ... in thor-gui.py.

justaCasualCoder avatar Mar 27 '24 14:03 justaCasualCoder

Just added flashing functionality to the gtk branch! If anyone want's to help, just look for # TODO ... in thor-gui.py.

Nice! I'd like to start working on it, but I get this error with the latest gtk branch:

Traceback (most recent call last):
  File "/home/ethical_haquer/GitHub/Thor_GUI/thor-gui.py", line 253, in scan_output
    terminal_text = vte.get_text_range_format(Vte.Format(1), 0, 0, 10000, 10000)[0]
                    ^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'Terminal' object has no attribute 'get_text_range_format'

I can't find anything online, maybe I don't have something installed? I honestly have no idea. What are you developing this on? TIA.

ethical-haquer avatar Mar 27 '24 23:03 ethical-haquer

Just added flashing functionality to the gtk branch! If anyone want's to help, just look for # TODO ... in thor-gui.py.

Nice! I'd like to start working on it, but I get this error with the latest gtk branch:

Traceback (most recent call last):
  File "/home/ethical_haquer/GitHub/Thor_GUI/thor-gui.py", line 253, in scan_output
    terminal_text = vte.get_text_range_format(Vte.Format(1), 0, 0, 10000, 10000)[0]
                    ^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'Terminal' object has no attribute 'get_text_range_format'

I can't find anything online, maybe I don't have something installed? I honestly have no idea. What are you developing this on? TIA.

You need to have VTE 3.9.1, and GTK 4.12. I was working on Debian, but switched to Arch because packages were newer. GTK is always removing/renaming functions. For a while between 4.10 and 4.12 there was like no file dialog :laughing: ... get_text_range_format was added in 0.72. These are the Debian package versions:

Package gir1.2-vte-3.91 bookworm (stable) (introspection): GObject introspection data for the VTE library ~0.70.6-2~deb12u1: amd64 arm64 armel armhf i386 mips64el mipsel ppc64el s390x trixie (testing) (introspection): GObject introspection data for the VTE library 0.75.91-2: amd64 arm64 armel armhf i386 mips64el ppc64el s390x sid (unstable) (introspection): GObject introspection data for the VTE library 0.75.92-1: amd64 arm64 armel armhf i386 m68k mips64el ppc64 ppc64el riscv64 s390x 0.75.91-2 [debports]: hppa sh4 0.74.2-1 [debports]: alpha ia64 sparc64 x32

EDIT1: These are the docs for PyGObject.

justaCasualCoder avatar Mar 28 '24 13:03 justaCasualCoder

Just added flashing functionality to the gtk branch! If anyone want's to help, just look for # TODO ... in thor-gui.py.

Nice! I'd like to start working on it, but I get this error with the latest gtk branch:

Traceback (most recent call last):
  File "/home/ethical_haquer/GitHub/Thor_GUI/thor-gui.py", line 253, in scan_output
    terminal_text = vte.get_text_range_format(Vte.Format(1), 0, 0, 10000, 10000)[0]
                    ^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'Terminal' object has no attribute 'get_text_range_format'

I can't find anything online, maybe I don't have something installed? I honestly have no idea. What are you developing this on? TIA.

You need to have VTE 3.9.1, and GTK 4.12. I was working on Debian, but switched to Arch because packages were newer. GTK is always removing/renaming functions. For a while between 4.10 and 4.12 there was like no file dialog 😆 ... get_text_range_format was added in 0.72. These are the Debian package versions:

Package gir1.2-vte-3.91 bookworm (stable) (introspection): GObject introspection data for the VTE library ~0.70.6-2~deb12u1: amd64 arm64 armel armhf i386 mips64el mipsel ppc64el s390x trixie (testing) (introspection): GObject introspection data for the VTE library 0.75.91-2: amd64 arm64 armel armhf i386 mips64el ppc64el s390x sid (unstable) (introspection): GObject introspection data for the VTE library 0.75.92-1: amd64 arm64 armel armhf i386 m68k mips64el ppc64 ppc64el riscv64 s390x 0.75.91-2 [debports]: hppa sh4 0.74.2-1 [debports]: alpha ia64 sparc64 x32

EDIT1: These are the docs for PyGObject.

Thanks for the reply! I saw those docs, but I thought I had version 3.91 (way newer, right? :rofl:), but yeah, I actually had 0.70.6. :facepalm: I've upgraded to Debian Testing, and now have the newer packages I need. Thanks again!

ethical-haquer avatar Mar 28 '24 17:03 ethical-haquer