How to start building a GUI toolkit for wayland - linux

I want to create a GUI toolkit for my desktop environment (because neither gtk nor qt don't fit to my needs) but I don't know how to start. I don't want a cross-platform or display-server independent library, theming options, configurable icons etc. just a few basic widgets for making wayland clients. (widgets like button, entry, label, window and images... and I want to use CSD if it's important)
My problem is that I can't understand how graphics work in wayland (in X you only need to create a window and use XDrawLine etc. right?) also I don't know how to write a graphical toolkit. Can you give me some articles or recommendations on how can I do this?

The easiest way to create a wayland client is to use the wayland-client library. Basically, it abstracts the wire format.
example:
#include <stdio.h>
#include <wayland-client.h>
int main(void)
{
struct wl_display *display = wl_display_connect(NULL);
if (display) {
printf("Connected!\n");
} else {
printf("Error connecting ;(\n");
return 1;
}
wl_display_disconnect(display);
return 0;
}

Related

Flutter PDF Viewer for Linux desktop

I developing some kind of chat application with PDF viewing functions on Flutter for Android and Linux desktop platforms.
So i want to embed PDF viewer in flutter application using some kind of PDF reader or WebBrowser. There is no problems with PDF's on Android - more than 100 plugins on pub.dev for PDF's and WebViews, but none of them supported Linux desktop.
I have tried to add Linux desktop support for Android and IOS plugins, but look's like all of them using PlatformView and webview_flutter classes, which not supported on Linux desktop yet: webview_flutter PlatformView. They have P4 priority and no milestone assigned. I can't wait undefinitely long time, i should end this project in 2 months. So what should i do?
I have read that Flutter uses GTK+ to display on Linux desktop, and i know that there is GTK+ components to display PDF. So is it possible to inject somehow this component in flutter ui? Is there any example?
Or maybe better will be to convert PDF in jpeg and show images instead? (But i don't want lost zoom and document navigation)
Opening PDF into external program with File.Open() is not solution for me, because in this case user's should constantly switch between flutter app (where we have list of PDF files) and PDF reader windows.
I am new to both Flutter and Linux, so any help would be appreciated.
So is it possible to inject somehow this component in flutter ui?
That is exactly what PlatformView is, so that's equivalent to the question of whether PlatformView is supported on Linux.
Two options that could work without PlatformView support:
Swap the window between displaying the Flutter view and a PDF view (if you want the PDF to fill the window while displayed).
Place the Flutter view and the PDF view side by side in the window (if you want both Flutter content—like your list of files—and PDF content visible at the same time).
Both would require the work to be done in the native code, so you would need to either write a plugin, or implement it directly in your runner, and use a method channel to coordinate between Dart and native code.
So just to clarify how we can achive this using webkit, as example:
CMakeLists.txt:
#add webkit package reference
pkg_check_modules(WEBKIT2 REQUIRED IMPORTED_TARGET webkit2gtk-4.0)
...
#remove -Werror flag to allow compilation with warnings
target_compile_options(${TARGET} PRIVATE -Wall)
...
#link webkit libraries
target_link_libraries(${BINARY_NAME} PUBLIC PkgConfig::WEBKIT2)
#somehow this line causes 'flutter run' to crash on "Linking CXX executable" step.
#Looks like it compiles, but fails to link.
#I think there is should be other question opened for this issue.
my_application.cc:
#include "my_application.h"
#include <flutter_linux/flutter_linux.h>
#include <webkit2/webkit2.h>
#include "flutter/generated_plugin_registrant.h"
static void my_application_activate(GApplication* application) {
GtkWidget *vbox1 = gtk_vbox_new (FALSE, 0);
gtk_widget_show (vbox1);
// we can insert any gtk controls in this window outside of FlView
GtkWidget *label = gtk_label_new ("Hello GNOME!");
gtk_box_pack_start (GTK_BOX (vbox1), label, TRUE, TRUE, 2);
gtk_widget_show (label);
// webkit/poppler/evince should work perfect because they gtk+
WebKitWebView *pWebKitView = WEBKIT_WEB_VIEW(webkit_web_view_new());
gtk_box_pack_start (GTK_BOX (vbox1), GTK_WIDGET(pWebKitView), TRUE, TRUE, 2);
gtk_widget_show(GTK_WIDGET(pWebKitView));
// finally add FlView
g_autoptr(FlDartProject) project = fl_dart_project_new();
FlView *view = fl_view_new(project);
gtk_box_pack_start (GTK_BOX (vbox1), GTK_WIDGET(view), TRUE, TRUE, 2);
gtk_widget_show (GTK_WIDGET (view));
GtkWindow* window =
GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
gtk_container_add (GTK_CONTAINER (window), vbox1);
fl_register_plugins(FL_PLUGIN_REGISTRY(view));
gtk_widget_grab_focus(GTK_WIDGET(view));
GtkHeaderBar *header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
gtk_widget_show(GTK_WIDGET(header_bar));
gtk_header_bar_set_title(header_bar, "client");
gtk_header_bar_set_show_close_button(header_bar, TRUE);
gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
gtk_window_set_default_size(window, 1280, 720);
gtk_widget_show(GTK_WIDGET(window));
}

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 change the background of the child window from an MDI Visual C++ 2008 application

I have an MDI Visual C++ 2008 application based on MFC. I am trying to find a way to use an image as background for the child window (child frame). I have been looking on various sites but I can't seem to find a solution. Does anyone know how to implement this?
It is always the same way when you want to change the background of a window.
Handle the WM_ERASEBKGND (OnEraseBkGnd). Draw the bitmap on the given DC and return TRUE
Either use StretchBlt or use it as a brush.
BOOL CMyClientWnd::OnEraseBkgnd(CDC* pDC)
{
CBrush* pbrushOld = pDC->SelectObject(&m_brush);
CRect rect;
pDC->GetClipBox(&rect);
pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY);
pDC->SelectObject(pbrushOld);
return TRUE;
}

