GTK+ MenuItem Size Small - menuitem

On a machine running Windows, the MenuItems are too small for my use case.
Therefore, my question is, "how I may increase the font size of the text "Save", "Load" and "Exit?" "
If not, then how can I increase the padding between the MenuItems?
(without adding more of those line separators as seen between "Load" and "Exit")
Additionally, how may I remove the intermediate variable SubMenu1, if possible?
Cropped Screenshot
Below is a complete source to reproduce:
#include <gtk/gtk.h>
int main (int argc, char *argv[]) {
gtk_init (&argc, &argv);
GtkWidget* Window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GtkWidget* MenuBar = gtk_menu_bar_new();
GtkWidget* MenuItem_File = gtk_menu_item_new_with_mnemonic("_File");
GtkWidget* SubMenu1 = gtk_menu_new();
GtkWidget* Item_Save = gtk_menu_item_new_with_mnemonic("_Save");
GtkWidget* Item_Load = gtk_menu_item_new_with_mnemonic("_Load");
GtkWidget* Item_Exit = gtk_menu_item_new_with_mnemonic("_Exit");
gtk_menu_shell_append(GTK_MENU_SHELL(SubMenu1), Item_Save);
gtk_menu_shell_append(GTK_MENU_SHELL(SubMenu1), Item_Load);
gtk_menu_shell_append(GTK_MENU_SHELL(SubMenu1), gtk_separator_menu_item_new());
gtk_menu_shell_append(GTK_MENU_SHELL(SubMenu1), Item_Exit);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(MenuItem_File), SubMenu1);
gtk_menu_shell_append(GTK_MENU_SHELL(MenuBar), MenuItem_File);
GtkWidget* VerticalBox;
VerticalBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start(GTK_BOX(VerticalBox), MenuBar, false, false, 0);
gtk_container_add(GTK_CONTAINER(Window), VerticalBox);
gtk_widget_show_all(MenuBar);
gtk_widget_show(VerticalBox);
gtk_window_set_default_size(GTK_WINDOW(Window), 950, 600);
gtk_window_set_position(GTK_WINDOW(Window), GTK_WIN_POS_CENTER);
gtk_window_set_title(GTK_WINDOW(Window), "My Title");
gtk_widget_show(Window);
gtk_main();
return 0;
}

Gtk3's font size control (and other style properties) are delegated to the CSS files. It is generally discouraged to do this in your program (though this is certainly possible - have a look at Gtk3's CSS_provider functions). But normally you would like your program to look 'compatible' with other programs, I suspect.
The reason is that the aspect of your program should be controllable from the outside - be it for reasons of personal taste, or for accessibility. So, if you consider the font style for the menus etc, too small, you can:
Choose another 'theme' or style, eg. on the Gnome-Look site
Look at the Window manager's preferences for an 'Appearance' setting (as it is called in XFCE. There are similar tools in Gnome, KDE, etc.)
Modify the CSS files of the theme you are currently using
Many other visual aspects are controlled from the CSS files: Separation between elements (eg. menuitems), rounding of corners, visual effects, etc etc... but, thanks to the CSS system, you can normally just 'tweak' the items you like.
EDIT: If you want to run the executable on another machine, you'd probably need a window manager to run it under, which makes the above still valid.
There is still another solution (which I mentioned above, first paragraph), which is to change the CSS temporarily using the CSS provider set of Gtk functions. If you really want to code program rigidly, you can use the modify_font method of GtkWidget.

Related

Create window without title bar

I am trying to create a simple panel for Openbox in Arch Linux using c++, but I cannot figure out how to remove the title bar from a window.
I am creating the window with XCreateWindow(...), and that gives a window with the correct size, but it contains a title bar, and the window also opens in the top-left corner of the screen, no matter what offset coordinates I specify.
I read here that both of these problems are probably caused by the window manager (Openbox), which overrides the window attributes I specified in XCreateWindow(..., &window_attributes). This could be solved by adding window_attributes.override_redirect = True;, although this does not seem to do anything for me. When I try this I get the exact same window as before. (I did compile the file after this change.)
Also I read into the code of Tint2 (link), which is another panel for Openbox. They create a window using the following code:
XSetWindowAttributes att = { .colormap=server.colormap, .background_pixel=0, .border_pixel=0 };
p->main_win = XCreateWindow(server.dsp, server.root_win, p->posx, p->posy, p->area.width, p->area.height, 0, server.depth, InputOutput, server.visual, mask, &att);
I don't see an override_redirect anywhere in their code, so I'm not sure how they are removing the title bar.
As additional information, I thought it would be worth mentioning how I'm executing the script:
/* The c++ file is saved as 'panel.cpp' */
$ gcc panel.cpp -lX11 -o panel
$ ./panel
Also, I am running Arch Linux through VirtualBox with Windows 8 as host. I'm not sure if this changes anything, but it won't hurt to mention.
Since I found the solution, I figured I'd post the solution here if anyone else needs it.
As #JoachimPileborg mentioned, I needed to alter the Openbox settings in ~/.config/openbox/rc.xml. Inside the <applications> tag, I added the following code:
<application class="*">
<decor>no</decor>
<position force="no"></position>
</application>
The class="*" means that all applications will follow these rules, you could fill in the class name of the application instead. The <decor>no</decor> removes the title bar, and <position force="no"></position> ensures that my own script is able to handle the positioning. You could also add another <application> tag after this one to make exceptions to this rule.
Also, the window_attributes.override_redirect = True; is not needed anymore.
A more correct way is to use the Extended Window Manager Hints.
The idea is that you don't tell the window manager how to decorate or not your window, you just indicate the window type with _NET_WM_WINDOW_TYPE :
Atom window_type = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
long value = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DOCK", False);
XChangeProperty(display, your_window, window_type,
XA_ATOM, 32, PropModeReplace, (unsigned char *) &value,1 );
"Dock" is the type for panels and taskbar. Usually they are undecorated and appear on all desktops. As written on the documentation, previously the _MOTIF_WM_HINTS property was used to define the appearance and decorations of the window. Window managers still support it, but _NET_WM_WINDOW_TYPE is prefered as it describe the function and let the window manager (and user) decide on the appearance and behavior of that type of window.
Another interesting property for a panel is _NET_WM_STRUT_PARTIAL, to "reserve" space.

