Get window handle from QT on Mac - c++

I am looking for an equivalent of this solution from SDL to get the window handle from QT(5.12) on OSX (Mojave)
SDL_SysWMinfo wmInfo = {};
SDL_GetWindowWMInfo(window, &wmInfo);
mInfo.info.cocoa.window;
I tried a solution which I found on stack
NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(500, 500, 500, 500)
styleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask
backing:NSBackingStoreBuffered
defer:NO];
But it fails with the error message
expected variable name or this in lambda capture list
I tried it via the QWidget
QWidget window;
window.resize(320, 240);
window.show();
window.winId()
window.windowHandle()
I tried to use the QMacNativeWidget but it failed, too.
I tried to fool around with this imports
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#import <AppKit/NSWindow.h>
But NSWindow.h throws a lot of error messages. It complains for example about missing braces.
So I can't find any documentation which helps me and I am working after the try and error principle which is not the most productive one^^
Maybe one of you had already the same issue and could provide some help or reference

Related

MFC MDI Problem with SetLook even with header file in place

I've implemented a Property Sheet and several Property Pages that are called from the Main Menu from the MainFrame.cpp spawned from my issue here:
MFC MDI Designing user preferences dialog GUI layout functionality
The code I landed on was:
BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWndEx)
Other messages...
ON_COMMAND(ID_SETTINGS_DIALOG, OnSettingsTools)
Other messages...
END_MESSAGE_MAP()
void CMainFrame::OnSettingsTools()
{
SettingsSheet SettingsSheet(L"Application Settings");
CSettingsPowerUser m_PowerUser;
CSettingsReset m_Reset;
CSettingsToolbars m_Toolbars;
CSettingsUserWarnings m_UserWarnings;
SettingsSheet.AddPage(&m_PowerUser);
SettingsSheet.AddPage(&m_Reset);
SettingsSheet.AddPage(&m_Toolbars);
SettingsSheet.AddPage(&m_UserWarnings);
//SetLook(CMFCPropertySheet::PropSheetLook_OneNoteTabs);
SettingsSheet.DoModal();
}
Yielding:
I have included in MainFrame.h
#include <afxpropertysheet.h>
The property sheet is using CMFCPropertySheet in both the .cpp & .h as shown here in its .h file:
class SettingsSheet : public CMFCPropertySheet
{
DECLARE_DYNAMIC(SettingsSheet)
public:
SettingsSheet(UINT nIDCaption, CWnd* pParentWnd = nullptr, UINT iSelectPage = 0);
SettingsSheet(LPCTSTR pszCaption, CWnd* pParentWnd = nullptr, UINT iSelectPage = 0);
virtual ~SettingsSheet();
protected:
DECLARE_MESSAGE_MAP()
};
So what the issue here is, you can see that I had to comment out the SetLook(CMFCPropertySheet::PropSheetLook_OneNoteTabs); because I get an error that says SetLook identifier not found C3861.
If I hover inside the MainForm.h and right click the #include <afxpropertysheet.h> the file opens right up in the IDE and if I search for SetLook it most certainly can find it in the public section of the function.
So I've seen multiple code examples that use that SetLook and one of the tutorials I looked at used it and it works fine as I'm using VS2017.
I realize what a "not found is", but I'm at a loss as to why it's a problem here. It is the only error I am having now and I would like to use that functionality.
Thoughts on what may be going on here?
Update:
Following Dxiv's advice I changed the code to:
SettingsSheet.SetLook(CMFCPropertySheet::PropSheetLook_OneNoteTabs);
It now compiles and runs, but have some odd results, it only shows one property page, and all the rest are AWOL.
I have figured out what the issue was; when I created the dialogs I used the base class of:
CPropertyPage
instead of:
CMFCPropertyPage
I had set the sheet to:
CMFCPropertySheet
and assumed it carried down since it compiled and displayed the tab view correctly, but failed on the other SetLook property options.
Once I adjusted all the dialogs to CMFCPropertyPage, the SetLook started working immediately. So I consider this issue CLOSED.

Is open OpenGL completely broken after iOS 12.4?

