环境:debian 12.5、mate desktop。
参考:marco 1.20.2
marco-1.png
如上图,当点击窗口菜单的最大化按钮,marco 如何与系统交互来相应此要求呢?
首先,meta_window_maximize 函数负责将窗口最大化的具体操作。此函数会在menu_callback中被调用。menu_callback会作为参数传递给函数meta_ui_window_menu_new.至此,存在如下两个问题。
- 用户点击窗口菜单的最大化按钮,这个要求是如何传递到marco的。
- 窗口最大化要求被传递到marco后,menu_callback是如何被调用的。
第一个问题主要涉及到GTK+相关,此篇文章,主要关心marco内部动作,因此,现在我们主要对第二个问题进行代码跟踪说明。
对于第二个问题,首先需要知道menu_callback被放置在什么地方。基于此,需要对函数meta_ui_window_menu_new函数流程进行分析。
void meta_window_show_menu (MetaWindow *window,
int root_x,
int root_y,
int button,
guint32 timestamp)
{
......
menu =
meta_ui_window_menu_new (window->screen->ui,
window->xwindow,
ops,
insensitive,
meta_window_get_net_wm_desktop (window),
meta_screen_get_n_workspaces (window->screen),
menu_callback,
NULL);
......
}
MetaWindowMenu*
meta_ui_window_menu_new (MetaUI *ui,
Window client_xwindow,
MetaMenuOp ops,
MetaMenuOp insensitive,
unsigned long active_workspace,
int n_workspaces,
MetaWindowMenuFunc func,
gpointer data)
{
return meta_window_menu_new (ui->frames,
ops, insensitive,
client_xwindow,
active_workspace,
n_workspaces,
func, data);
}
MetaWindowMenu*
meta_window_menu_new (MetaFrames *frames,
MetaMenuOp ops,
MetaMenuOp insensitive,
Window client_xwindow,
unsigned long active_workspace,
int n_workspaces,
MetaWindowMenuFunc func,
gpointer data)
{
......
MetaWindowMenu *menu;
......
menu->func = func;
......
else if (menuitem.type != MENU_ITEM_SEPARATOR)
{
......
md = g_new (MenuData, 1);
md->menu = menu;
......
g_signal_connect_data (G_OBJECT (mi),
"activate",
G_CALLBACK (activate_cb),
md,
(GClosureNotify) g_free, 0);
}
}
}
根据上述代码流程,menu_callback函数存放在MenuData数据结构中menu成员的func指针中。
最终,menu_callback会在active_cb函数中被调用。
static void activate_cb(GtkWidget* menuitem, gpointer data)
{
......
md = data;
......
(*md->menu->func)(
md->menu,
GDK_DISPLAY_XDISPLAY (gdk_display_get_default()),
md->menu->client_xwindow,
gtk_get_current_event_time(),
md->op,
GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menuitem), "workspace")),
md->menu->data);
}