Drag n Drop

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 dest_default is 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 0.

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 drag_status remains 0.

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.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create your website at WordPress.com
Get started
%d bloggers like this: