I'm doing an uni project with initially one main GLUT window and will have some sort of "login" GLUI window that, if succeed Draws the glut window. However I want to be able to close the login window after it succeeds.
I've been struggling with this for quite some time, and I've only managed to get it working with glui->hide. However I'm pretty sure the process/thread whatever keeps running on background decreasing the program's performance.
I want to be able to have that similar behavior thats in hide() method, but instead of hiding , deleting/closing it.
I tried glui->close(), but it doesn't disappear. Also tried to glui->unlink() before closing and still doesn't do the desired behavior.
Is there any way I can close only the GLUI window without closing the whole program nor any GLUT window?
This is a bit of my main function:
glui = GLUI_Master.create_glui( "GLUI", 0, 400, 150 );
glui->add_statictext( "Login" );
glui->add_separator();
edittext = glui->add_edittext( "Username:", GLUI_EDITTEXT_TEXT);
edittext->set_w(200);
edittext1 = glui->add_edittext( "Password:", GLUI_EDITTEXT_TEXT);
edittext1->set_w(200);
glui->add_button( "OK", 303,validateLogIn );
glui->set_main_gfx_window( main_window );
GLUI_Master.set_glutIdleFunc( myGlutIdle );
If you remove GLUI_Master.set_glutIdleFunc( myGlutIdle ); then glui->close() should work.
Related
I'm trying to place a window either above or below the icons on the desktop. I mostly just want it to stay attached to the desktop at all times. Similar to Rainmeter or Wallpaper engine. So far, everything I tried either disables interaction, or gets minimized when you use the "Show Desktop" button. Any ideas on how to achieve this? I'm using electron and a native module in node to do this.
It's an old subject, but I'll find out how to do it recently and answer it.
The method is to find the handle of SHELLDLL_DefView, the parent of the desktop window, and then make the SHELLDLL_DefView handle the parent of my window to fix it to the desktop.
The method is to find the handle of SHELLDLL_DefView, the owner of the desktop window, and then make the SHELLDLL_DefView handle the owner of my window to fix it to the desktop.
SHELLDLL_DefView is located under the Progma or WorkerW handle. This is a code to prevent ShowDesktop from being used in the Electget package created by ffi-napi to attach the Electron browserWindow to the desktop.
const GWLP_HWNDPARENT = -8;
// find SHELLDLL_DefView in Progma
const progman = user32.FindWindowExA(ref.NULL, ref.NULL, 'Progman', ref.NULL);
let defView = user32.FindWindowExA(progman, ref.NULL, 'SHELLDLL_DefView', ref.NULL );
// find SHELLDLL_DefView in WorkerW
if (!defView) {
const desktopHWnd = user32.GetDesktopWindow();
let workerW = 0;
do {
workerW = user32.FindWindowExA(desktopHWnd, workerW, 'WorkerW', ref.NULL);
defView = user32.FindWindowExA(workerW, ref.NULL, 'SHELLDLL_DefView', ref.NULL );
} while (!defView && workerW);
}
if (!defView) return false;
// make the SHELLDLL_DefView handle the parent of my window
user32.SetWindowLongPtrA(hWnd, GWLP_HWNDPARENT, defView);
This allows you to create a window where you can click and interact without being hidden by ShowDesktop.
2022-03-29
There was a wrong word, so I corrected it. According to doc, it is not a parent window, but an owner window. In the doc, it is strange that the GWLP_HWNDPARENT constant is related to the parent window. However, when tested with Spy++, the corresponding constant changes the owner window.
I started with this branch of wxWidgets from GitHub user hokein since it seems to do what I'm looking for with older versions of CEF. Basically, I'm trying to implement wxWebViewChromium (a wxWebView using CEF as a back-end) using cef_3.2526.1354 since this is the version we want to use in our application. I'm running CentOS 7 with GNOME in a VM using Hyper-V.
Original code from the repository linked above (part of webview_chromium.cpp)
#ifdef __WXGTK__
m_widget = gtk_scrolled_window_new( NULL, NULL );
g_object_ref( m_widget );
GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW( m_widget );
// Hide the scroll bar.
gtk_scrolled_window_set_policy( scrolled_window, GTK_POLICY_NEVER, GTK_POLICY_NEVER);
GtkWidget* view_port = gtk_viewport_new( NULL, NULL );
gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(scrolled_window),
view_port );
info.SetAsChild( view_port );
m_parent->DoAddChild( this );
PostCreation( size );
gtk_widget_show( view_port );
#endif
When I tried to compile and link this with cef_3.2526.1354, I was getting errors related to the info.SetAsChild(viewport); line. I was passing it a GtkWidget* and it was expecting cef_window_handle_t, CefRect.
What I've tried so far
I created the CefRect like this based on the GtkWidget* view_port:
GtkAllocation gtk_alloc;
gtk_widget_get_allocation(view_port, >k_alloc);
CefRect cef_rect (
(int)gtk_alloc.x,
(int)gtk_alloc.y,
(int)gtk_alloc.width,
(int)gtk_alloc.height
);
The typedef from the CEF library code indicates that cef_window_handle_t is an unsigned long, but the CEF documentation says it's a GtkWidget*... Which I guess are the same thing, but this led to some initial confusion. At first I thought that I needed to pass the X11 window id (XID) from the underlying X11 window, but this produced a runtime error:
Gdk: gdkdrawable-x11.c:952 drawable is not a pixmap or window
Simply casting the GtkWidget* as an unsigned long instead of using the underlying X11 window ID removed this error, so I think that this is what the function was expecting.
My code currently (part of webview_chromium.cpp)
#ifdef __WXGTK__
m_widget = gtk_scrolled_window_new( NULL, NULL );
g_object_ref( m_widget );
GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW( m_widget );
// Hide the scroll bar.
gtk_scrolled_window_set_policy( scrolled_window, GTK_POLICY_NEVER, GTK_POLICY_NEVER);
GtkWidget* view_port = gtk_viewport_new( NULL, NULL );
gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(scrolled_window),
view_port );
GtkAllocation gtk_alloc;
gtk_widget_get_allocation(view_port, >k_alloc);
CefRect cef_rect (
(int)gtk_alloc.x,
(int)gtk_alloc.y,
(int)gtk_alloc.width,
(int)gtk_alloc.height
);
info.SetAsChild(
(unsigned long) view_port,
cef_rect
);
m_parent->DoAddChild( this );
PostCreation( size );
// gtk_widget_show(view_port);
gtk_widget_show_all(m_widget);
gtk_widget_show_all(view_port);
#endif
What's happening
I am able to compile, link, and run the application. I can see the wxWidgets window, and I can minimize, maximize, resize, and close the window just like any normal window. There is nothing in the window - it is just a plain, grey, empty window. I am expecting (or hoping) to see the CEF browser. In the terminal that I used to launch the application, I get the following message:
[0727/132200:ERROR:browser_main_loop.cc(203)] Running without SUID sandbox! See https://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment for more information on developing with sandbox on.
This URL no longer seems to be of any use. If I launch ./cefclient --no-sandbox from the command line I get the same error message, but the CEF client works as expected. If I launch ./cefclient from the command line (without disabling sandbox), I get this same message except instead of ERROR it says FATAL and the CEF client does not work (crashes outright).
My questions
Have I done anything wrong with my modifications to the webview_chromium.cpp file? Is there anywhere else in this file that I should look for things that I might need to update to get this working with cef_3.2526.1354? How can I troubleshoot this empty window that I'm seeing?
Thanks!
UPDATE
Czarek Tomczak informed me that this version of CEF is expecting an X11 window handle, so I have modified my code as follows.
#ifdef __WXGTK__
m_widget = gtk_scrolled_window_new( NULL, NULL );
g_object_ref( m_widget );
GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW( m_widget );
// Hide the scroll bar.
gtk_scrolled_window_set_policy( scrolled_window, GTK_POLICY_NEVER, GTK_POLICY_NEVER);
GtkWidget* view_port = gtk_viewport_new( NULL, NULL );
gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(scrolled_window),
view_port );
gtk_widget_show_all(m_widget);
gtk_widget_show_all(view_port);
GtkAllocation gtk_alloc;
gtk_widget_get_allocation(view_port, >k_alloc);
CefRect cef_rect (
(int)gtk_alloc.x,
(int)gtk_alloc.y,
(int)gtk_alloc.width,
(int)gtk_alloc.height
);
info.SetAsChild(
gdk_x11_drawable_get_xid(gtk_widget_get_window(view_port)),
cef_rect
);
m_parent->DoAddChild( this );
PostCreation( size );
#endif
But this is still leading to the run-time error below, with the same blank window output as before.
Gdk: gdkdrawable-x11.c:952 drawable is not a pixmap or window
Any help pointing me in the right direction would be much appreciated. I have also tried creating an actual GtkWindow here instead of a scrolled window with a viewport inside it. This gets rid of the above run-time error, but it opens a second window, both of which are blank. I need all of this to work within one window.
UPDATE 2
With some help from Czarek Tomczak, the links he posted, and this FAQ I have gotten to a point where I am able to embed the CEF browser into a GtkWidget, but I am only able to make this work if I create the widget as a top-level GTK window like this:
m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
Where m_widget is the main widget of the wxWebView I'm trying to create. The issue with this is that now the CEF browser is coming up in its own GTK window, but what I really need is for the CEF browser to fit into the wxBoxSizer that I am adding my wxWebViewChromium widget to. To get this working to this point I split out some of the code from the Create method into the OnSize method so that I could get the XID of the GtkWidget after the GtkWidget was realized, and create the CEF browser after this happened. The OnSize method is connected to wxEVT_SIZE. My code is now as follows.
Updated portion of Create Method
// Actual creation of CEF browser moved to OnSize function so we
// can guarantee the widgets have been realized
this->Bind(wxEVT_SIZE, &wxWebViewChromium::OnSize, this);
// Works but as a top-level GTK window only
m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
// None of these work
//m_widget = gtk_drawing_area_new();
//m_widget = gtk_vbox_new(false, 0);
g_object_ref( m_widget );
Updated portion of OnSize Method
if (!cef_browser_created)
{
cef_browser_created = true;
CefBrowserSettings browsersettings;
CefWindowInfo info;
XSetErrorHandler(XErrorHandlerImpl);
XSetIOErrorHandler(XIOErrorHandlerImpl);
gtk_widget_realize(m_widget);
::Window xwindow = GTK_WINDOW_XID(gtk_widget_get_window(m_widget));
DCHECK(xwindow);
GtkAllocation gtk_alloc;
gtk_widget_get_allocation(m_widget, >k_alloc);
CefRect cef_rect (
(int)gtk_alloc.x,
(int)gtk_alloc.y,
(int)gtk_alloc.width,
(int)gtk_alloc.height
);
info.SetAsChild(xwindow, cef_rect);
m_parent->DoAddChild( this );
PostCreation( size );
CefBrowserHost::CreateBrowserSync(
info,
static_cast<CefRefPtr<CefClient> >(m_clientHandler),
create_url.ToStdString(),
browsersettings,
NULL
);
}
When I try to make m_widget something other than a top-level GTK widget (as shown in the commented-out portions of the code for the Create method above), I get the following error at run-time.
Gtk: IA__gtk_widget_realize: assertion 'GTK_WIDGET_ANCHORED (widget) || GTK_IS_INVISIBLE (widget)' failed
Gdk: gdkdrawable-x11.c:952 drawable is not a pixmap or window
Check failed: xwindow.
How can I make this window appear inside my wxBoxSizer instead of as its own GTK top-level window?
CEF expects X11 window handle. GtkWidget handle was required in previous versions of CEF. The documentation on that wiki page seems to be outdated. Make sure the X11 handle is valid (show the window) before passing it to CEF.
I can only suggest to take a look at how GTK window is created in cefclient sample application:
https://bitbucket.org/chromiumembedded/cef/src/98f59f47fd395c170f389eba36f2ef2e06a500a8/tests/cefclient/browser/root_window_gtk.cc?at=master&fileviewer=file-view-default#root_window_gtk.cc-233
Also take a look at CreateBrowser() - it uses GetXWindowForWidget():
https://bitbucket.org/chromiumembedded/cef/src/98f59f47fd395c170f389eba36f2ef2e06a500a8/tests/cefclient/browser/browser_window_std_gtk.cc?at=master&fileviewer=file-view-default#browser_window_std_gtk.cc-91
So, (I rewrote this since a lot of people didn't understand me. I apologize.)
I'd like to bring the window of my qt application to the very front of ALL windows on screen.
I've heard you can do this by attaching to the thread of the foreground window and then "stealing focus" aka putting yourself where that foreground window was.
(I'm using OSX, so windows.h is no option for me.)
I hope you understand now.
To bring a window to the front, ensure the window is visible, then activate the window.
As the docs state: -
Sets the top-level widget containing this widget to be the active window.
And
If you want to ensure that the window is stacked on top as well you should also call raise().
So, assuming you have a window called pWindow, you can do something like this: -
pWindow->raise();
pWindow->show();
pWindow->activateWindow();
Also note that OS X can have multiple desktops (Spaces). If you also want the window to track the user's Space when they switch between them, you can add this function to your window class: -
void MyWindow::DisplayOnAllSpaces()
{
// ensure we stay on the active desktop
WId windowObject = this->winId();
objc_object* nsviewObject = reinterpret_cast<objc_object *>(windowObject);
objc_object* nsWindowObject = objc_msgSend(nsviewObject, sel_registerName("window"));
int NSWindowCollectionBehaviorCanJoinAllSpaces = 1 << 0;
objc_msgSend(nsWindowObject, sel_registerName("setCollectionBehavior:"), NSWindowCollectionBehaviorCanJoinAllSpaces);
}
I have a Application mostly written with the owl-libary.
There I want open new vcl-windows out of the main owl-window.
This works great, though if a dialog-window is opened (even with ShowModal) and I focus another application, then the main-window get's into foreground but is blocked by the window behind it.
I guess the Problem is the missing parent-setting.
However, I can't convert owl's TWindow to vcl's TWinControl.
Is there a trick to set a vcl's parent setting to a owl's TWindow-Object?
Or could this be caused by something entirely different?
EDIT:
I'm using...
void(TWindow* parent){
Form=new TForm((HWND)parent->Handle);
Form->ParentWindow=parent->Handle;
Form->BorderIcons >> biMinimize >> biMaximize << biSystemMenu; //No minimize, no maximize, but close
Form->BorderStyle = bsSingle;
Form->Position = poMainFormCenter;
...
Form->ShowModal();
...now.
However, the new window is locked up and can not be clicked/closed/switched to.
Is there something I missed in using ParentWindow?
EDIT2:
I think it might be a Problem that the parent is a TDecoratedMDIFrame, which is a MDI-Container, so my dialog is treated like a mdi-child instead of a normal dialog...
TWinControl has a ParentWindow property for specifying a non-VCL parent window.
Also, in modern VCL versions, you can specify a ParentWnd when displaying a VCL dialog.
Using CWnd::ShowWindow(SW_SHOWMAXIMIZED) maximizes my app window as expected.
However, when clicking the restore button on the app (or double clicking the title-bar), the restored size is the same size as the maximized window, which is confusing for the user.
Using this alternative code has the same problem:
WINDOWPLACEMENT wndpl;
GetWindowPlacement(&wndpl);
wndpl.showCmd = SW_SHOWMAXIMIZED;
SetWindowPlacement(&wndpl);
How can I keep the default un-maximized size when restoring.
I've solved my problem, and the solution might solve yours too. My problem was that even though I called SetWindowPlacement(&wndpl) within CMainFrame::OnCreate the window was not properly restored if it was maximized. I added two lines of code before SetWindowPlacement, and now it works as expected.
CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
...
// Obtain wndpl, maybe from registry
AfxGetApp()->m_nCmdShow = wndpl.showCmd;
wndpl.showCmd = SW_SHOW;
SetWindowPlacement(&wndpl);
}
These two lines helps underlying code not to mess things up when calling ActivateFrame, which calls ShowWindow with parameter obtained from CWinApp::m_nCmdShow.
All information are in the file with extension .RC. I never used a Maximize/Restore procedures though you should look for a 'DIALOGEX' for the same window. You can change it using any editor (notepad, ultraedit etc.)