I am attempting to re-parent a child window Gtk::Window so that I can emulate the deprecated GTKMM 4 call to position the window in the centre of the parent (which was present in GTKMM 3). I have searched for XReparentWindow posts and the only relevant one advised to use XSetTransientForHint this which did not work for me. The code that I have written is:
void MyGtk::Window_Centre_Child_On_Parent(
Gtk::Window *parent,
Gtk::Window *child
)
{
int child_height;
int child_width;
int parent_height;
int parent_width;
int position_x;
int position_y;
//
//First we must validate all parameters and terminate if any fail.
//
assert(parent);
assert(child);
//
//Now we need to fetch the size of the child window so that we can then
//re-parent the window at the centre of the parent window thus emulating
//the GTKMM 3 set position call. This has been deprecated in GTKMM 4.
//
Widget_Get_Size(
child,
child_width,
child_height
);
//
//Now we need to ensure that the above returned sensible values and we
//terminate if not.
//
assert(child_height > 0);
assert(child_width > 0);
//
//Now we need to fetch the size of the parent window so that we can then
//re-parent the window at the centre of the parent window thus emulating
//the GTKMM 3 set position call. This has been deprecated in GTKMM 4.
//
Widget_Get_Size(
parent,
parent_width,
parent_height
);
//
//Now we need to ensure that the above returned sensible values and we
//terminate if not.
//
assert(parent_height > 0);
assert(parent_width > 0);
//
//Now we need to fetch the X windows ID for the child window. This ID
//is what is used to refer to windows within the X windows library.
//
auto child_window = Window_Get_X_Windows_ID(child);
assert(child_window > 0);
//
//Now we need to fetch the X windows ID for the parent window. This ID
//is what is used to refer to windows within the X windows library.
//
auto parent_window = Window_Get_X_Windows_ID(parent);
assert(parent_window > 0);
//
//Now we need to open the X windows display for the X server instance
//that is running. We could also use the DISPLAY environment variable
//but the below is faster as it does not have to fetch the environment.
//
auto display = XOpenDisplay(XDisplayName(nullptr));
assert(display);
//
//Now we need to calculate where to place the child window within the
//parent window. This depends on the size of the child as using the
//centre of the parent can mean that the child window does not fit on
//the display.
//
position_x = abs(
std::min(
parent_width / 2,
(parent_width - child_width) / 2
)
);
position_y = abs(
std::min(
parent_height / 2,
(parent_height - child_height) / 2
)
);
//
//Now we need to ensure that the child window will be transient for the
//parent window.
//
XSetTransientForHint(
display,
child_window,
parent_window
);
//
//Now we need to re-parent the child window to the parent window and we
//set the (X, Y) co-ordinate such that the top left corner of the child
//window will be in the centre of the parent window.
//
XReparentWindow(
display,
child_window,
parent_window,
position_x,
position_y
);
//
//Now we need to flush any changes made to the display.
//
XFlush(display);
//
//Finally, we need to close the display and thus release any resources
//associated with it.
//
XCloseDisplay(display);
}
What I see is that all of the decorations for the child window are removed but if I do not use the above code and simply display the dialog the decorations are rendered correctly. I would very much appreciate any hints on how to solve this problem.
Searched for XReparentWindow within stack overflow and found a possible solution (see link) that did not work for me.