日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

Windows平台下GTK 窗口在任务栏的隐藏问题以及解决办法

發布時間:2024/1/8 windows 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows平台下GTK 窗口在任务栏的隐藏问题以及解决办法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一口氣寫上了這么長的一個標題,估計嚇到不少人。這個問題并不常見,也不是一個很大很嚴重的問題。但是確實存在,并且gtk的文檔里沒有說清楚。這導致了我走了一些彎路。好了,進入正題。

我們通過gtk_window_new新建一個GtkWindow后,一般情況下(不經過我們的特殊處理),當把這個窗口顯示出來時,就會在任務欄中顯示窗口的圖標。但是有些時候我們不想要這個圖標,比如,菜單窗口,是不應該有這個圖標的。

GtkWindow中提供了gtk_window_set_skip_taskbar這個函數,并且有這樣的說明:"Windows may set a hint asking the desktop environment not to display the window in the task bar. This function sets this hint.”這不正是我們要的嗎?!很遺憾,在Linux上是可以的,但是在Windows上就不行了。

可以通過下面的代碼進行驗證:

#include

static gboolean flag = TRUE;
gboolean destroy(GtkWidget *widget, gpointer data)
{
??? gtk_main_quit();
}

gboolean clicked(GtkButton *button, gpointer data)
{
??? GtkWidget *window = (GtkWidget *)data;

??? g_print("skip taskbar:%d./n",
??????????? gtk_window_get_skip_taskbar_hint(GTK_WINDOW(window)));

??? if(flag)
??????? gtk_widget_hide_all(window);
??? else
??????? gtk_widget_show_all(window);

??? flag = !flag;
??? return FALSE;

}
int main(int argc,char ** argv )
{
??? gtk_init(&argc,&argv);
??? GtkWidget *window, *button,*layout;
??? GtkWidget *parent;
??? parent = gtk_window_new(GTK_WINDOW_TOPLEVEL);
??? window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
??? gtk_window_resize(GTK_WINDOW(window),100,200);
??? gtk_window_set_title(GTK_WINDOW(parent),"parent");
??? gtk_window_set_title(GTK_WINDOW(window),"child");???
??? gtk_window_set_decorated(GTK_WINDOW(window),FALSE);

??? gtk_widget_realize(window);
??? gtk_window_set_type_hint(GTK_WINDOW(window),GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU);

??? gtk_window_set_skip_taskbar_hint(GTK_WINDOW(window),TRUE);
??? layout = gtk_vbox_new(FALSE,0);
??? button = gtk_button_new_with_label("ok");
??? gtk_box_pack_start(GTK_BOX(layout),button,TRUE,TRUE,0);
??? gtk_container_add(GTK_CONTAINER(parent),layout);
??? g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(clicked),window);

??? g_signal_connect(G_OBJECT(parent),"destroy",G_CALLBACK(destroy),NULL);

??? gtk_widget_show_all(window);
??? gtk_widget_show_all(parent);
??? gtk_main();

}

?

這段代碼創建一個窗口,然后用gtk_window_set_skip_taskbar_hint將其在任務欄中隱藏。我們可以發現,在windows下,我們是無法通過gtk_window_set_skip_taskbar_hint函數讓窗口在任務欄中隱藏的。

其實,這個問題在gtk的開發人員也是知道的。請看這里,https://bugzilla.gnome.org/show_bug.cgi?id=537183,但幾年過去了,問題卻沒有解決。

通過查看相關源碼,可以看到,在gtk_window_set_skip_taskbar_hint中,實際上會調用gdk_window_set_skip_taskbar_hint來完成主要的隱藏工作,而在gdk_window_set_skip_taskbar_hint函數中(在gdkwindow-win32.c文件中),讓人很意外,本質上這個函數什么事情都沒做。所以,想通過這個函數來實現在任務欄中的隱藏是不可能的。

參考這個鏈接,我們可以看到,gdk的官方文檔里并不支持使用gdk_window_set_skip_taskbar_hint來隱藏任務欄圖標,它們建議使用gdk_window_set_type_hint(),由窗口類型來決定是否應該在任務欄中顯示圖標。

這樣做就可以了嗎?不是的。在上面的代碼中,我們看到里面已經過窗口的類型設置成GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU(也可以使用gdk_window_set_type_hint,結果一樣),可是照樣在任務欄中可以看到這個下拉菜單的圖標。

問題回到最初,什么樣的窗口在任務欄中是需要隱藏的?換句話說,就是什么樣的窗口在任務欄中是可以顯示的。回答這個問題暫時沒有找到windows下的明確規定,但是參考metacity的文檔中的這段話:

Dialogs which have no transient parent or root window being
their tranisent parent are the ones which will be visible in
the tasklist.

我們可以推測,如果窗口不是transient 窗口,或者不是root窗口的transient 窗口,它就可以顯示在任務欄中。換言之,如果我們想讓一個窗口不顯示在任務欄中,就指定它是某一個非root窗口的transient窗口。

在我們的測試代碼中,在設置完窗口類型后,加入:

gtk_window_set_transient_for(GTK_WINDOW(window),GTK_WINDOW(parent));

現在,無論窗口是何種類型,都不會在任務欄中顯示了。

我們再看一下gdk_window_set_skip_taskbar_hint的實現代碼:

void
gdk_window_set_skip_taskbar_hint (GdkWindow *window,
????????????????? gboolean?? skips_taskbar)
{
? static GdkWindow *owner = NULL;
? //GdkWindowAttr wa;

? g_return_if_fail (GDK_IS_WINDOW (window));

? GDK_NOTE (MISC, g_print ("gdk_window_set_skip_taskbar_hint: %p: %s, doing nothing/n",
?????????????? GDK_WINDOW_HWND (window),
?????????????? skips_taskbar ? "YES" : "NO"));

? // ### TODO: Need to figure out what to do here.
? return;

? if (skips_taskbar)
??? {
#if 0
????? if (owner == NULL)
??????? {
????????? wa.window_type = GDK_WINDOW_TEMP;
????????? wa.wclass = GDK_INPUT_OUTPUT;
????????? wa.width = wa.height = 1;
????????? wa.event_mask = 0;
????????? owner = gdk_window_new_internal (NULL, &wa, 0, TRUE);
??????? }
#endif

????? SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, (LONG_PTR) GDK_WINDOW_HWND (owner));

#if 0 /* Should we also turn off the minimize and maximize buttons? */
????? SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
???????????? GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE) & ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU));
????? SetWindowPos (GDK_WINDOW_HWND (window), NULL,
??????????? 0, 0, 0, 0,
??????????? SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
??????????? SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
#endif
??? }
? else
??? {
????? SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, 0);
??? }
}

可以看到,作者原先的意思是如果需要skip taskbar,就為這個窗口找一個父窗口。通過下面的語句實現:

SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, (LONG_PTR) GDK_WINDOW_HWND (owner));

但是不知作者基于什么樣的原因,在類型判斷之后就return了。

也有人提出了另外的解決方法,就是通過gdk_win32_drawable_get_handle得到窗口的句柄,然后再用SetWindowLong這個Windows API來設置窗口的屬性。這種方法是也是可行的(我只試過簡單的),如果做得完善的話,說不定就修正了gtk_window_set_skip_taskbar_hint無法正常使用的問題了。

總結

以上是生活随笔為你收集整理的Windows平台下GTK 窗口在任务栏的隐藏问题以及解决办法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。