Page 15 of 38

FocusWriter 1.4.5 released

Posted on March 25, 2014, under FocusWriter

7 comments

I have made a new bugfix release of FocusWriter, version 1.4.5. This release fixes quite a few smaller bugs. It will most likely be the last bugfix release I make before the next feature release, which if I hope to have finished soon. Enjoy!

On Break

Posted on January 8, 2014, under Uncategorized

I am taking a break from my open source work. Please continue to enjoy the projects until I return!

Whisker Menu 1.3.0 released!

Posted on December 29, 2013, under Whisker Menu

3 comments

I have just released a new version of Whisker Menu, version 1.3.0. The biggest feature in this release is probably the addition of search actions, which are inspired by the Xfce application finder’s custom actions. These are useful if you want to perform specific actions by typing something into the search field, and included by default are four example actions that you can change or remove. For instance, one of the default actions allows you to open your default web browser and search Wikipedia by starting your search with !w (eg, !wopen source will show you Wikipedia’s definition of “Open Source”).

This release also has a lot of smaller features, such as the ability to run arbitrary programs from your path by typing the entire program name into the search field. You can also now drag menu items to your panel or desktop if you do not want to use the context menu. Additionally there is more flexibility in configuring the command buttons, as well as the option to hide them if you do not need them. You can also hide the category or menu item icons by setting their size to “None” if you prefer a menu without icons.

I hope you enjoy this release! And, of course, please let me know if you have any issues.

Theming Whisker Menu

Posted on November 27, 2013, under Whisker Menu

24 comments

Hi there! This post does not apply to styling the GTK+3 Whisker Menu. For that, read the page on theming.

I have seen several people state that Whisker Menu does not use their GTK theme. This is understandable but completely incorrect. Whisker Menu is a regular window and therefore it matches the GTK theme of regular windows. It can not be a GtkMenu because of the widgets it uses (believe me, I tried), so it does not match the theming of menus.

I did investigate if it would be possible for Whisker Menu to “pick up” the theming of GTK menus and mimic them. Short answer: no. Longer answer: haha, my sanity is worth more than the creaky mess of hacks it would take, and besides I’m fairly certain it still wouldn’t work. So instead I did something much simpler: I named the menu widget itself whiskermenu-window so users or theme makers can play with its appearance as much as they want.

I will not be adding any theme configuration settings to Whisker Menu. First, I really have no interest in doing so. Second, modifying the theme from a .gtkrc file gives you much more power than I could ever expose from a GUI. Third, anything I add would probably interfere with .gtkrc theming.

So, how do you theme Whisker Menu? It’s pretty easy, actually. Open up the hidden file named .gtkrc-2.0 in your home directory with any text editor you want. If the file doesn’t exist, create it. Now, if you want to change the background color of the menu window add something like this:

style "darkback"
{
	bg[NORMAL] = "#404040"
	bg[ACTIVE] = "#606060"
	bg[PRELIGHT] = "#808080"
}
widget "whiskermenu-window*" style "darkback"

Whisker Menu darkback

If you want to change the window text color as well, add something like this:

style "darkback"
{
	bg[NORMAL] = "#404040"
	bg[ACTIVE] = "#606060"
	bg[PRELIGHT] = "#808080"
	fg[NORMAL] = "#ccc"
	fg[ACTIVE] = "#fff"
	fg[PRELIGHT] = "#fff"
}
widget "whiskermenu-window*" style "darkback"

Whisker Menu darkback2

If you want to change the background color of the menu items, add something like this:

style "darktree"
{
	base[NORMAL] = "#404040"
	base[ACTIVE] = "#606060"
}
widget "whiskermenu-window*TreeView*" style "darktree"

Whisker Menu darktree

If you want to change the text color of the menu items as well, add something like this:

style "darktree"
{
	base[NORMAL] = "#404040"
	base[ACTIVE] = "#606060"
	text[NORMAL] = "#ccc"
	text[ACTIVE] = "#fff"
}
widget "whiskermenu-window*TreeView*" style "darktree"

Whisker Menu darktree2

These examples just scratch the surface of what you can do with theming from a .gktrc file. I don’t have much experience with it myself, nor do I intend to really look into it further. There are plenty of resources on how to make GTK themes and what they say should be applicable to Whisker Menu as well.

Revisiting signal handlers

Posted on November 24, 2013, under Programming, Whisker Menu

Ever since I changed how I handle connecting GTK+ signals to C++ members I have never been completely happy with that code. I prefer to not repeat myself, and I like the power and simplicity that templates can bring (and the safety they have over macros). I thought that any GCC before 4.7 would not allow me to write the signal handlers the way I want, but it turns out I was wrong!

Based on the load time error of Whisker Menu 1.0.0 I had surmised that there was a bug in GCC where you can’t take the address of a template function because it did not handle the name mangling properly. However, upon further research I discovered that the bug really is that if you take the address of a template function and cast it to something else before storing it the template is not instantiated. Easy enough to fix: just create a function pointer of the correct type and then cast that:

template <typename T, typename R, typename A1, typename A2>
gulong g_signal_connect_slot(gpointer instance,
		const gchar* detailed_signal,
		R (T::*member)(A1,A2),
		T* obj,
		bool after = false)
{
	class Slot
	{
		T* m_instance;
		R (T::*m_member)(A1,A2);

	public:
		Slot(T* instance, R (T::*member)(A1,A2)) :
			m_instance(instance),
			m_member(member)
		{
		}

		static R invoke(A1 a1, A2 a2, Slot* slot)
		{
			return (slot->m_instance->*slot->m_member)(a1, a2);
		}

		static void destroy(Slot* slot)
		{
			delete slot;
		}
	};
	R (*invoke_slot)(A1,A2,Slot*) = &Slot::invoke;
	void (*destroy_slot)(Slot*) = &Slot::destroy;

	return g_signal_connect_data(instance,
			detailed_signal,
			reinterpret_cast<GCallback>(invoke_slot),
			new Slot(obj, member),
			reinterpret_cast<GClosureNotify>(destroy_slot),
			after ? G_CONNECT_AFTER : GConnectFlags(0));
}

class Example
{
public:
	Example();
	gboolean button_press_event(GtkWidget* widget, GdkEventButton* event);
};

Example::Example()
{
	g_signal_connect_slot(widget, "button-press-event", &Example::button_press_event, this);
}

The code is not quite as simple as the original version, though, because variadic templates are only available in C++11. Instead I have to make make overloads of the function for each amount of parameters I want to support. I did clean it up in other ways by using local classes, which I think makes the new template slot handlers more clear. It even compiles to less space than using class functions for slots.

Categories