X Client requests fail for GTK based window - linux

I have created a simple gstreamer+gtk based application to play video file. "filesrc", "decodebin", "autovideosink", "autoaudiosink" gstreamer elements are used for that.
Main window is created using gtk_window_new(GTK_WINDOW_TOPLEVEL) and drawing area is created using gtk_drawing_area_new(). Drawing window is embedded in main window.
To render on gtk drawing window, its handle is passed to gstreamer video plugin as overlay using gstreamer api gst_video_overlay_set_window_handle()
By doing so video is not rendered only audio gets played.
Instead of GTK window if i pass XCreateWindow() handle to gstreamer video plugin as overlay then everything works fine. But i have to create GTK based player.
Now, when i start debugging the issue i have found below details.
"autovideosink" plugin gets blocked on XNextEvent inside mainloop thread(Luckily i have source code and verified using logs)
Then using xtrace utility it was found that most of X Request gets failed(See below) whereas in case of XCreateWindow all such Request gets successful Response.
002:<:000f: 52: Request(1): CreateWindow depth=0x18 window=0x01600001 parent=0x01400007 x=0 y=0 width=640 height=368 border-width=0 class=InputOutput(0x0001) visual=0x00000021 value-list={background-pixel=0x00000000 border-pixel=0x00000000 backing-store=NotUseful(0x00) override-redirect=false(0x00) colormap=CopyFromParent(0x00000000)}
002:<:0010: 24: Request(16): InternAtom only-if-exists=true(0x01) name='_NET_WM_STATE'
002:>:000f:Error 8=Match: major=1, minor=0, bad=20971527
002:<:001d: 8: Request(3): GetWindowAttributes window=0x01600001
002:<:001e: 8: Request(14): GetGeometry drawable=0x01600001
002:>:001d:Error 3=Window: major=3, minor=0, bad=23068673
002:>:001e:Error 9=Drawable: major=14, minor=0, bad=23068673
I have no idea why these requests gets failed for GTK window. Whereas in my old system(ubuntu 14.04) i can run the same player very well. Current system is ubuntu 16.04
Any X Server related configuration setting doing that?
Please suggest some solution or any idea how to debug it further to catch the real cause.

Prototype:
XCreateWindow(display, parent, x, y, width, height, border_width, depth, class, visual, valuemask, attributes)
autovideosink mentioned in question is actually imxeglvivsink. imxeglvivsink creates child window with gtk-window as parent(Check second parameter of XCreateWindow api).
Now GDK default Visual used for Parent Windodw(GTK) were different from X default Visual and this is the reason X CreateWindow Request gets failed.
I solved this problem with 2 solutions.
Solution 1:
In imxeglvivsink, while creating child window i used 'CopyFromParent' flag for 'visual' parameter of XCreateWindow api. By doing so, Visual for Parent and Child matches and X request CreateWindow gets successful.
I didn't like this solution as i have to replace original imxeglvivsink library with my new library.
Solution 2:
My ultimate goal is still same. I have to keep same visual for parent and child window. In this solution i changed Visual of Parent window(GTK) to X Default Visual. I did this change at application level and i don't have any dependency of imxeglvivsink. Code snippet to change GDK visual is below:
static int change_visual(GtkWidget *widget)
{
int nitems_return;
Display *x_display = XOpenDisplay(NULL);
Visual *x_visual = XDefaultVisual(x_display, DefaultScreen(x_display));
GdkScreen *gdk_screen = gdk_screen_get_default();
GList *gdk_visual_list = gdk_screen_list_visuals(gdk_screen);
GList *l;
for (l = gdk_visual_list; l != NULL; l = l->next)
{
Visual *temp = gdk_x11_visual_get_xvisual((GdkVisual *)l->data);
if(temp->visualid == x_visual->visualid) break;
}
//l is pointing the visual which is similar to system x visual. Lets change it.
gtk_widget_set_visual (widget, (GdkVisual *)l->data);
return 0;
}
I know i don't take care if visualid don't match inside the for loop. For me i always find GDK visual same to X Default Visual.

Related

Main Camera Referenced script is missing

