GTK window, how to get window decoration sizes? - widget

I am looking for an equivalent of AdjustWindowRect function that allows to get widths/heights of window caption and borders.
Do we have this functionality in GTK 3 at all? Seems like not.
I've looked through all gtk_window_xxx, gtk_widget_xxx and gdk_window_xxx* functions...
Update:
In principle I am able to determine window-chrome/decoration dimensions as a delta of gdk_window_get_frame_extents() and gtk_widget_get_allocation() / gdk_window_get_origin() but
it works only after window appeared on the screen. I need it before that - to calculate initial window position.
it is really a hack.

It's up to Window Manager to decide.
You can request it by sending a message _NET_REQUEST_FRAME_EXTENTS as explained in the specification of EWMH (Extended Window Manager Hints):
_NET_REQUEST_FRAME_EXTENTS
window = window for which to set _NET_FRAME_EXTENTS
message_type = _NET_REQUEST_FRAME_EXTENTS
A Client whose window has not yet been mapped can request of the
Window Manager an estimate of the frame extents it will be given upon
mapping. To retrieve such an estimate, the Client MUST send a
_NET_REQUEST_FRAME_EXTENTS message to the root window. The Window Manager MUST respond by estimating the prospective frame extents and
setting the window's _NET_FRAME_EXTENTS property accordingly. The
Client MUST handle the resulting _NET_FRAME_EXTENTS PropertyNotify
event. So that the Window Manager has a good basis for estimation, the
Client MUST set any window properties it intends to set before sending
this message. The Client MUST be able to cope with imperfect
estimates.
Rationale: A client cannot calculate the dimensions of its window's
frame before the window is mapped, but some toolkits need this
information. Asking the window manager for an estimate of the extents
is a workable solution. The estimate may depend on the current theme,
font sizes or other window properties. The client can track changes to
the frame's dimensions by listening for _NET_FRAME_EXTENTS
PropertyNotify events.
https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472648576
So, in two words, you send a _NET_REQUEST_FRAME_EXTENTS msg to WM (to the root window - it's gdk_get_default_root_window() in case of gdk), then wait for the reply (_NET_FRAME_EXTENTS PropertyNotify), and get the desired data from your window's _NET_FRAME_EXTENTS property.

Unfortunately situation with GTK is even worse than just problem of getting decorations.
The first:
gtk_window_move(window, x, y) sets border frame position of the window.
And gtk_window_resize(window, w, h) sets client dimensions of the window.
And there is absolutely no way in GTK API to set border frame size programmatically and explicitly. And so there is no way to set window frame position/size of decorated windows.
On Windows and MacOS, using their APIs, that is easy to do, and reliably. But on GTK they only have this:
gtk_window_move(): Begs the window manager to move window to the
given position. Window managers are free to ignore this; most window
managers ignore requests for initial window positions (instead using a
user-defined placement algorithm) and honor requests after the window
has already been shown.

You are correct that the functionality is not there. GTK is agnostic of the decorations that the window manager places on the window; for all that your application is aware of, there may be giant decorations, or there may be none.
What you can do, is use gtk_window_set_titlebar() to tell the window manager to let you use your own decorations; then you have full control over their size.

For what it's worth, AdjustWindowRect() and AdjustWindowRectEx() assume that you are working purely with the default Windows window decorations and, optionally, one row of default Windows menus. It's not suitable for custom window decoration or multiple rows of menus; in these cases, you use the WM_NCCALCSIZE message, which has to be sent to a specific window. DefWindowProc() does all the work for you if you just want the defaults. (Example for multi-row menus. And if you aren't using default Windows menus, then just tell Windows that you aren't; you'll be responsible for positioning everything yourself in this case. GtkMenuBar works on this principle too.)
Since you want the default decorations, though, you merely luck out in that Windows provides an AdjustWindowRect() function in the first place, and that it will work for the default window decoration because it's provided by Windows.
(It is entirely possible for a program to lie in its WM_NCCALCSIZE, but it'd be lying to Windows as well, and Windows does not like a liar. I imagine the same would hold for _NET_REQUEST_FRAME_EXTENTS, though I'm not sure how bad the damage would be in that case.)
So the fact that X11 doesn't have this guarantee that all window managers must follow means you're out of luck in that department. (In fact, I don't think Wayland has such a thing either; does it?) Hell, nothing prevents a window manager from not having window decorations at all. Or you can even not run a window manager in the first place!
In theory, you could compare the size and position of a window (either the geometry of the GdkWindow or the allocation of the GtkWindow) with and without CSD to see what space you lost. But I don't know if this is reliable. A GTK+ developer will need to confirm.

Related

Is there a way to remove the option to minimize the application or maximize it, in pygame?

Is there a way to remove the option to minimize the application or maximize it, in pygame?
To not make it able to be resized, only add your dimensions to the pygame.display.set_mode function. Do not add options. If what you mean by "removing the option to minimize the application or maximize it" is get rid of the button altogether, you can't do this. When you create a window in pygame, pygame creates a window with whatever window api is for your platform. Pygame doesn't get to decide how your window should look (menu-bar/options). This is why windows in macos and linux look different from windows in windows. To recap, you don't get to chose how your windows look. That's the job of whatever window manager api your system uses.
screen = pg.display.set_mode((width, height), pg.NOFRAME)

Difference between a chrome popup and Panel

I am building an extension for Chrome and Can't decide If I should use chrome.windows.create type popup , panel or detached panel. I could not find a comparative study of the three options . Any links or short description of positives and limitations of each will be helpful .
Thanks
You are having difficulty understanding it, because unless you specifically enabled an experimental feature, they are exactly the same, or rather the latter ones are ignored and a popup type is created.
Unfortunately, this means that this API is unavailable for general use until Google decides to mark it stable.
Quoting the docs:
The 'panel' and 'detached_panel' types create a popup unless the '--enable-panels' flag is set.
As for what panels are, here is the API proposal with detailed description.
Panels are windows that are visible to the user even while the user is interacting with other applications. The small windows are positioned at the bottom of the screen, with minimal manual window management by the user. This API will allow extension developers to create and use panels.
[...]
An extension opens small "pop up" windows, for example, separate chat sessions, calculator, media player, stock/sport/news ticker, task list, scratchpad, that the user wants to keep visible while using a different application or browsing a different web site. Scattered "pop up" windows are difficult for the user to keep track of, therefore panels are placed along the bottom of the screen and are "always on top".
The user would like easy control of chat windows: finding them, moving them out of the way, etc. Window management of separate chat "pop ups" is time consuming. All panels can be minimized/maximized together.
If you want a real-life example, the Hangouts extension is whitelisted to use this window type; that's how they make the chat panels:
Since chrome doesn't by default enable panels , this need to be set to display panel behavior instead of popup window . Note that popup windows can be re positioned and one can view console window , but none of it is available in panel .

How to tell if a control is no longer visible to the user?

I have a control in which I repeatedly run some animations (e.g. DoubleAnimation). Can I detect if my control is no longer visible to the user? E.g it gets scrolled away from, the user navigates forward to another page, or it gets obscured behind other controls.
I don't want to run those animations unless at least some part of my control is visible for the user.
You could analyze the visual tree or get a transform from control coordinates to screen coordinates to see if its positioning is within the view port and also check things like opacities, visibilities etc. of controls down the visual tree path, but that is so processing intensive that it is not worth doing all the time for a general solution.
The only thing that would make sense is to handle the ScrollViewer.ViewChanged event and check if the offsets make it visible or not while limiting the TransformToVisual or VisualTreeHelper calls only to times when the actual layout within your ScrollViewer changes.

popup with resizing controls

I want to call a popup window where i lock the window size to maximum size possible and don't allow size/ aspect ratio to be changed subsequently. This saves overhead of doing relative sizing and positioning multiple times.
When I do use jscript, i find code that works for IE but not chrome and vice versa (haven't checked on any other browser). Is it possible to have single common solution for all browsers
function newPopup(url) { popupWindow= window.open( url,'popUpWindow','height=700,width=1200,left=1,top=1,resizable=no,scrollbars=no,toolbar=no,menubar=no,location=no,directories=no,status=yes')
}
popup open
The script line is getting truncated from message...
No, because other browsers are designed to be user-friendly, which, for example, means that the user can resize a window whenever he wants to.

swing: saving dialog box resize dimensions

I have a dialog box with a bunch of dimensions that a user can change by moving/dragging, including a JTable with resizable/draggable columns.
What I would like to do is to make the state of these resizable columns / dialog boxes / etc. persistent, so the next time my application starts up, the user doesn't have to go through the resizing step all over again.
What's the most convenient way to do this?
You should probably take a look at the code in (the now probably dead) JSR-296. A part of it was focused on persistent session state, and I know for sure that the code for persisting window locations and such was already functional and in the basic framework. It should either already do what you want, or provide a good starting point.
Cfr. dev.java.net site for JSR-296