How do Right-Click and Menu-Bar menus work?

I've created simple application that monitors X11's _NET_CLIENT_LIST. It prints me info when window ( including conky,tint2,... ) opens or closes. It works fine, except when i create menu (RMB-click or front Menu-Bar) it won't print anything - that means they aren't new windows, but they can be drawn out of window they are created from, so what is it?
I'd like create my own context menu in my app and i don't want to use any toolkit ( GTK, QT,... ). So i need to know how do they work.
Adding another answer because the old one is for a different question entirely :)
Pop-up menus (whether RMB-activated or from a menu-bar) are perfectly normal X11 windows. The reason that you don't see them in your monitoring program is that you are monitoring changes caused by the window manager. Pop-up menus normally bypass the WM entirely, so WM doesn't know about them.
This is achieved by setting the override_redirect window attribute XSetWindowAttributes structure. Set it for your pop-up menus (and only for pop-up menus) and you should be all set.
Menus are not managed by a WM and don't have any WM-specific properties.
To watch windows, catch XMapNotify and XUnmapNotify events on the root window, using SubstructureNotifyMask. Here's a very simple program that does something:
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
int main () {
Display* d = XOpenDisplay(0);
if (!d) {
printf ("Oops...!\n");
exit (EXIT_FAILURE);
}
XSelectInput(d, DefaultRootWindow(d), SubstructureNotifyMask);
for(;;) {
XEvent e;
XNextEvent(d, &e);
if (e.type == MapNotify) {
printf ("Window %lx mapped!\n", e.xmap.window);
}
if (e.type == UnmapNotify) {
printf ("Window %lx unmapped!\n", e.xunmap.window);
}
}
}
It reports spurious Unmap events which can be simply ignored.
A more complete program should probably watch all events selected by SubstructureNotifyMask and SubstructureRedirectMask.

j2me screen flicker when switching between canvases

I'm writing a mobile phone game using j2me. In this game, I am using multiple Canvas objects.
For example, the game menu is a Canvas object, and the actual game is a Canvas object too.
I've noticed that, on some devices, when I switch from one Canvas to another, e.g from the main menu to the game, the screen momentarily "flickers". I'm using my own double buffered Canvas.
Is there anyway to avoid this?
I would say, that using multiple canvases is generally bad design. On some phones it will even crash. The best way would really be using one canvas with tracking state of the application. And then in paint method you would have
protected void paint(final Graphics g) {
if(menu) {
paintMenu(g);
} else if (game) {
paintGame(g);
}
}
There are better ways to handle application state with screen objects, that would make the design cleaner, but I think you got the idea :)
/JaanusSiim
Do you use double buffering? If the device itself does not support double buffering you should define a off screen buffer (Image) and paint to it first and then paint the end result to the real screen. Do this for each of your canvases. Here is an example:
public class MyScreen extends Canvas {
private Image osb;
private Graphics osg;
//...
public MyScreen()
{
// if device is not double buffered
// use image as a offscreen buffer
if (!isDoubleBuffered())
{
osb = Image.createImage(screenWidth, screenHeight);
osg = osb.getGraphics();
osg.setFont(defaultFont);
}
}
protected void paint(Graphics graphics)
{
if (!isDoubleBuffered())
{
// do your painting on off screen buffer first
renderWorld(osg);
// once done paint it at image on the real screen
graphics.drawImage(osb, 0, 0, Tools.GRAPHICS_TOP_LEFT);
}
else
{
osg = graphics;
renderWorld(graphics);
}
}
}
A possible fix is by synchronising the switch using Display.callSerially(). The flicker is probably caused by the app attempting to draw to the screen while the switch of the Canvas is still ongoing. callSerially() is supposed to wait for the repaint to finish before attempting to call run() again.
But all this is entirely dependent on the phone since many devices do not implement callSerially(), never mind follow the implementation listed in the official documentation. The only devices I've known to work correctly with callSerially() were Siemens phones.
Another possible attempt would be to put a Thread.sleep() of something huge like 1000 ms, making sure that you've called your setCurrent() method beforehand. This way, the device might manage to make the change before the displayable attempts to draw.
The most likely problem is that it is a device issue and the guaranteed fix to the flicker is simple - use one Canvas. Probably not what you wanted to hear though. :)
It might be a good idea to use GameCanvas class if you are writing a game. It is much better for such purpose and when used properly it should solve your problem.
Hypothetically, using 1 canvas with a sate machine code for your application is a good idea. However the only device I have to test applications on (MOTO v3) crashes at resources loading time just because there's too much code/to be loaded in 1 GameCanvas ( haven't tried with Canvas ). It's as painful as it is real and atm I haven't found a solution to the problem.
If you're lucky to have a good number of devices to test on, it is worth having both approaches implemented and pretty much make versions of your game for each device.

Resources