I have an open source MS-DOS emulator for iOS here:
https://github.com/MattAndrzejczuk/MSDOS-for-iOS
This app runs well when using my older iOS devices such as the old iPhone 5S. but right after iOS 13.0 was released, the app delegate has trouble rendering SDL due to NOT calling UIKit methods on the main thread, but I'm not quite sure if this crash is due to OpenGL being completely deprecated, or, if maybe the newer SceneDelegate and AppDelegate changes which seemed to have been overhauled in iOS 13 are the cause of this issue. Just for some context, I've noticed that I cannot create a new Xcode project with a basic hello world label and build it directly for iOS 12 devices without doing this:
#import <UIKit/UIKit.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate>
// ADD THIS TO DEFAULT APPDELEGATE.H:
#property (strong, nonatomic) UIWindow *window;
#end
This solution below, only somewhat fixed the problem:
Sources/dospad/Shared/DosEmuThread.m
#import "DosEmuThread.h"
extern int SDL_main(int argc, char *argv[]);
#implementation DosEmuThread
#synthesize started;
- (void)start
{
if (started) {
NSLog(#"DosEmuThread %p already started", self);
return;
}
NSLog(#"Start dosbox in new thread");
started = YES;
[NSThread detachNewThreadSelector:#selector(run) toTarget:self withObject:nil];
}
- (void) run {
#autoreleasepool {
/// UNCOMMENTING THIS SOMEWHAT FIXES THE ISSUE:
//dispatch_async(dispatch_get_main_queue(), ^{
char *argv[1] = {"dosbox"};
SDL_main(1, argv);
self.started = NO;
//});
}
}
#end
This fixes the app, in that I can reach the DOS prompt, but once I try to open something like this:
C:\ cd WAR2A
C:\ WAR2.EXE
I just get stuck at a blank screen, so obviously the quick fix of putting the dos thread on the main thread will break once SDL tries to run a full screen EXE app.
I'd really like to have the ability to emulate an x86 machine to run classic DOS games and even support Windows 95 for iOS, if there are alternative git repos out there that can do something similar, please let me know.

How to Change QMessageBox Icon and Title

I am creating a ui app with Qt c++.
I have a error message that I have created by using QMessageBox Class like :
QMessageBox errorMessage;
errorMessage.critical(0, "Error", "An error has occured !");
errorMessage.setFixedSize(500, 200);
It is like:
And I want to change the red circled things which are the icon and the title.
I would appreciate any help.
Thanks in advance.
However you can use of QMessageBox::critical(0, "Error", "An error has occured !"); because critical(...) method is static and theres no need for create an instance of QMessageBox.
Use bellow code :
QMessageBox mb("Application Name",
"Hardware failure.\n\nDisk error detected\nDo you want to stop?",
QMessageBox::NoIcon,
QMessageBox::Yes | QMessageBox::Default,
QMessageBox::NoButton,
QMessageBox::NoButton);
QPixmap exportSuccess("/media/msi/Information/Pictures/Icons/Icons Pack/PNG/48X48/about.png");
mb.setIconPixmap(exportSuccess);
mb.exec();
This example work 100%
If you want to set the icon for every window you can do so globally with this:
QApplication::setWindowIcon(QIcon(":/GuiMain/gh_resource/GH Icon.ico"));
You also aren't required to use pixmap in my experience, you can use:
mb.setWindowIcon(QIcon(":/path/to/icon.ico"));
This will work on individual message boxes, just add your custom icon to your .qrc file
Simply you can set Icon for your Application it will automatically set on your MessegeBox

Using CEF3 with wxWidgets (and GTK) on Linux

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, &gtk_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, &gtk_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, &gtk_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, &gtk_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

Notification window in Mac. With or without Qt

Qt project on Mac OS X. I need to show notification window on top without stealing a focus from any active application.
Here the widget constructor part:
setWindowFlags(
Qt::FramelessWindowHint |
Qt::WindowSystemMenuHint |
Qt::Tool |
Qt::WindowStaysOnTopHint
);
setAttribute(Qt::WA_TranslucentBackground);
Qt::WA_ShowWithoutActivating doesn't affect anything.
Is there a way to do that? I'm ready to implement the native Carbon/Cocoa solution there, but Qt is preferred.
Or maybe I'm wrong in Mac philosophy and I should notify user in a kind another manner?
Update Growl doesn't support editor line in its notifications, does it?
I did it!
#ifdef Q_OS_MAC
#include <Carbon/Carbon.h>
#endif
NotifyWindow::NotifyWindow() : QWidget(0 /* This zero is the first point */) {
setWindowFlags(
#ifdef Q_OS_MAC
Qt::SubWindow | // This type flag is the second point
#else
Qt::Tool |
#endif
Qt::FramelessWindowHint |
Qt::WindowSystemMenuHint |
Qt::WindowStaysOnTopHint
);
setAttribute(Qt::WA_TranslucentBackground);
// And this conditional block is the third point
#ifdef Q_OS_MAC
winId(); // This call creates the OS window ID itself.
// qt_mac_window_for() doesn't
int setAttr[] = {
kHIWindowBitDoesNotHide, // Shows window even when app is hidden
kHIWindowBitDoesNotCycle, // Not sure if required, but not bad
kHIWindowBitNoShadow, // Keep this if you have your own design
// with cross-platform drawn shadows
0 };
int clearAttr[] = { 0 };
HIWindowChangeAttributes(qt_mac_window_for(this), setAttr, clearAttr);
#endif
}
We get almost the same nice behavior as in Windows:
It does not stole focus on show. (Two weeks of searching over the Internet)
The controls there handle the first user click, while other windows need an extra click to activate.
When the window is being activated, the other windows of the same application, do not bubble up to the front.
And a small problem remains, but at least it has a simple workaround. Or even could be left.
Pavel,
Have you heard of Growl? Growl is a VERY impressive notification app that you can bundle and use with your application. Adium - a popular instant messaging app for OS X - uses it for all notifications.
http://growl.info/
You could implement Growl. http://growl.info/documentation/developer/
try this on mac:
setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
setAttribute(Qt::WA_TranslucentBackground);
setAttribute(Qt::WA_AlwaysStackOnTop);
Ive just tested these flags
Qt::FramelessWindowHint |Qt::WindowSystemMenuHint |Qt::WindowStaysOnTopHint
And
setFocusPolicy(Qt::NoFocus);
setAttribute(Qt::WA_ShowWithoutActivating,true);
Without Cocoa or Carbon code for window flags/masks.
And notifyWindow works like on Windows or Linux.