aboutsummaryrefslogtreecommitdiff
path: root/src/window/window.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/window/window.c')
-rw-r--r--src/window/window.c48
1 files changed, 43 insertions, 5 deletions
diff --git a/src/window/window.c b/src/window/window.c
index 72f8598..ba4e8d5 100644
--- a/src/window/window.c
+++ b/src/window/window.c
@@ -69,7 +69,12 @@ typedef struct {
Atom image_gif_atom;
Atom incr_atom;
Atom net_wm_state_atom;
- Atom wm_state_fullscreen_atom;
+ Atom net_wm_state_fullscreen_atom;
+ Atom net_wm_state_above_atom;
+ Atom net_wm_name_atom;
+ Atom net_wm_window_type_atom;
+ Atom net_wm_window_type_normal_atom;
+ Atom net_wm_window_type_dialog_atom;
Cursor default_cursor;
Cursor invisible_cursor;
unsigned int prev_keycode_pressed;
@@ -160,7 +165,12 @@ static int x11_context_init(x11_context *self, bool alpha) {
self->image_gif_atom = XInternAtom(context->connection, "image/gif", False);
self->incr_atom = XInternAtom(context->connection, "INCR", False);
self->net_wm_state_atom = XInternAtom(context->connection, "_NET_WM_STATE", False);
- self->wm_state_fullscreen_atom = XInternAtom(context->connection, "_NET_WM_STATE_FULLSCREEN", False);
+ self->net_wm_state_fullscreen_atom = XInternAtom(context->connection, "_NET_WM_STATE_FULLSCREEN", False);
+ self->net_wm_state_above_atom = XInternAtom(context->connection, "_NET_WM_STATE_ABOVE", False);
+ self->net_wm_name_atom = XInternAtom(context->connection, "_NET_WM_NAME", False);
+ self->net_wm_window_type_atom = XInternAtom(context->connection, "_NET_WM_WINDOW_TYPE", False);
+ self->net_wm_window_type_normal_atom = XInternAtom(context->connection, "_NET_WM_WINDOW_TYPE_NORMAL", False);
+ self->net_wm_window_type_dialog_atom = XInternAtom(context->connection, "_NET_WM_WINDOW_TYPE_DIALOG", False);
self->default_cursor = None;
self->invisible_cursor = None;
@@ -473,6 +483,22 @@ static unsigned long mgl_color_to_x11_pixel(mgl_color color) {
return ((uint32_t)color.a << 24) | ((uint32_t)color.r << 16) | ((uint32_t)color.g << 8) | (uint32_t)color.b;
}
+static void mgl_set_window_type(mgl_window *self, mgl_window_type window_type) {
+ mgl_context *context = mgl_get_context();
+ x11_context *x11_context = self->context;
+ switch(window_type) {
+ case MGL_WINDOW_TYPE_NORMAL: {
+ XChangeProperty(context->connection, self->window, x11_context->net_wm_window_type_atom, XA_ATOM, 32, PropModeReplace, (unsigned char*)&x11_context->net_wm_window_type_normal_atom, 1L);
+ break;
+ }
+ case MGL_WINDOW_TYPE_DIALOG: {
+ XChangeProperty(context->connection, self->window, x11_context->net_wm_window_type_atom, XA_ATOM, 32, PropModeReplace, (unsigned char*)&x11_context->net_wm_window_type_dialog_atom, 1L);
+ XChangeProperty(context->connection, self->window, x11_context->net_wm_state_atom, XA_ATOM, 32, PropModeReplace, (unsigned char*)&x11_context->net_wm_state_above_atom, 1L);
+ break;
+ }
+ }
+}
+
static int mgl_window_init(mgl_window *self, const char *title, const mgl_window_create_params *params, Window existing_window) {
self->window = 0;
self->context = NULL;
@@ -573,7 +599,7 @@ static int mgl_window_init(mgl_window *self, const char *title, const mgl_window
return -1;
}
- XStoreName(context->connection, self->window, title);
+ mgl_window_set_title(self, title);
if(!hide_window)
XMapWindow(context->connection, self->window);
}
@@ -594,6 +620,14 @@ static int mgl_window_init(mgl_window *self, const char *title, const mgl_window
32, PropModeReplace, (const unsigned char*)&pid, 1);
}
+ if(params && params->class_name) {
+ XClassHint class_hint = { params->class_name, params->class_name };
+ XSetClassHint(context->connection, self->window, &class_hint);
+ }
+
+ mgl_window_type window_type = params ? params->window_type : MGL_WINDOW_TYPE_NORMAL;
+ mgl_set_window_type(self, window_type);
+
XFlush(context->connection);
/* TODO: Check for failure? */
@@ -1306,7 +1340,11 @@ void mgl_window_close(mgl_window *self) {
void mgl_window_set_title(mgl_window *self, const char *title) {
mgl_context *context = mgl_get_context();
+ x11_context *x11_context = self->context;
+
XStoreName(context->connection, self->window, title);
+ XChangeProperty(context->connection, self->window, x11_context->net_wm_name_atom, x11_context->utf8_string_atom, 8, PropModeReplace, (unsigned char*)title, strlen(title));
+ XFlush(context->connection);
}
void mgl_window_set_cursor_visible(mgl_window *self, bool visible) {
@@ -1341,7 +1379,7 @@ void mgl_window_set_fullscreen(mgl_window *self, bool fullscreen) {
xev.xclient.message_type = x11_context->net_wm_state_atom;
xev.xclient.format = 32;
xev.xclient.data.l[0] = fullscreen ? 1 : 0;
- xev.xclient.data.l[1] = x11_context->wm_state_fullscreen_atom;
+ xev.xclient.data.l[1] = x11_context->net_wm_state_fullscreen_atom;
xev.xclient.data.l[2] = 0;
xev.xclient.data.l[3] = 1;
xev.xclient.data.l[4] = 0;
@@ -1365,7 +1403,7 @@ bool mgl_window_is_fullscreen(const mgl_window *self) {
unsigned long remaining_bytes = 0;
unsigned char *data = NULL;
if(XGetWindowProperty(context->connection, self->window, x11_context->net_wm_state_atom, 0, 1024, False, PropertyNewValue, &type, &format, &items, &remaining_bytes, &data) == Success && data) {
- is_fullscreen = format == 32 && *(unsigned long*)data == x11_context->wm_state_fullscreen_atom;
+ is_fullscreen = format == 32 && *(unsigned long*)data == x11_context->net_wm_state_fullscreen_atom;
XFree(data);
}
return is_fullscreen;