GTK窗口,如何获得窗口装饰尺寸?

时间:2016-03-10 05:55:04

标签: widget window gtk

我正在寻找相当于AdjustWindowRect的功能,可以获得窗口标题和边框的宽度/高度。

我们在GTK 3中有这个功能吗?好像不是。 我查看了所有gtk_window_xxx,gtk_widget_xxx和gdk_window_xxx *函数...

更新:

原则上,我可以将窗口镶边/装饰尺寸确定为gdk_window_get_frame_extents()gtk_widget_get_allocation() / gdk_window_get_origin()的增量,但

  1. 只有在屏幕上出现窗口后才能工作。我之前需要它 - 计算初始窗口位置。
  2. 这真是个黑客。

4 个答案:

答案 0 :(得分:1)

由Window Manager决定。 您可以通过发送消息_NET_REQUEST_FRAME_EXTENTS来请求它,如EWMH规范(扩展窗口管理器提示)中所述:

_NET_REQUEST_FRAME_EXTENTS
  window = window for which to set _NET_FRAME_EXTENTS
  message_type = _NET_REQUEST_FRAME_EXTENTS
     

尚未映射窗口的客户端可以请求   Window Manager估计它将被赋予的帧范围   映射。要检索这样的估计,客户必须发送一个   _NET_REQUEST_FRAME_EXTENTS消息到根窗口。窗口管理器必须通过估计预期的帧范围来响应   相应地设置窗口的_NET_FRAME_EXTENTS属性。该   客户端必须处理生成的_NET_FRAME_EXTENTS PropertyNotify   事件。这样窗口管理器就有了很好的估算基础   客户端必须在发送之前设置它想要设置的任何窗口属性   这条信息。客户必须能够应对不完美   估计。

     

理由:客户无法计算其窗口的尺寸   窗口映射前的帧,但有些工具包需要这个   信息。要求窗口管理器估计范围   是一个可行的解决方案。估计可能取决于当前的主题,   字体大小或其他窗口属性。客户端可以跟踪更改   通过侦听_NET_FRAME_EXTENTS来查看框架的尺寸   PropertyNotify事件。

https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472648576

所以,用两个词来说,你发送一个_NET_REQUEST_FRAME_EXTENTS消息到WM(到根窗口 - 它是gdk的gdk_get_default_root_window()),然后等待回复(_NET_FRAME_EXTENTS PropertyNotify),并获得所需的来自您窗口的_NET_FRAME_EXTENTS属性的数据。

答案 1 :(得分:0)

你是正确的,功能不存在。 GTK不知道窗口管理器放在窗户上的装饰;对于您的应用程序所知道的所有内容,可能有巨大的装饰,或者可能没有。

你可以做的是,使用gtk_window_set_titlebar()告诉窗口管理员让你使用自己的装饰;然后你可以完全控制它们的大小。

答案 2 :(得分:0)

值得注意的是,AdjustWindowRect()AdjustWindowRectEx()假设您纯粹使用默认的Windows窗口装饰,并且可选择一个行的默认值Windows菜单。它不适合自定义窗口装饰或多行菜单;在这些情况下,您使用WM_NCCALCSIZE消息,该消息必须发送到特定窗口。如果您只想要默认值,DefWindowProc()可以为您完成所有工作。 (Example for multi-row menus.如果您没有使用默认的Windows菜单,那么只需告诉Windows您不是;在这种情况下,您自己负责定位所有内容.GtkMenuBar就此工作原则也是。)

由于你想要默认装饰,你只是幸运的是,Windows首先提供了AdjustWindowRect()功能,并且它将用于默认窗口装饰,因为它是由Windows提供的。

(一个程序完全有可能位于WM_NCCALCSIZE,但它也会对Windows说谎,Windows也不喜欢骗子。我想这同样适用于{ {1}},虽然我不确定在这种情况下损害会有多严重。)

因此X11没有保证所有窗口管理员必须遵循的事实意味着您在该部门运气不佳。 (事实上​​,我不认为Wayland也有这样的事情;是吗?)天哪,没有什么可以阻止窗口管理员not having window decorations at all。或者你甚至可以not run a window manager in the first place

从理论上讲,可以比较窗口的大小和位置(GdkWindow的几何或GtkWindow的分配有和没有CSD,看看你失去了什么空间。但我不知道这是否可靠。 GTK +开发人员需要确认。

答案 3 :(得分:0)

不幸的是,GTK的情况比仅仅获得装饰的问题还要糟糕。

第一个:

gtk_window_move(window, x, y)设置窗口的边框 frame 位置。

然后gtk_window_resize(window, w, h)设置窗口的 client 尺寸。

GTK API中绝对没有办法以编程方式和显式方式设置边框 frame 的大小。因此,无法设置装饰窗的窗框位置/大小。

在Windows和MacOS上,使用它们的API可以轻松,可靠地进行操作。但是在GTK上,他们只有这样:

  

gtk_window_move():请求窗口管理器将窗口移至   给定位置。窗口管理者可以自由地忽略这一点。大多数窗口   经理忽略对初始窗口位置的请求(而是使用   用户定义的放置算法)并在窗口之后接受荣誉请求   已经显示。