2012-11-19 73 views
3

我想爲我用Python編寫的Gtk應用程序在屏幕上保留一些空間。我已經寫了這個功能:無法更改_NET_WM_STRUT_PARTIAL屬性

import xcb, xcb.xproto 
import struct 
def reserve_space(xid, data): 
    connection = xcb.connect() 
    atom_cookie = connection.core.InternAtom(True, len("_NET_WM_STRUT_PARTIAL"), 
     "_NET_WM_STRUT_PARTIAL") 
    type_cookie = connection.core.InternAtom(True, len("CARDINAL"), "CARDINAL") 
    atom = atom_cookie.reply().atom 
    atom_type = type_cookie.reply().atom 
    data_p = struct.pack("I I I I I I I I I I I I", *data) 
    strat_cookie = connection.core.ChangeProperty(xcb.xproto.PropMode.Replace, xid, 
     atom, xcb.xproto.Atom.CARDINAL, 32, len(data_p), data_p) 
    connection.flush() 

它的調用是這樣的:

utils.reserve_space(xid, [0, 60, 0, 0, 0, 0, 24, 767, 0, 0, 0, 0]) 

不幸的是,這是行不通的。我的代碼中有哪些錯誤?

UPD: Here是我的xprop輸出。我的WM是Compiz。

+0

你可以在調用之前和之後打印'xprop -id [xid here]'嗎?你使用的是什麼窗口管理器? –

回答

0

更改爲使用ChangePropertyChecked(),然後檢查結果給出BadLength異常。

我覺得這裏的錯誤是,ChangeProperty()參數data_lenformat給出的,而不是字節數大小的元素的個數,在屬性數據data

稍加修改代碼工作對我來說:

def reserve_space(xid, data): 
    connection = xcb.connect() 
    atom_cookie = connection.core.InternAtom(False, len("_NET_WM_STRUT_PARTIAL"), 
     "_NET_WM_STRUT_PARTIAL") 
    atom = atom_cookie.reply().atom 
    data_p = struct.pack("12I", *data) 
    strat_cookie = connection.core.ChangePropertyChecked(xcb.xproto.PropMode.Replace, xid, 
     atom, xcb.xproto.Atom.CARDINAL, 32, len(data_p)/4, data_p) 
    strat_cookie.check() 
    connection.flush() 
+0

請注意,對InternAtom使用only_if_exists = FALSE可能是一個好主意,因此如果此客戶端在WM(或任何其他實例爲「_NET_WM_STRUT_PARTIAL」的實例)客戶端啓動, – jturney

2

我已上傳gist演示如何指定什麼可能是一個任務欄跨越當前顯示器的頂部的支柱。這可能有助於解釋這一點。

我的要旨,其要旨在於以下:

window = gtk.Window() 
window.show_all() 
topw = window.get_toplevel().window 
topw.property_change("_NET_WM_STRUT","CARDINAL",32,gtk.gdk.PROP_MODE_REPLACE, 
     [0, 0, bar_size, 0]) 
topw.property_change("_NET_WM_STRUT_PARTIAL","CARDINAL",32,gtk.gdk.PROP_MODE_REPLACE, 
     [0, 0, bar_size, 0, 0, 0, 0, 0, x, x+width, 0, 0]) 

我找到了支撐論點在第一混淆,所以這裏是我所希望的是更清晰的解釋:

我們設置_NET_WM_STRUT,舊機制以及_NET_WM_STRUT_PARTIAL,但如果窗口管理者支持後者則忽略前者。是陣列中的數目如下:

  • 0, 0, bar_size, 0是沿着順序給出的屏幕的每一個邊緣留下保留像素的數目,右頂部底部。這裏,條的大小保留在屏幕的頂部,其他邊保留一個。
  • _NET_WM_STRUT_PARTIAL還提供另外四對,每個對都是支柱的開始和結束位置(它們不需要佔據整個邊緣)。

在這個例子中,我們將頂端開頭設置爲當前監視器的x座標,將頂端設置爲相同的值加上監視器的寬度。最終的結果是該空間僅在當前監視器上保留。

請注意,座標是相對於屏幕(即所有顯示器一起)指定的。