LINUX.ORG.RU

помогите с C + GTK


0

0

Привет всем, ребят тут один Анонимус поделился кодом, работает хорошо, но увы моих познаний в C + GTK никак не хватает добавить одну функцию.

сам код делает следующие, если загрузить этот модуль с какоилибо программой , например тхунар, то можно по хоткею убрать/показать меню.

а мне хотелось бы чтобы уже при запуске меню было убрано (спрятано), но если надо то по нажатию хоткеяв оно появляется.

ещё было бы здорово если ктонить мельком обясним бы как оно работает, и какие аргументы надо передать функции toggle_menu_bar чтоб оно работало =(

вобщем вот сам код:

#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>

#define _gtk_marshal_VOID__VOID g_cclosure_marshal_VOID__VOID
#define _gtk_marshal_NONE__NONE _gtk_marshal_VOID__VOID

static GObject* (*old_gtk_menu_bar_constructor)(GType type, guint n_construct_properties, GObjectConstructParam *construct_params) = NULL;
static GObject* (*old_gtk_window_constructor)(GType type, guint n_construct_properties, GObjectConstructParam *construct_params) = NULL;

static void toggle_menu_bar (GtkWidget *widget, gpointer user_data)
{
        GtkWidget * wdg = GTK_WIDGET(user_data);
        if (GTK_WIDGET_VISIBLE(wdg))
                gtk_widget_hide(wdg);
        else
                gtk_widget_show(wdg);
}

static void anchor_event (GtkWidget *widget, GtkWidget *previous_toplevel, gpointer   user_data)
{
        GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
        if (GTK_WIDGET_TOPLEVEL (toplevel)) {
                if (previous_toplevel) 
                        g_signal_handlers_disconnect_by_func(previous_toplevel, G_CALLBACK(toggle_menu_bar), widget);
                g_signal_connect (toplevel, "toggle-menu-bar", G_CALLBACK(toggle_menu_bar), widget);
        }
}

GObject* new_gtk_menu_bar_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_params)
{
	GObject * ret = old_gtk_menu_bar_constructor(type,n_construct_properties,construct_params);
        g_signal_connect (ret,"hierarchy-changed", G_CALLBACK(anchor_event), NULL);

        return ret;
}

G_MODULE_EXPORT void
gtk_module_init (gint * argc, gchar *** argv)
{
	GtkWidget *fc;
	GObjectClass *klass;

        g_signal_new ("toggle-menu-bar",
                      GTK_TYPE_WINDOW,
                      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                      0,
                      NULL, NULL,
                      _gtk_marshal_VOID__VOID,
                      G_TYPE_NONE,
                      0);
        

	fc = gtk_menu_bar_new();
	klass = GTK_MENU_BAR_GET_CLASS(fc);
	old_gtk_menu_bar_constructor = klass->constructor;
	klass->constructor = new_gtk_menu_bar_constructor;

	fc = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	klass = GTK_WINDOW_GET_CLASS(fc);
        gtk_binding_entry_add_signal (gtk_binding_set_by_class (klass), GDK_m, GDK_CONTROL_MASK,
                                "toggle-menu-bar", 0);
}

зы как уже сказал код не мой, если товарищ аннонимус увидет, то говорю ему ещё раз большое спасибо =))

★★

Пожалуйста. Завтра с мешком за деньгами зайду.

anonymous
()

Здесь сложность в том, что после создания меню (при этом срабоает эта реализация перехвата конструктора), то в дальнейшем коде приложения скорее всего явно стоит gtk_widget_show, посему, даже если здесь, в новом конструкоре, сказать ***_hide, то в основном коде программы будет вызван ***_show и меню будет отображено.

Deleted
()

Как-то так :)

#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>

#define _gtk_marshal_VOID__VOID g_cclosure_marshal_VOID__VOID
#define _gtk_marshal_NONE__NONE _gtk_marshal_VOID__VOID

static GObject* (*old_gtk_menu_bar_constructor)(GType type, guint n_construct_properties, GObjectConstructParam *construct_params) = NULL;
static GObject* (*old_gtk_window_constructor)(GType type, guint n_construct_properties, GObjectConstructParam *construct_params) = NULL;
static void     (*old_widget_show) (GtkWidget * widget) = NULL;

static void toggle_menu_bar (GtkWidget *widget, gpointer user_data)
{
        GtkWidget * wdg = GTK_WIDGET(user_data);
	GTK_WIDGET_GET_CLASS(wdg)->show = old_widget_show;
        if (GTK_WIDGET_VISIBLE(wdg))
                gtk_widget_hide(wdg);
        else
                gtk_widget_show(wdg);
}

static void anchor_event (GtkWidget *widget, GtkWidget *previous_toplevel, gpointer   user_data)
{
        GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
        if (GTK_WIDGET_TOPLEVEL (toplevel)) {
                if (previous_toplevel) 
                        g_signal_handlers_disconnect_by_func(previous_toplevel, G_CALLBACK(toggle_menu_bar), widget);
                g_signal_connect (toplevel, "toggle-menu-bar", G_CALLBACK(toggle_menu_bar), widget);
        }
}

static void show (GtkWidget *widget)
{
	if (GTK_IS_MENU_BAR(widget))
		return;
	old_widget_show(widget);
}

GObject* new_gtk_menu_bar_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_params)
{
	GObject * ret = old_gtk_menu_bar_constructor(type,n_construct_properties,construct_params);
        g_signal_connect (ret, "hierarchy-changed", G_CALLBACK(anchor_event), NULL);

        return ret;
}

G_MODULE_EXPORT void
gtk_module_init (gint * argc, gchar *** argv)
{
	GtkWidget *fc;
	GObjectClass *klass;

        g_signal_new ("toggle-menu-bar",
                      GTK_TYPE_WINDOW,
                      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                      0,
                      NULL, NULL,
                      _gtk_marshal_VOID__VOID,
                      G_TYPE_NONE,
                      0);
        

	fc = gtk_menu_bar_new();
	klass = GTK_MENU_BAR_GET_CLASS(fc);
	old_gtk_menu_bar_constructor = klass->constructor;
	klass->constructor = new_gtk_menu_bar_constructor;
	old_widget_show = GTK_WIDGET_CLASS(klass)->show;
	GTK_WIDGET_CLASS(klass)->show = show;

	fc = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	klass = GTK_WINDOW_GET_CLASS(fc);
        gtk_binding_entry_add_signal (gtk_binding_set_by_class (klass), GDK_m, GDK_CONTROL_MASK,
                                "toggle-menu-bar", 0);
}

anonymous
()
Ответ на: комментарий от anonymous

классс, иммено то что надо, большое тебе спасибо =))))

djung ★★
() автор топика
Ответ на: комментарий от anonymous

смотрю на все эти перехваты :)... смахивает на хак :)

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.