September 29, 2016 - Stephen Houston
A Venture Into Enlightenment’s Gadget API
In my last post, I mentioned that my internship would revolve around creating gadgets using the new Enlightenment gadget API. After several conversations with Mike Blumenkrantz, the creator of the gadget API and my mentor for this internship, we determined the Pager module is in a state that requires minimal work to be converted to the new gadget API. Therefore, converting Pager to the new API would allow me to focus on learning how the new gadget system works better than writing a gadget from the ground up.
Mentors are a Great Resource for Learning Something New
Before I continue with details about the Pager API conversion, I think it would be prudent to explain how this internship works behind the scenes. Mike and I have known each other for quite a while as we’ve both worked on Enlightenment and EFL for years. In fact, when Mike joined the project, I was one of the first to welcome him and encourage his development, and he has quickly rose to the top of the project by bringing creative ideas and elegant code. This relationship is what my internship is all about: I get to work with people within the community that I’ve already spent considerable time with. Additionally, I get to build new relationships in the open source industry and meet mentors who are well adjusted to how open source development works.
Rarely do you find internships that are more of a partnership, but that’s what the Open Source Group’s internship offers. Mike and I keep an open line to each other to frequently discuss ideas, project directions, and bugs that we have found in both my own code as well as his. The ability to get in touch with a mentor quickly to solve problems and keep development moving is extremely valuable, and I get to play an active role in the decision making process.
Converting Pager to the New Gadget API
Now that I’ve provided context, I’ll explain one of the first things I’ve worked on as a part of this internship. The rest of this article will provide a brief overview of the process of converting Pager to the new gadget API. If you have any experience with GUI application development, then you will feel like you already know the new gadget API. It works the way most graphic toolkits do: create an object, tell the object how it should be laid out, and let the backend do the actual layout, sizing, and event handling. There are exceptions, of course, where size or events need to be handled manually; the gadget API makes this seamless with simple set/get functions and event callbacks.
Pager creates a simple table and packs layout objects that mimic virtual desktops into the table. The objects are packed based on the virtual desktop layout, and sizing is based on a gadget site. You can think of a gadget site as a container, or parent, for the object. Pager handles sizing based on the orientation of its parent gadget site. This orientation can be determined from a simple get function. If the gadget site has a horizontal orientation, then Pager will create a layout based on the height of the gadget site. If the gadget site has a vertical orientation, then Pager will create a layout based on the width of the gadget site. Let’s use Pager as an example of how sizing can be handled in a gadget.
Once the height or width (depending on your orientation) has been determined, you can use that size, the aspect ratio of the desktop, and the number of virtual desktops. Let’s assume the desktop has an aspect ratio of 16:9 and there are 4 virtual desktops. These virtual desktops are laid out horizontally in a row. The gadget site (parent of the Pager) has a horizontal orientation and height of 49 pixels. We can use a simple equation where we solve for x to determine what the width of the Pager should be: x = (aspect width / aspect height) * gadget height. This formula is a simple version of 16/9 = x/y where x is your desired width and y is your desired height. Since we already know the desired height is 49, plug 49 into the equation for gadget height. We also know the aspect width is 16 and the aspect height is 9, so we can plug those numbers into the formula as well. That gives us x = (16/9)*49. Solving for x = 87 pixels (rounded). You now know that each virtual desktop layout in the Pager will need to be 87 pixels wide and 49 pixels tall. Since there are four virtual desktops, and they are laid out horizontally, you can determine that 4 * 87, or 348 pixels, will be the width of the Pager, and 49 pixels will be the height. Obviously the math gets slightly more complicated if you have virtual desktops laid out in two directions, both horizontally and vertically, but the principle is the same. If the gadget site is resized, or the number of virtual desktops changes, the size of the Pager is updated simply using the formula we just established.
Once you have the hang of how sizing and orientation works with the gadget API, you can then begin to work on the contents of your actual gadget. Remember, learning new things take some trial and error, and no one is perfect. Sizing can be tricky, but the new gadget API makes it as easy as possible. If you don’t believe me, watch the following video and you can see that even I didn’t get sizing correct the first go around. Notice the Pager jumping around because it is constantly changing sizes.
Furthermore, remember that any issues you may find are not necessarily your fault because the gadget API is new. One of the biggest roadblocks I faced when completing the Pager conversion was correcting drag n drop. I spent a lot of time debugging my own code and asking Mike to debug his as well. Finally, Mike found a bug in the way the gadget code handles layering. He promptly made the fix and I was able to continue working to complete the Pager. It’s rare as an intern to get to ask your mentor to fix HIS bugs! :-).
Once the Pager was working well, the final touch was to create a configuration popup. In the past, Enlightenment modules have used window dialogs to handle configuration. The idea with the new gadgets is to have a simple popup that appears when a gadget is right clicked.
The end result that is now available via git in Enlightenment can be seen in the following video:
Converting Pager to the new gadget API was a great primer for me to learn and prepare myself for the rest of my projects in this internship. The next project I will be working on is creating a new launcher for the enlightenment desktop. I will be writing this gadget from scratch and it will serve not only as a launcher, but also as a taskbar with the ability to handle iconified windows. Keep an eye out for updates regarding my progress!
Image Credits: EFL Project