Merge pull request #779 from fwSmit/transition-output

Create abstract output and fix wayland bug
This commit is contained in:
Nikos Tsipinakis 2020-11-18 17:44:18 +02:00 committed by GitHub
commit 0bcc135ffd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 196 additions and 75 deletions

View File

@ -264,6 +264,8 @@ Set to 0 to disable.
A client can mark a notification as transient to bypass this setting and timeout A client can mark a notification as transient to bypass this setting and timeout
anyway. Use a rule with 'set_transient = no' to disable this behavior. anyway. Use a rule with 'set_transient = no' to disable this behavior.
Note: this doesn't work on wayland yet.
=item B<font> (default: "Monospace 8") =item B<font> (default: "Monospace 8")
Defines the font or font set used. Optionally set the size as a decimal number Defines the font or font set used. Optionally set the size as a decimal number

View File

@ -1,7 +1,6 @@
#include "draw.h" #include "draw.h"
#include <assert.h> #include <assert.h>
#include <cairo.h>
#include <math.h> #include <math.h>
#include <pango/pango-attributes.h> #include <pango/pango-attributes.h>
#include <pango/pangocairo.h> #include <pango/pangocairo.h>
@ -10,6 +9,7 @@
#include <pango/pango-types.h> #include <pango/pango-types.h>
#include <stdlib.h> #include <stdlib.h>
#include <inttypes.h> #include <inttypes.h>
#include <glib.h>
#include "dunst.h" #include "dunst.h"
#include "icon.h" #include "icon.h"
@ -17,7 +17,15 @@
#include "markup.h" #include "markup.h"
#include "notification.h" #include "notification.h"
#include "queues.h" #include "queues.h"
#include "x11/x.h" #include "output.h"
#include "settings.h"
struct color {
double r;
double g;
double b;
double a;
};
struct colored_layout { struct colored_layout {
PangoLayout *l; PangoLayout *l;
@ -31,7 +39,8 @@ struct colored_layout {
const struct notification *n; const struct notification *n;
}; };
struct window_x11 *win; const struct output *output;
window win;
PangoFontDescription *pango_fdesc; PangoFontDescription *pango_fdesc;
@ -39,9 +48,12 @@ PangoFontDescription *pango_fdesc;
void draw_setup(void) void draw_setup(void)
{ {
x_setup(); const struct output *out = output_create();
output = out;
out->init();
win = out->win_create();
win = x_win_create();
pango_fdesc = pango_font_description_from_string(settings.font); pango_fdesc = pango_font_description_from_string(settings.font);
} }
@ -176,7 +188,7 @@ static struct dimensions calculate_dimensions(GSList *layouts)
{ {
struct dimensions dim = { 0 }; struct dimensions dim = { 0 };
struct screen_info *scr = get_active_screen(); const struct screen_info *scr = output->get_active_screen();
if (have_dynamic_width()) { if (have_dynamic_width()) {
/* dynamic width */ /* dynamic width */
dim.w = 0; dim.w = 0;
@ -261,10 +273,10 @@ static struct dimensions calculate_dimensions(GSList *layouts)
static PangoLayout *layout_create(cairo_t *c) static PangoLayout *layout_create(cairo_t *c)
{ {
struct screen_info *screen = get_active_screen(); const struct screen_info *screen = output->get_active_screen();
PangoContext *context = pango_cairo_create_context(c); PangoContext *context = pango_cairo_create_context(c);
pango_cairo_context_set_resolution(context, screen_dpi_get(screen)); pango_cairo_context_set_resolution(context, screen->dpi);
PangoLayout *layout = pango_layout_new(context); PangoLayout *layout = pango_layout_new(context);
@ -723,7 +735,7 @@ static struct dimensions layout_render(cairo_surface_t *srf,
*/ */
static void calc_window_pos(int width, int height, int *ret_x, int *ret_y) static void calc_window_pos(int width, int height, int *ret_x, int *ret_y)
{ {
struct screen_info *scr = get_active_screen(); const struct screen_info *scr = output->get_active_screen();
if (ret_x) { if (ret_x) {
if (settings.geometry.negative_x) { if (settings.geometry.negative_x) {
@ -746,7 +758,7 @@ void draw(void)
{ {
assert(queues_length_displayed() > 0); assert(queues_length_displayed() > 0);
GSList *layouts = create_layouts(x_win_get_context(win)); GSList *layouts = create_layouts(output->win_get_context(win));
struct dimensions dim = calculate_dimensions(layouts); struct dimensions dim = calculate_dimensions(layouts);
@ -764,7 +776,7 @@ void draw(void)
} }
calc_window_pos(dim.w, dim.h, &dim.x, &dim.y); calc_window_pos(dim.w, dim.h, &dim.x, &dim.y);
x_display_surface(image_surface, win, &dim); output->display_surface(image_surface, win, &dim);
cairo_surface_destroy(image_surface); cairo_surface_destroy(image_surface);
g_slist_free_full(layouts, free_colored_layout); g_slist_free_full(layouts, free_colored_layout);
@ -772,7 +784,7 @@ void draw(void)
void draw_deinit(void) void draw_deinit(void)
{ {
x_win_destroy(win); output->win_destroy(win);
x_free(); output->deinit();
} }
/* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */ /* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */

View File

@ -1,8 +1,12 @@
#ifndef DUNST_DRAW_H #ifndef DUNST_DRAW_H
#define DUNST_DRAW_H #define DUNST_DRAW_H
#include "x11/x.h" #include <stdbool.h>
extern struct window_x11 *win; // Temporary #include <cairo.h>
#include "output.h"
extern window win; // Temporary
extern const struct output *output;
void draw_setup(void); void draw_setup(void);

View File

@ -20,8 +20,7 @@
#include "queues.h" #include "queues.h"
#include "settings.h" #include "settings.h"
#include "utils.h" #include "utils.h"
#include "x11/screen.h" #include "output.h"
#include "x11/x.h"
GMainLoop *mainloop = NULL; GMainLoop *mainloop = NULL;
@ -67,8 +66,8 @@ static gboolean run(void *data)
LOG_D("RUN"); LOG_D("RUN");
dunst_status(S_FULLSCREEN, have_fullscreen_window()); dunst_status(S_FULLSCREEN, output->have_fullscreen_window());
dunst_status(S_IDLE, x_is_idle()); dunst_status(S_IDLE, output->is_idle());
queues_update(status); queues_update(status);
@ -77,9 +76,9 @@ static gboolean run(void *data)
if (active) { if (active) {
// Call draw before showing the window to avoid flickering // Call draw before showing the window to avoid flickering
draw(); draw();
x_win_show(win); output->win_show(win);
} else { } else {
x_win_hide(win); output->win_hide(win);
} }
if (active) { if (active) {

62
src/output.c Normal file
View File

@ -0,0 +1,62 @@
#include "output.h"
#include "log.h"
#include "x11/x.h"
#include "x11/screen.h"
/* #include "wayland/wl.h" */ // Not yet
const bool is_running_wayland(void){
char* wayland_display = getenv("WAYLAND_DISPLAY");
return !(wayland_display == NULL);
}
const struct output output_x11 = {
x_setup,
x_free,
x_win_create,
x_win_destroy,
x_win_show,
x_win_hide,
x_display_surface,
x_win_visible,
x_win_get_context,
get_active_screen,
x_is_idle,
have_fullscreen_window
};
/* const struct output output_wl = { */
/* wl_init, */
/* wl_deinit, */
/* wl_win_create, */
/* wl_win_destroy, */
/* wl_win_show, */
/* wl_win_hide, */
/* wl_display_surface, */
/* wl_win_visible, */
/* wl_win_get_context, */
/* wl_get_active_screen, */
/* wl_is_idle, */
/* wl_have_fullscreen_window */
/* }; */
const struct output* output_create(void)
{
if (is_running_wayland()) {
LOG_I("System is running wayland");
} else{
LOG_I("System is running X11");
}
return &output_x11;
}
/* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */

55
src/output.h Normal file
View File

@ -0,0 +1,55 @@
#ifndef DUNST_OUTPUT_H
#define DUNST_OUTPUT_H
#include <stdbool.h>
#include <glib.h>
#include <cairo.h>
typedef gpointer window;
struct dimensions {
int x;
int y;
int w;
int h;
int corner_radius;
};
struct screen_info {
int id;
int x;
int y;
unsigned int h;
unsigned int mmh;
unsigned int w;
int dpi;
};
struct output {
void (*init)(void);
void (*deinit)(void);
window (*win_create)(void);
void (*win_destroy)(window);
void (*win_show)(window);
void (*win_hide)(window);
void (*display_surface)(cairo_surface_t *srf, window win, const struct dimensions*);
bool (*win_visible)(window);
cairo_t* (*win_get_context)(window);
const struct screen_info* (*get_active_screen)(void);
bool (*is_idle)(void);
bool (*have_fullscreen_window)(void);
};
const struct output* output_create(void);
const bool is_running_wayland(void);
#endif
/* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */

View File

@ -25,6 +25,7 @@
#include "notification.h" #include "notification.h"
#include "settings.h" #include "settings.h"
#include "utils.h" #include "utils.h"
#include "output.h" // For checking if wayland is active.
/* notification lists */ /* notification lists */
static GQueue *waiting = NULL; /**< all new notifications get into here */ static GQueue *waiting = NULL; /**< all new notifications get into here */
@ -143,7 +144,8 @@ static bool queues_notification_is_finished(struct notification *n, struct dunst
bool is_idle = status.fullscreen ? false : status.idle; bool is_idle = status.fullscreen ? false : status.idle;
/* don't timeout when user is idle */ /* don't timeout when user is idle */
if (is_idle && !n->transient) { /* NOTE: Idle is not working on wayland */
if (is_idle && !n->transient && !is_running_wayland()) {
n->start = time_monotonic_now(); n->start = time_monotonic_now();
return false; return false;
} }

View File

@ -69,12 +69,12 @@ static double screen_dpi_get_from_xft(void)
return screen_dpi_xft_cache; return screen_dpi_xft_cache;
} }
static double screen_dpi_get_from_monitor(struct screen_info *scr) static double screen_dpi_get_from_monitor(const struct screen_info *scr)
{ {
return (double)scr->h * 25.4 / (double)scr->mmh; return (double)scr->h * 25.4 / (double)scr->mmh;
} }
double screen_dpi_get(struct screen_info *scr) double screen_dpi_get(const struct screen_info *scr)
{ {
if ( ! settings.force_xinerama if ( ! settings.force_xinerama
&& settings.per_monitor_dpi) && settings.per_monitor_dpi)
@ -156,6 +156,7 @@ void randr_update(void)
screens[i].w = m[i].width; screens[i].w = m[i].width;
screens[i].h = m[i].height; screens[i].h = m[i].height;
screens[i].mmh = m[i].mheight; screens[i].mmh = m[i].mheight;
screens[i].dpi = screen_dpi_get(&screens[i]);
} }
XRRFreeMonitors(m); XRRFreeMonitors(m);
@ -300,7 +301,7 @@ bool window_is_fullscreen(Window window)
* Select the screen on which the Window * Select the screen on which the Window
* should be displayed. * should be displayed.
*/ */
struct screen_info *get_active_screen(void) const struct screen_info *get_active_screen(void)
{ {
int ret = 0; int ret = 0;
bool force_follow_mouse = false; bool force_follow_mouse = false;

View File

@ -7,21 +7,12 @@
#define INRECT(x,y,rx,ry,rw,rh) ((x) >= (rx) && (x) < (rx)+(rw) && (y) >= (ry) && (y) < (ry)+(rh)) #define INRECT(x,y,rx,ry,rw,rh) ((x) >= (rx) && (x) < (rx)+(rw) && (y) >= (ry) && (y) < (ry)+(rh))
struct screen_info {
int id;
int x;
int y;
unsigned int h;
unsigned int mmh;
unsigned int w;
};
void init_screens(void); void init_screens(void);
void screen_dpi_xft_cache_purge(void); void screen_dpi_xft_cache_purge(void);
bool screen_check_event(XEvent *ev); bool screen_check_event(XEvent *ev);
struct screen_info *get_active_screen(void); const struct screen_info *get_active_screen(void);
double screen_dpi_get(struct screen_info *scr); double screen_dpi_get(const struct screen_info *scr);
/** /**
* Find the currently focused window and check if it's in * Find the currently focused window and check if it's in

View File

@ -67,8 +67,10 @@ static int x_shortcut_tear_down_error_handler(void);
static void setopacity(Window win, unsigned long opacity); static void setopacity(Window win, unsigned long opacity);
static void x_handle_click(XEvent ev); static void x_handle_click(XEvent ev);
static void x_win_move(struct window_x11 *win, int x, int y, int width, int height) static void x_win_move(window winptr, int x, int y, int width, int height)
{ {
struct window_x11 *win = (struct window_x11*)winptr;
/* move and resize */ /* move and resize */
if (x != win->dim.x || y != win->dim.y) { if (x != win->dim.x || y != win->dim.y) {
XMoveWindow(xctx.dpy, win->xwin, x, y); XMoveWindow(xctx.dpy, win->xwin, x, y);
@ -126,8 +128,9 @@ static void x_win_corners_shape(struct window_x11 *win, const int rad)
win->xwin, ShapeNotifyMask); win->xwin, ShapeNotifyMask);
} }
static void x_win_corners_unshape(struct window_x11 *win) static void x_win_corners_unshape(window winptr)
{ {
struct window_x11 *win = (struct window_x11*)winptr;
XRectangle rect = { XRectangle rect = {
.x = 0, .x = 0,
.y = 0, .y = 0,
@ -153,8 +156,9 @@ static bool x_win_composited(struct window_x11 *win)
} }
} }
void x_display_surface(cairo_surface_t *srf, struct window_x11 *win, const struct dimensions *dim) void x_display_surface(cairo_surface_t *srf, window winptr, const struct dimensions *dim)
{ {
struct window_x11 *win = (struct window_x11*)winptr;
x_win_move(win, dim->x, dim->y, dim->w, dim->h); x_win_move(win, dim->x, dim->y, dim->w, dim->h);
cairo_xlib_surface_set_size(win->root_surface, dim->w, dim->h); cairo_xlib_surface_set_size(win->root_surface, dim->w, dim->h);
@ -173,14 +177,14 @@ void x_display_surface(cairo_surface_t *srf, struct window_x11 *win, const struc
} }
bool x_win_visible(struct window_x11 *win) bool x_win_visible(window winptr)
{ {
return win->visible; return ((struct window_x11*)winptr)->visible;
} }
cairo_t* x_win_get_context(struct window_x11 *win) cairo_t* x_win_get_context(window winptr)
{ {
return win->c_ctx; return ((struct window_x11*)win)->c_ctx;
} }
static void setopacity(Window win, unsigned long opacity) static void setopacity(Window win, unsigned long opacity)
@ -278,7 +282,7 @@ gboolean x_mainloop_fd_dispatch(GSource *source, GSourceFunc callback, gpointer
struct window_x11 *win = ((struct x11_source*) source)->win; struct window_x11 *win = ((struct x11_source*) source)->win;
bool fullscreen_now; bool fullscreen_now;
struct screen_info *scr; const struct screen_info *scr;
XEvent ev; XEvent ev;
unsigned int state; unsigned int state;
while (XPending(xctx.dpy) > 0) { while (XPending(xctx.dpy) > 0) {
@ -641,7 +645,7 @@ GSource* x_win_reg_source(struct window_x11 *win)
/* /*
* Setup the window * Setup the window
*/ */
struct window_x11 *x_win_create(void) window x_win_create(void)
{ {
struct window_x11 *win = g_malloc0(sizeof(struct window_x11)); struct window_x11 *win = g_malloc0(sizeof(struct window_x11));
@ -671,7 +675,7 @@ struct window_x11 *x_win_create(void)
ExposureMask | KeyPressMask | VisibilityChangeMask | ExposureMask | KeyPressMask | VisibilityChangeMask |
ButtonReleaseMask | FocusChangeMask| StructureNotifyMask; ButtonReleaseMask | FocusChangeMask| StructureNotifyMask;
struct screen_info *scr = get_active_screen(); const struct screen_info *scr = get_active_screen();
win->xwin = XCreateWindow(xctx.dpy, win->xwin = XCreateWindow(xctx.dpy,
root, root,
scr->x, scr->x,
@ -713,11 +717,13 @@ struct window_x11 *x_win_create(void)
} }
XSelectInput(xctx.dpy, root, root_event_mask); XSelectInput(xctx.dpy, root, root_event_mask);
return win; return (window)win;
} }
void x_win_destroy(struct window_x11 *win) void x_win_destroy(window winptr)
{ {
struct window_x11 *win = (struct window_x11*)winptr;
g_source_destroy(win->esrc); g_source_destroy(win->esrc);
g_source_unref(win->esrc); g_source_unref(win->esrc);
@ -731,8 +737,10 @@ void x_win_destroy(struct window_x11 *win)
/* /*
* Show the window and grab shortcuts. * Show the window and grab shortcuts.
*/ */
void x_win_show(struct window_x11 *win) void x_win_show(window winptr)
{ {
struct window_x11 *win = (struct window_x11*)winptr;
/* window is already mapped or there's nothing to show */ /* window is already mapped or there's nothing to show */
if (win->visible) if (win->visible)
return; return;
@ -763,8 +771,9 @@ void x_win_show(struct window_x11 *win)
/* /*
* Hide the window and ungrab unused keyboard_shortcuts * Hide the window and ungrab unused keyboard_shortcuts
*/ */
void x_win_hide(struct window_x11 *win) void x_win_hide(window winptr)
{ {
struct window_x11 *win = (struct window_x11*)winptr;
ASSERT_OR_RET(win->visible,); ASSERT_OR_RET(win->visible,);
x_shortcut_ungrab(&settings.close_ks); x_shortcut_ungrab(&settings.close_ks);

View File

@ -11,6 +11,8 @@
#include <X11/X.h> #include <X11/X.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include "../output.h"
#include "screen.h" #include "screen.h"
struct keyboard_shortcut { struct keyboard_shortcut {
@ -24,42 +26,24 @@ struct keyboard_shortcut {
// Cyclical dependency // Cyclical dependency
#include "../settings.h" #include "../settings.h"
struct window_x11;
struct dimensions {
int x;
int y;
int w;
int h;
int corner_radius;
};
struct x_context { struct x_context {
Display *dpy; Display *dpy;
XScreenSaverInfo *screensaver_info; XScreenSaverInfo *screensaver_info;
}; };
struct color {
double r;
double g;
double b;
double a;
};
extern struct x_context xctx; extern struct x_context xctx;
/* window */ /* window */
struct window_x11 *x_win_create(void); window x_win_create(void);
void x_win_destroy(struct window_x11 *win); void x_win_destroy(window);
void x_win_show(struct window_x11 *win); void x_win_show(window);
void x_win_hide(struct window_x11 *win); void x_win_hide(window);
void x_display_surface(cairo_surface_t *srf, struct window_x11 *win, const struct dimensions *dim); void x_display_surface(cairo_surface_t *srf, window, const struct dimensions *dim);
bool x_win_visible(struct window_x11 *win); bool x_win_visible(window);
cairo_t* x_win_get_context(struct window_x11 *win); cairo_t* x_win_get_context(window);
/* X misc */ /* X misc */
bool x_is_idle(void); bool x_is_idle(void);