Work till now
After the translation debacle in my previous post, I started working on the back-end that will be used by later UI (I’ll be talking about one place where this back-end is used in this post) in a manner such that, when translations start functioning, they can easily be implemented by addition of a few lines of code. This back-end work involves methods that will be used to add or remove firmware, checking whether the firmware being added is acceptable/supported etc.
The goal of adding drag n drop support would allow addition of firmware through, well, drag n drop. Which would be an added bonus to the firmware UI that will be implemented after translations are taken care of after 3.38 release.
My work here is to write a widget that can be easily added almost anywhere allowing that area to accept drops and install firmware. Not only that, but also give visual feedback of whether the dropped firmware has been successfully added or not.
The ideal way to do this would be by writing a widget that’s an overlay. Because the widget is an overlay, it would have the area presented to the widget it’s being attached to and would be able to give visual feedback through the shared real estate for better UX.
For any widget to accept drag,
Gtk.drag_dest_set (widget, dest_default, targets, actions);
line must be used. Here widget, is the widget surface that’s going to experience drag. The documentation for each parameter here can be read here.
The argument being passed as
dest_default must be chosen carefully in my opinion. That is because, if the
Gtk.DestDefault.MOTION, whenever something is being dragged on the surface of the widget, this argument will forcefully emit
drag_motion signal. But if
drag_motion is connected to some other callback, that callback will be called twice due to it being connected to the default signal which would be emitted during a drag motion, and again by the destination default flag. Same with
Gtk.DestDefault.DROP. In my widget, the
dest_default flag was making the experience very clunky, so I simply passed a 0.
After setting the whole widget surface to accept drag,
drag_motion was connected to a callback. This callback checks the target of the drag context. If the target is a list of uris, then the drag data is requested with a
checking flag. Otherwise the
drag_status is set to
Then in the callback for
drag_data_received (which is called when drag data is requested) when the
checking flag is active, the files being dragged on the widget surface are checked for their compatibility. To do this, a function was written in the name space of
FirmwareManager class, which takes a
File as parameter, and runs for a match for checksums of accepted firmware that are not installed yet, or if they are installed, whether these installed firmware files are corrupt or not. If all these checks are clear the function returns true and the file being dragged is an acceptable file, then the overlay is activated and the
drag_status is set to
Gdk.DragAction.COPY. Otherwise the function returns false, and the
If the data is not dropped and simply leaves the widget surface,
drag_leave signal is triggered. This activates a callback that deactivates the overlay if active and the surface reverts back to normal.
If the data is dropped instead, then
drag_drop signal is triggered, which again requests for drag data, but this time with a
dropped flag. This way, when
drag_data_received signal is emitted, the callback rather than checking the file again, simply tries to install the file that was dropped. After the dropped file installed,
drag_finished is called.
drag_finished is important as it tells the system that the drag n drop action has ended.
When drag action ends, the overlay shows the results of the drag process. If it was a success it shows a 1.5 sec success overlay after which all flags otherwise it shows an error message. After the overlay ends messages and flags are reset to prepare for the next drag.
With drag n drop implemented, the last things that needs to be done is the firmware page in the preferences UI in the user interface. But that needs to wait till the 3.38 release is over, after which translations will be implemented and work on firmware preferences page could be continues.