I know, there is always a lot of questions about this error BUT I didn't succeed to fix it with the previous answers...
So, please, let me explain.
I'm working with the Hololens tech. Recently, I have updated from HoloToolKit to MRTK V2 (new SDK provided by Microsoft and the community). My app worked with HoloToolKit, Unity and 2017.4. I updated for MRTKv2 and 2019.2 (recommended).
I have some scripts that use the camera position. In my previous app, Camera was BiCamera (GameObject), child of Basic (GameObject). And my BiCamera was tagged as MainCamera. Right now, my camera was Main Camera (with a space between the 2 words), tagged MainCamera, child of MixedRealityPlayspace. This camera is provided by the MRTKv2. I can't change the settings.
So, when I'm in a Play mode I have this message in yellow :
The referenced script on this Behaviour (Game Object 'Main Camera') is missing!
And when I move my Main Camera in order to simulate a walk of the user (Hololens = augmented reality), I have this message in red :
NullReferenceException: Object reference not set to an instance of an object
TextSpeedUI.Update () (at Assets/Scripts/TextSpeedUI.cs:23)
I think the second message is linked to the first... My script TextSpeedUI needs the camera.transform to calculate walking speed (in fact not directly, he finds the public variable from another GameObject, but this GameObject requires Camera.transform).
An other option is linked with the GameObject Main Camera provided by MRTK because when I select this GameObject I have a missing script. A message says that I have to fix compile errors... But perhaps it's a consequence not the origin... I'm lost.
TextSpeedUI.cs 23
if (sd.isActiveAndEnabled && sd.Steps.Count > 4)
{
xzSpeed = (sd.Steps[sd.Steps.Count - 1].localMinPosition - sd.Steps[sd.Steps.Count - 4].localMinPosition) / ((sd.Steps[sd.Steps.Count - 1].t - sd.Steps[sd.Steps.Count - 4].t));
txt.text = (xzSpeed.magnitude * 3.6).ToString("0.##"); // speed in km/h
}
sd comes from public StepDetector sd; which is at the beginning of my script TextSpeedUI.cs
And my script StepDetector.cs calls public DataManager dm;
In my DataManager.cs script, I call at the beginning :
public Camera Cam { get; private set; }
And in void Start :
Cam = Camera.main;
Thanks a lot
I've solved by myself (just remove the component). It seems that it doesn't have consequence on my scene...

Application bar color for MDI in VC++ (MFC)

How to define a system theme to be applied that matches the new style and apply it. Please find the attached image for the actual and expected style.
MDI Frame window color:
The following approaches i have tried so far, it was not yielded expected result.
1: Setting Application caption using Windows API The following code sets the color for application title bar for the session. But with theme settings and such on Windows 8.1 and 10, it does not come into effect.
int aElement = COLOR_ACTIVECAPTION;
DWORD aOldColor;
DWORD aNewColor;
aOldColor = GetSysColor(aElement);
aNewColor = RGB(0x04, 0x04, 0x04);
SetSysColors(1, &aElement, &aNewColor);
2: Using theme/DWM API
With a Windows theme in effect, changing the application title bar alone does not become successful. Have tried:
2-a: Getting theme handle, defining a captionbar and using the captionbar in a call to CMFCVisualManager::GetInstance()->OnDrawCaptionBarBorder()
2-b: DwmSetWindowAttribute() was used for setting rendering policy disabled.
3: Using CMFCVisualManager
Defining a CMFCCaptionBar and assigning it to CMFCVisualManager. This too does not get the effect needed.

Does QNativeGesture works on Linux / Windows, given that the hardware supports it?

I want to add swipe gestures in my application based on Qt5. The application is intended to run primarily on Linux (laptop). I was just not able to write code because I couldn't understand how to use the class (no example code was available).
The touchpad driver supports swipe gestures (libinput). Also, synaptics (on my system at least) support multi-finger touch.
Can someone please guide me about how to use the API, and provide with some example code?
Do you mean QNativeGestureEvent? You probably shouldn't mess with QNativeGestureEvent and use the higher-level framework: see Gestures in Widgets and Graphics View. The QNativeGestureEvent used to be only available on OS X; it's not really an API that's meant for wide consumption.
Alas, the QNativeGestureEvents are delivered to the widgets themselves. You would react to them by reimplementing QObject::event and acting on the event:
class MyWidget : public QWidget {
typedef base_type = QWidget;
...
bool QWidget::event(QEvent * ev) override {
if (ev->type() == QEvent::NativeGesture) {
auto g = static_Cast<QNativeGestureEvent*>(ev);
...
return true; // if event was recognized and processed
}
return base_type::event(ev);
}
};
But don't do that.

How to make an assert window in QT

