Skip to content

Instantly share code, notes, and snippets.

@adventurist
Last active January 11, 2022 08:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adventurist/7cfe0c3cd175a73dbecd24a23b371471 to your computer and use it in GitHub Desktop.
Save adventurist/7cfe0c3cd175a73dbecd24a23b371471 to your computer and use it in GitHub Desktop.
cef simple main
#include "tests/cefsimple/simple_app.h"
#if defined(CEF_X11)
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#endif
#include "include/base/cef_logging.h"
#include "include/cef_command_line.h"
#include <future>
#define WIDTH 960
#define HEIGHT 640
static const char *event_names[]{
"",
"",
"KeyPress",
"KeyRelease",
"ButtonPress",
"ButtonRelease",
"MotionNotify",
"EnterNotify",
"LeaveNotify",
"FocusIn",
"FocusOut",
"KeymapNotify",
"Expose",
"GraphicsExpose",
"NoExpose",
"VisibilityNotify",
"CreateNotify",
"DestroyNotify",
"UnmapNotify",
"MapNotify",
"MapRequest",
"ReparentNotify",
"ConfigureNotify",
"ConfigureRequest",
"GravityNotify",
"ResizeRequest",
"CirculateNotify",
"CirculateRequest",
"PropertyNotify",
"SelectionClear",
"SelectionRequest",
"SelectionNotify",
"ColormapNotify",
"ClientMessage",
"MappingNotify"};
struct XTree
{
Window root {0};
Window parent {0};
Window* children {0};
unsigned int child_num {0};
};
struct XCoords
{
int x;
int y;
int h;
int w;
};
class X11Window
{
Display* display;
int screen;
Colormap colormap;
Window container_window;
Window child;
public:
Window GetID()
{
return container_window;
}
Display* GetDisplay()
{
return display;
}
void Create()
{
static uint32_t black;
static uint32_t white;
child = 0;
display = XOpenDisplay(NULL);
screen = DefaultScreen(display);
black = BlackPixel(display, screen);
white = WhitePixel(display, screen);
container_window = XCreateSimpleWindow(display, DefaultRootWindow(display), 0, 0,
WIDTH, HEIGHT, 5, white, black);
XSetStandardProperties(display, container_window, "TestWindow", "TestIcon", None, NULL, 0, NULL);
XSelectInput(display, container_window, ExposureMask | StructureNotifyMask);
XMapWindow(display, container_window);
}
~X11Window()
{
XCloseDisplay(display);
}
void Query()
{
XTree t{};
XQueryTree(display, container_window, &t.root, &t.parent, &t.children, &t.child_num);
if (t.child_num)
child = t.children[0];
}
Window GetChild()
{
return child;
}
XWindowAttributes GetChildAttributes()
{
int x, y;
XWindowAttributes wa;
XTranslateCoordinates(display, child, container_window, 0, 0, &x, &y, &child);
XGetWindowAttributes(display, child, &wa);
return wa;
}
XCoords GetChildCoords()
{
XWindowAttributes wa = GetChildAttributes();
return XCoords{wa.x, wa.y, wa.height, wa.width};
}
void Run()
{
XEvent event;
XNextEvent(display, &event);
printf("container_event: %s\n", event_names[event.type]);
// Refresh container window
if (event.type == Expose)
XClearWindow(display, container_window);
}
};
namespace {
int XErrorHandlerImpl(Display* display, XErrorEvent* event) {
LOG(WARNING) << "X error received: "
<< "type " << event->type << ", "
<< "serial " << event->serial << ", "
<< "error_code " << static_cast<int>(event->error_code) << ", "
<< "request_code " << static_cast<int>(event->request_code)
<< ", "
<< "minor_code " << static_cast<int>(event->minor_code);
return 0;
}
int XIOErrorHandlerImpl(Display* display) {
return 0;
}
} // ns
X11Window x_window;
bool window_valid = true;
int x = 0;
int y = 0;
void RunWindow()
{
uint64_t time_passed{0};
XCoords coords {};
for (;;)
{
LOG(INFO) << "Running Window";
x_window.Run();
std::this_thread::sleep_for(std::chrono::milliseconds(50));
time_passed += 50;
if (!x_window.GetChild())
x_window.Query();
else
{
coords = x_window.GetChildCoords();
LOG(INFO) << "Child window: " << "\nX: " << coords.x
<< "\nY: " << coords.y
<< "\nH: " << coords.h
<< "\nW: " << coords.w;
}
if (window_valid && coords.h)
{
LOG(INFO) << "Invalidating parent window";
XClearArea(x_window.GetDisplay(), x_window.GetChild(), coords.x + 10, coords.y + 10, 10, 10, true);
window_valid = false;
}
}
}
int main(int argc, char* argv[])
{
CefMainArgs main_args(argc, argv);
int exit_code = CefExecuteProcess(main_args, nullptr, nullptr);
if (exit_code >= 0) return exit_code;
XSetErrorHandler (XErrorHandlerImpl);
XSetIOErrorHandler(XIOErrorHandlerImpl);
LOG(INFO) << "Creating X11 Window";
x_window.Create();
std::this_thread::sleep_for(std::chrono::milliseconds(50));
std::future<void> window_future = std::async(std::launch::async, RunWindow);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
CefRefPtr<CefCommandLine> command_line = CefCommandLine::CreateCommandLine();
command_line->InitFromArgv(argc, argv);
CefSettings settings;
if (command_line->HasSwitch("enable-chrome-runtime"))
settings.chrome_runtime = true;
#if !defined(CEF_USE_SANDBOX)
settings.no_sandbox = true;
#endif
CefRefPtr<SimpleApp> app(new SimpleApp(x_window.GetID()));
CefInitialize(main_args, settings, app.get(), nullptr);
CefRunMessageLoop();
CefShutdown();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment