gtkdialog does not include support for right-click menu, but like the knob, there has been some workarounds for right-click menus as well. Let's look at one of the existing...
The main structural solution has been around some years, and includes some basic knowledge of gtkdialog options.
<window decorated="false" skip_taskbar_hint="true">
<hbox scrollable="true" hscrollbar-policy="2" vscrollbar-policy="2" space-expand="true" space-fill="true">
<vbox spacing="2">
menuitem xml-code here
</vbox>
</hbox>
<action signal="focus-out-event">EXIT:exit</action>
</window>
This is much like any right-click menu works - so far, so good
This is the minimal right-click menu in the tray manager (/usr/local/jwm_config/tray).
The code for each menu-item is a combination of a <pixmap> and a <button> widget.
<hbox>
<pixmap height-request="18" icon_size="1" space-expand="false" space-fill="false">
<input file stock="gtk-edit"></input>
</pixmap>
<button height-request="18" xalign="0" can-focus="no" relief="2" space-expand="true" space-fill="true">
<label>"'$(gettext 'Manual edit')'"</label>
<action>echo edit > /tmp/menu_OUTPUT</action>
<action>EXIT:exit</action>
</button>
</hbox>
The weaknesses shows up when using the default gtk-theme in Slacko-6.3.2, scaling the font, or using another language string that is longer than the default. This is critical when we move towards touch-screen layouts.
Since the background color is similar to the 3D border in the menu, the menu 'melts' into the main gui, and we see only half of the border. The menu has a fixed size (defined in pixels), so it won't scale when needed. And why does it has a fixed size? The answer is because this is the way to avoid the menu to grey out parts of the main gui.
Technical: Reducing the the default size of a button-widget (used in the menu) will grey out the main gui as long as the menu is run as a child of the background gui. We have to run it as a child process to keep the selection viewable in the main gui (see image below).
The improvement process
I have tested several solutions, and ended up with the following... for now. But the first thing to do is to define what criteria should be set for an optimal right-click menu?
It should:
Here follows my attempt for a better solution. Not 100%, but far closer than the previous one.
The structural code in the first code snippet has not changed, but been extended to show the new border.
<window decorated="false" skip_taskbar_hint="true" resizable="false" border-width="0" space-expand="true" space-fill="true">
<eventbox name="rightclick_menu_frame" above-child="false">
<vbox border-width="1">
<eventbox>
<vbox spacing="0" border-width="7">
menuitem xml-code here
</vbox>
</eventbox>
</vbox>
</eventbox>
<action signal="focus-out-event">EXIT:exit</action>
</window>
The <eventbox> widget makes it possible for us to set a unique background color for this widget in the gtk-theme. We do this before executing gtkdialog. The name rightclick_menu_frame corresponds to our style for the extended gtk-theme. Color is set to black (#000), and border width to 1 px. The second <eventbox> is only to draw a new background with the color taken from the global gtk-theme.
echo 'style "Rightclick_menu" { bg[NORMAL] = "#888" }
style "Rightclick_menu_frame" { bg[NORMAL] = "#000" }
widget "*rightclick_menu" style "Rightclick_menu"
widget "*rightclick_menu_frame" style "Rightclick_menu_frame"
' > $WORKDIR/gtkrc_menu
export GTK2_RC_FILES=$WORKDIR/gtkrc_menu:/root/.gtkrc-2.0
The code for the menu-items differs more from the previous attempt (snippet above). This one does not use the <button> widget as the previous, but the <text> widget. Since the <text> widget does not has any internal spacing as the <button> (between text/icon and the gtk-button), it handles down-scaling perfect, and does not grey out any area in the main gui. Also, the <pixmap> here, does not use the gtk-stock, but a defined file. For some reason, this works better for down-scaling as well. As mentioned above, we downscale the gui to better simulate a menu rather than looking like a 'normal' gui.
The <text> widget and the <pixmap> widget does not support any <action>, but that is easily solved by putting them inside an <eventbox>, and let that one handle actions. The corresponding code for this new menu-item looks like this.
<eventbox above-child="true" visible-window="true">
<hbox spacing="7" border-width="3">
<pixmap space-expand="false" space-fill="false">
<height>18</height>
<input file>/usr/share/pixmaps/puppy/remove.svg</input>
</pixmap>
<text xalign="0" space-expand="true" space-fill="true">
<label>"'$(gettext 'Manual edit')'"</label>
</text>
</hbox>
<action signal="enter-notify-event">hide:MENU_1</action>
<action signal="enter-notify-event">show:MENU_1B</action>
<variable>MENU_1</variable>
</eventbox>
<eventbox name="rightclick_menu" above-child="true" visible-window="true" visible="false">
<hbox spacing="7" border-width="3">
<pixmap space-expand="false" space-fill="false">
<height>18</height>
<input file>/usr/share/pixmaps/puppy/remove.svg</input>
</pixmap>
<text xalign="0" space-expand="true" space-fill="true">
<label>"'$(gettext 'Manual edit')'"</label>
</text>
</hbox>
<action signal="leave-notify-event">show:MENU_1</action>
<action signal="leave-notify-event">hide:MENU_1B</action>
<action signal="button-release-event">echo edit > '$WORKDIR'/tray_menu_OUTPUT</action>
<action signal="button-release-event">EXIT:exit</action>
<variable>MENU_1B</variable>
</eventbox>
As we see, it's actual 2 set of the same menu-item - one normal, and one highlighted. Switching between them (hide itself / show opponent) when getting the leave-notify-event signal. The highlight color is handled by the extended gtk-theme described above in the style Rightclick_menu. Truly, setting the highlight color to #888, does not follow the global gtk-theme. To do that, you have to grab the foreground color in the active theme. - Not to be described in this blogpost.
The complete code is seen at github
Edit - Delete
No comments posted yet.