Merge pull request #779 from fwSmit/transition-output
Create abstract output and fix wayland bug
This commit is contained in:
commit
0bcc135ffd
@ -264,6 +264,8 @@ Set to 0 to disable.
|
||||
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.
|
||||
|
||||
Note: this doesn't work on wayland yet.
|
||||
|
||||
=item B<font> (default: "Monospace 8")
|
||||
|
||||
Defines the font or font set used. Optionally set the size as a decimal number
|
||||
|
38
src/draw.c
38
src/draw.c
@ -1,7 +1,6 @@
|
||||
#include "draw.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <cairo.h>
|
||||
#include <math.h>
|
||||
#include <pango/pango-attributes.h>
|
||||
#include <pango/pangocairo.h>
|
||||
@ -10,6 +9,7 @@
|
||||
#include <pango/pango-types.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "dunst.h"
|
||||
#include "icon.h"
|
||||
@ -17,7 +17,15 @@
|
||||
#include "markup.h"
|
||||
#include "notification.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 {
|
||||
PangoLayout *l;
|
||||
@ -31,7 +39,8 @@ struct colored_layout {
|
||||
const struct notification *n;
|
||||
};
|
||||
|
||||
struct window_x11 *win;
|
||||
const struct output *output;
|
||||
window win;
|
||||
|
||||
PangoFontDescription *pango_fdesc;
|
||||
|
||||
@ -39,9 +48,12 @@ PangoFontDescription *pango_fdesc;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -176,7 +188,7 @@ static struct dimensions calculate_dimensions(GSList *layouts)
|
||||
{
|
||||
struct dimensions dim = { 0 };
|
||||
|
||||
struct screen_info *scr = get_active_screen();
|
||||
const struct screen_info *scr = output->get_active_screen();
|
||||
if (have_dynamic_width()) {
|
||||
/* dynamic width */
|
||||
dim.w = 0;
|
||||
@ -261,10 +273,10 @@ static struct dimensions calculate_dimensions(GSList *layouts)
|
||||
|
||||
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);
|
||||
pango_cairo_context_set_resolution(context, screen_dpi_get(screen));
|
||||
pango_cairo_context_set_resolution(context, screen->dpi);
|
||||
|
||||
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)
|
||||
{
|
||||
struct screen_info *scr = get_active_screen();
|
||||
const struct screen_info *scr = output->get_active_screen();
|
||||
|
||||
if (ret_x) {
|
||||
if (settings.geometry.negative_x) {
|
||||
@ -746,7 +758,7 @@ void draw(void)
|
||||
{
|
||||
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);
|
||||
|
||||
@ -764,7 +776,7 @@ void draw(void)
|
||||
}
|
||||
|
||||
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);
|
||||
g_slist_free_full(layouts, free_colored_layout);
|
||||
@ -772,7 +784,7 @@ void draw(void)
|
||||
|
||||
void draw_deinit(void)
|
||||
{
|
||||
x_win_destroy(win);
|
||||
x_free();
|
||||
output->win_destroy(win);
|
||||
output->deinit();
|
||||
}
|
||||
/* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
||||
|
@ -1,8 +1,12 @@
|
||||
#ifndef DUNST_DRAW_H
|
||||
#define DUNST_DRAW_H
|
||||
|
||||
#include "x11/x.h"
|
||||
extern struct window_x11 *win; // Temporary
|
||||
#include <stdbool.h>
|
||||
#include <cairo.h>
|
||||
#include "output.h"
|
||||
|
||||
extern window win; // Temporary
|
||||
extern const struct output *output;
|
||||
|
||||
void draw_setup(void);
|
||||
|
||||
|
11
src/dunst.c
11
src/dunst.c
@ -20,8 +20,7 @@
|
||||
#include "queues.h"
|
||||
#include "settings.h"
|
||||
#include "utils.h"
|
||||
#include "x11/screen.h"
|
||||
#include "x11/x.h"
|
||||
#include "output.h"
|
||||
|
||||
GMainLoop *mainloop = NULL;
|
||||
|
||||
@ -67,8 +66,8 @@ static gboolean run(void *data)
|
||||
|
||||
LOG_D("RUN");
|
||||
|
||||
dunst_status(S_FULLSCREEN, have_fullscreen_window());
|
||||
dunst_status(S_IDLE, x_is_idle());
|
||||
dunst_status(S_FULLSCREEN, output->have_fullscreen_window());
|
||||
dunst_status(S_IDLE, output->is_idle());
|
||||
|
||||
queues_update(status);
|
||||
|
||||
@ -77,9 +76,9 @@ static gboolean run(void *data)
|
||||
if (active) {
|
||||
// Call draw before showing the window to avoid flickering
|
||||
draw();
|
||||
x_win_show(win);
|
||||
output->win_show(win);
|
||||
} else {
|
||||
x_win_hide(win);
|
||||
output->win_hide(win);
|
||||
}
|
||||
|
||||
if (active) {
|
||||
|
62
src/output.c
Normal file
62
src/output.c
Normal 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
55
src/output.h
Normal 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: */
|
@ -25,6 +25,7 @@
|
||||
#include "notification.h"
|
||||
#include "settings.h"
|
||||
#include "utils.h"
|
||||
#include "output.h" // For checking if wayland is active.
|
||||
|
||||
/* notification lists */
|
||||
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;
|
||||
|
||||
/* 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();
|
||||
return false;
|
||||
}
|
||||
|
@ -69,12 +69,12 @@ static double screen_dpi_get_from_xft(void)
|
||||
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;
|
||||
}
|
||||
|
||||
double screen_dpi_get(struct screen_info *scr)
|
||||
double screen_dpi_get(const struct screen_info *scr)
|
||||
{
|
||||
if ( ! settings.force_xinerama
|
||||
&& settings.per_monitor_dpi)
|
||||
@ -156,6 +156,7 @@ void randr_update(void)
|
||||
screens[i].w = m[i].width;
|
||||
screens[i].h = m[i].height;
|
||||
screens[i].mmh = m[i].mheight;
|
||||
screens[i].dpi = screen_dpi_get(&screens[i]);
|
||||
}
|
||||
|
||||
XRRFreeMonitors(m);
|
||||
@ -300,7 +301,7 @@ bool window_is_fullscreen(Window window)
|
||||
* Select the screen on which the Window
|
||||
* should be displayed.
|
||||
*/
|
||||
struct screen_info *get_active_screen(void)
|
||||
const struct screen_info *get_active_screen(void)
|
||||
{
|
||||
int ret = 0;
|
||||
bool force_follow_mouse = false;
|
||||
|
@ -7,21 +7,12 @@
|
||||
|
||||
#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 screen_dpi_xft_cache_purge(void);
|
||||
bool screen_check_event(XEvent *ev);
|
||||
|
||||
struct screen_info *get_active_screen(void);
|
||||
double screen_dpi_get(struct screen_info *scr);
|
||||
const struct screen_info *get_active_screen(void);
|
||||
double screen_dpi_get(const struct screen_info *scr);
|
||||
|
||||
/**
|
||||
* Find the currently focused window and check if it's in
|
||||
|
37
src/x11/x.c
37
src/x11/x.c
@ -67,8 +67,10 @@ static int x_shortcut_tear_down_error_handler(void);
|
||||
static void setopacity(Window win, unsigned long opacity);
|
||||
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 */
|
||||
if (x != win->dim.x || y != win->dim.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);
|
||||
}
|
||||
|
||||
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 = {
|
||||
.x = 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);
|
||||
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)
|
||||
@ -278,7 +282,7 @@ gboolean x_mainloop_fd_dispatch(GSource *source, GSourceFunc callback, gpointer
|
||||
struct window_x11 *win = ((struct x11_source*) source)->win;
|
||||
|
||||
bool fullscreen_now;
|
||||
struct screen_info *scr;
|
||||
const struct screen_info *scr;
|
||||
XEvent ev;
|
||||
unsigned int state;
|
||||
while (XPending(xctx.dpy) > 0) {
|
||||
@ -641,7 +645,7 @@ GSource* x_win_reg_source(struct window_x11 *win)
|
||||
/*
|
||||
* 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));
|
||||
|
||||
@ -671,7 +675,7 @@ struct window_x11 *x_win_create(void)
|
||||
ExposureMask | KeyPressMask | VisibilityChangeMask |
|
||||
ButtonReleaseMask | FocusChangeMask| StructureNotifyMask;
|
||||
|
||||
struct screen_info *scr = get_active_screen();
|
||||
const struct screen_info *scr = get_active_screen();
|
||||
win->xwin = XCreateWindow(xctx.dpy,
|
||||
root,
|
||||
scr->x,
|
||||
@ -713,11 +717,13 @@ struct window_x11 *x_win_create(void)
|
||||
}
|
||||
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_unref(win->esrc);
|
||||
|
||||
@ -731,8 +737,10 @@ void x_win_destroy(struct window_x11 *win)
|
||||
/*
|
||||
* 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 */
|
||||
if (win->visible)
|
||||
return;
|
||||
@ -763,8 +771,9 @@ void x_win_show(struct window_x11 *win)
|
||||
/*
|
||||
* 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,);
|
||||
|
||||
x_shortcut_ungrab(&settings.close_ks);
|
||||
|
34
src/x11/x.h
34
src/x11/x.h
@ -11,6 +11,8 @@
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include "../output.h"
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
struct keyboard_shortcut {
|
||||
@ -24,42 +26,24 @@ struct keyboard_shortcut {
|
||||
// Cyclical dependency
|
||||
#include "../settings.h"
|
||||
|
||||
struct window_x11;
|
||||
|
||||
struct dimensions {
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
|
||||
int corner_radius;
|
||||
};
|
||||
|
||||
struct x_context {
|
||||
Display *dpy;
|
||||
XScreenSaverInfo *screensaver_info;
|
||||
};
|
||||
|
||||
struct color {
|
||||
double r;
|
||||
double g;
|
||||
double b;
|
||||
double a;
|
||||
};
|
||||
|
||||
extern struct x_context xctx;
|
||||
|
||||
/* window */
|
||||
struct window_x11 *x_win_create(void);
|
||||
void x_win_destroy(struct window_x11 *win);
|
||||
window x_win_create(void);
|
||||
void x_win_destroy(window);
|
||||
|
||||
void x_win_show(struct window_x11 *win);
|
||||
void x_win_hide(struct window_x11 *win);
|
||||
void x_win_show(window);
|
||||
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);
|
||||
cairo_t* x_win_get_context(struct window_x11 *win);
|
||||
bool x_win_visible(window);
|
||||
cairo_t* x_win_get_context(window);
|
||||
|
||||
/* X misc */
|
||||
bool x_is_idle(void);
|
||||
|
Loading…
x
Reference in New Issue
Block a user