I currently have a very long running GUI-Application in QT. Later that application is going to be tested and run on an embedded device without a keyboard in full screen.
For easier debugging I have a custom assert macro, which allows me to ignore certain asserts (may include known buggy parts I have to work around for now) etc. For the time being I just print something on the console such as "Assertion: XXXX failed; abort/ignore". This is fine when I start the application within a console, but ultimately fails when I run it on the final device. In that case the assert will just block the main thread waiting for input and make the GUI hang badly without hope for recovery.
Now I am thinking about how to remedy this situation. One Idea is to just have the assert crash, as the standard assert does. But I do not really like that Idea, since there are a lot of know problems, and I've always found ignorable asserts very helpful when testing applications. Also I would have to put the messages into a separate file, so I can later see what happened while testing. Reading these files afterwards is possible, but I would prefer a simpler way to find out what went wrong.
The other idea was to make a window instead. However the asserts may be triggered in any thread and I can only create new windows in the GUI thread. Also the main event loop may be blocked by the assert, so I cannot be sure that it will handle the events correctly. I would somehow need a fully responsive stand-alone window in a separate thread, which only handles a few buttons.
Is this somehow possible in QT4?
You may post events to main thread to display dialog and wait for an answer from non-gui threads, or just display dialog if current thread is app thread
int result = -1;
if ( QTrhead::currentThread() == QCoreApplication::instance()->thread() )
{
result = AssertHandler->ShowDialog(where, what, condition);
}
else
{
QMetaObject::invokeMethod(AssertHandler, "ShowDialog", Qt::QueuedBlockingConnection, Q_RETURN_ARG(int, result), Q_ARG(QString, where), Q_ARG(QString, what), Q_ARG(QString, condition);
}
if (result != 0)
{
// handle assert
}
The AssertHandler is QObject based class with slot int ShowDialog(const QString &where, const QString what, const QString &condition). It should display dialog with assert data and buttons assert/ignore. Returns 0 when user pressed ignore, otherwise returns non zero value.

How to change the border style of applications main window in visual c++ win32 API

I have an application in Visual c++ (Win32 API). In my application the main window boarder is displayed in old windows styled. I have tried changing the wndWc.style values to WS_OVERLAPPED,WS_POPUP and other which are given in WinUser.h but there is no change in the appearance of the main window were as all my pop-up window are displayed in windows 7 style how this can be rectified. Any help in this regards will be highly appreciated. I have attached both the images the main window and the pop up window.
Code :
// our window class
WNDCLASS wndWc;
// ---------------------------------------------------------
// fill window class members
// ---------------------------------------------------------
wndWc.style = CS_GLOBALCLASS;
wndWc.lpfnWndProc = (WNDPROC) WndProc;
wndWc.cbClsExtra = 0;
wndWc.cbWndExtra = 0;
wndWc.hInstance = GetModuleHandle(NULL);
wndWc.hIcon = NULL;
wndWc.hCursor = LoadCursor(0, IDC_ARROW);
wndWc.hbrBackground = (HBRUSH)GetStockObject(0);
wndWc.lpszMenuName = NULL;
wndWc.lpszClassName = "XYZ";
// register class
if (!RegisterClass(&wndWc)) return false;
// ---------------------------------------------------------
// get actual screen resolution
int iSw = (WORD)GetSystemMetrics(SM_CXSCREEN); // height
int iSh = (WORD)GetSystemMetrics(SM_CYSCREEN); // height
// make a rectangle on the center of the screen
RECT rc = {(iSw - iWidth)/2, (iSh - iHeight)/2, width, height};
// create the window. the spaces on the window title
// are just to make sure this will be visible when the region
// is active. just run the app and you'll understand. =)
hWnd = CreateWindow("XYZ", "XYZ",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT, width,height,
NULL, NULL, GetModuleHandle(NULL), NULL);
It could be that your EXE has been flagged to run in compatibility mode for a previous OS version. Right-click the EXE, choose Properties, then ensure everything is switched off on the Compatibility tab. (Especially "Disable visual themes" and "run this program in compatibility mode for...")
Failing that...
It's unusual to need to do anything at all, but try this at the start of the app:
SetThemeAppProperties(STAP_ALLOW_NONCLIENT|STAP_ALLOW_CONTROLS)
If that doesn't work, try explicitly setting the theme for your window:
SetWindowTheme(hWnd, "WINDOW", NULL);
FWIW, I pasted your code in to a new Visual Studio 2008 project created using the "Win32 project" wizard, and it came out with a Windows 7 border. You usually have to go out of your way not to get the border, in fact.
There could be something unusual about the EXE you are building, like a flag in the EXE's header being set incorrectly. e.g. If it isn't specifying that it is a Windows GUI app, or maybe there are some version fields...
The EXE's manifest may also play a part, but I just tried deleting the manifest completely and my program still got a themed window, so it's probably not that.
If you look closely, you'll see that it's not just the border. The close button also uses the old visual style. Therefore, it's not sufficient that you change the window style. You must indicate that your app is Vista- and Aero-aware

Resources