c++ attaching to thread (taking focus)

So, (I rewrote this since a lot of people didn't understand me. I apologize.)
I'd like to bring the window of my qt application to the very front of ALL windows on screen.
I've heard you can do this by attaching to the thread of the foreground window and then "stealing focus" aka putting yourself where that foreground window was.
(I'm using OSX, so windows.h is no option for me.)
I hope you understand now.
To bring a window to the front, ensure the window is visible, then activate the window.
As the docs state: -
Sets the top-level widget containing this widget to be the active window.
And
If you want to ensure that the window is stacked on top as well you should also call raise().
So, assuming you have a window called pWindow, you can do something like this: -
pWindow->raise();
pWindow->show();
pWindow->activateWindow();
Also note that OS X can have multiple desktops (Spaces). If you also want the window to track the user's Space when they switch between them, you can add this function to your window class: -
void MyWindow::DisplayOnAllSpaces()
{
// ensure we stay on the active desktop
WId windowObject = this->winId();
objc_object* nsviewObject = reinterpret_cast<objc_object *>(windowObject);
objc_object* nsWindowObject = objc_msgSend(nsviewObject, sel_registerName("window"));
int NSWindowCollectionBehaviorCanJoinAllSpaces = 1 << 0;
objc_msgSend(nsWindowObject, sel_registerName("setCollectionBehavior:"), NSWindowCollectionBehaviorCanJoinAllSpaces);
}

How come allegro automatically handles minimize button, but not close button?

Here is a sample from Allegro5 tutorial: (to see the original sample, follow the link, I've simplified it a bit for illustratory purposes.
#include <allegro5/allegro.h>
int main(int argc, char **argv)
{
ALLEGRO_DISPLAY *display = NULL;
ALLEGRO_EVENT_QUEUE *event_queue = NULL;
al_init()
display = al_create_display(640, 480);
event_queue = al_create_event_queue();
al_register_event_source(event_queue, al_get_display_event_source(display));
al_clear_to_color(al_map_rgb(0,0,0));
al_flip_display();
while(1)
{
ALLEGRO_EVENT ev;
ALLEGRO_TIMEOUT timeout;
al_init_timeout(&timeout, 0.06);
bool get_event = al_wait_for_event_until(event_queue, &ev, &timeout);
//-->// if(get_event && ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
//-->// break;
//-->// }
al_clear_to_color(al_map_rgb(0,0,0));
al_flip_display();
}
al_destroy_display(display);
al_destroy_event_queue(event_queue);
return 0;
}
If I don't manually check for the ALLEGRO_EVENT_DISPLAY_CLOSE, then I can't close the window or terminate the program (without killing the process through task manager). I understand this. But in this case I don't understand how the minimize button works without me manually handling it. Can someone please explain?
Disclaimer: I don't know Allegro.
Minimizing a window at the most basic level only involves work from the process that deals with the windows (the Window Manager), not the process itself.
Terminating a program, usually requires files to be closed or memory to be freed or something else that only the process itself can do.
The biggest reason that you must handle it yourself via an event is that closing (destroying) a window invalidates the ALLEGRO_DISPLAY * pointer. The request to terminate the window comes from a different thread, so it would be unsafe to destroy it immediately. Allowing you to process it yourself on your own time is safe and easy, and fits in with the event model that Allegro 5 uses for all other things.
There are other ways to solve the problem, but they are no more simple than this method and don't really have any major advantages.
I don't know anything about allegro, but minimizing windows is generally handled by the window manager without the need of further intervention by your program. The main window is set to a "minimized"-state and your program continues running in the background without a visible window.
You can check if your app is being minized by intercepting specific window-messages (those being WM_ACTIVATEAPP, WM_ACTIVATE or WM_SIZE). Maybe allegro provides something like that, too.
In contrast closing the window does need to be done by your program. Clicking on the X simply sends a message to the window (WM_CLOSE), that the user has clicked it, and you have to respond accordingly (save states, quit the program, or you could prevent it).
At least that's how the normal winapi works, and allegro seems to work the same way.

Glade C++ app, GUI design not the same at Runtime

Im very new to gui programming in linux and Im stumbling at the 1st hurdle, Im using glade to design a form (i come from windows background) it looks completly different in Glade than it does when I run the compiled program.
heres a screen grab of them
see link as they wont let me post images
heres the c++
#include <gtk/gtk.h>
void close_app(GtkWidget* widget,gpointer user_data) {
gtk_main_quit();
}
int main (int argc, char **argv) {
GtkBuilder *gtkBuilder;
GtkWidget *mainwin;
gtk_set_locale();
gtk_init (&argc, &argv);
gtkBuilder= gtk_builder_new();
gtk_builder_add_from_file(gtkBuilder,"test2.glade",NULL);
gtk_builder_connect_signals ( gtkBuilder, NULL );
mainwin= GTK_WIDGET(gtk_builder_get_object(gtkBuilder,"window1"));
g_object_unref ( G_OBJECT(gtkBuilder) );
gtk_widget_show_all ( mainwin );
gtk_main ();
return 0;
}
im on debian squeeze and im using libgtk2.0-dev version 2.20 libgnome2.24 <- I dont even know if this mught be the problem?
any ideas?
Thanks
You have nothing in the empty spaces in your HBox and VBox. If there are no other widgets taking up the space, then your button will expand to fill all available space. Put some other widgets in your window if you don't want the button to fill it. Sizing and placement work differently in GTK than they do in other toolkits, the idea is to build a user interface that still looks good when the user resizes the window or when the UI strings change length because the user is using your application in another language.
See the relevant section of the GTK tutorial or this other tutorial.

Motif main window w/o system menu, minimize and maximize boxes how? (C++)

How do I create a Motif main window that doesn't have a system menu, minimize and maximize boxes? I just cannot find out how by googling and reading docs and tutorials. I believe that it should be possible with some additional parameters for XtVaCreateManagedWindow, but which?
I have tried several variants of XtVaSetValues (topWid, XmNmwmDecorations, ...) but none worked. Instead I get an error message that I need to use a vendor shell for this. Most widget types aren't derived from vendor shells however, and when I e.g. try to use a dialog shell and put a scrollable text widget inside of it, then then text widget seems to control the dialog.
Apparently it's not (easily) possible to get rid of the window (system) menu, but it seems to be possible to disable window menu items with some code like this:
int i;
XtVaGetValues (widget, XmNmwmFunctions, &i);
i &= ~(MWM_FUNC_ALL | MWM_FUNC_MINIMIZE | MWM_FUNC_MAXIMIZE | MWM_FUNC_CLOSE);
XtVaSetValues (widget, XmNmwmFunctions, i);
which removes the related window decoration too and apparently even works for non vendor shell widgets.
There should also be the possibility to remove the decorations (i.e. make them invisible). However, please note that these "system menu" decorations belong to the Window Manager, not your Motif program itself. It is up to the Window Manager to handle your requests or disregard them--you might get vendor-specific behavior with any MWM resources.
Anyway, here's the code sample to try out:
int decors; //bit-mask of flags defining the decorations, from Xm/MwmUtil.h
XtVaGetValues(dlg, XmNmwmDecorations, &decors, NULL);
decors &= ~MWM_DECOR_MENU;
decors &= ~MWM_DECOR_MAXIMIZE;
decors &= ~MWM_DECOR_MINIMIZE;
XtVaSetValues(dlg, XmNmwmDecorations, decors, NULL);
If you intend to run your application from Mwm, you can achieve the desired behavior by setting (e.g. via XtVaAppInitialize()) the following X11 resources:
! Title bar buttons
Mwm*YourApplicationClassHere.clientDecoration: -minimize -maximize
! Window menu functions
Mwm*YourApplicationClassHere.clientFunctions: -minimize -maximize
These resources are explained in more detail here and here.
Speaking of window menu, this one depends on a specific window manager in use. Mwm, for instance, allows the client to set the menu name using Mwm*YourApplicationClassHere.windowMenu resource, the menu itself must be defined in either ${HOME}/.mwmrc or global mwmrc, or XmNmwmMenu resource of VendorShell. The resulting custom window menu is exposed as a _MOTIF_WM_MENU atom, which seems to be ignored by modern window managers.
Sample mwmrc menu definitions may look like this
Menu CustomMenu0
{
Restore _R Alt<Key>F5 f.restore
Move _M Alt<Key>F7 f.move
Size _S Alt<Key>F8 f.resize
Minimize _n Alt<Key>F9 f.minimize
Maximize _x Alt<Key>F10 f.maximize
Lower _L Alt<Key>F3 f.lower
no-label f.separator
Pass\ Keys _K f.pass_keys
no-label f.separator
Close _C Alt<Key>F4 f.kill
}
Menu CustomMenu1
{
Your\ Application\ Name\ Here f.title
no-label f.separator
Close _C Alt<Key>F4 f.kill
}
(see the function descriptions). Custom menu items can be added using f.send_msg (examples here and here).
I'm pretty sure all of the above also applies to Dtwm (CDE).