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
	 Nikos Tsipinakis
						Nikos Tsipinakis