Merge pull request #472 from bebehei/fullscreen
Implement hiding on fullscreen
This commit is contained in:
commit
f80e6fc579
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- `fullscreen` rule to hide notifications when a fullscreen window is active
|
||||||
|
|
||||||
## 1.3.0 - 2018-01-05
|
## 1.3.0 - 2018-01-05
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@ -594,8 +594,9 @@ Shell-like globing is supported.
|
|||||||
=item B<modifying>
|
=item B<modifying>
|
||||||
|
|
||||||
The following attributes can be overridden: timeout, urgency, foreground,
|
The following attributes can be overridden: timeout, urgency, foreground,
|
||||||
background, new_icon, set_transient, format where, as with the filtering attributes,
|
background, new_icon, set_transient, format, fullscreen where,
|
||||||
each one corresponds to the respective notification attribute to be modified.
|
as with the filtering attributes, each one corresponds to the respective
|
||||||
|
notification attribute to be modified.
|
||||||
|
|
||||||
As with filtering, to make a rule modify an attribute simply assign it in the
|
As with filtering, to make a rule modify an attribute simply assign it in the
|
||||||
rule definition.
|
rule definition.
|
||||||
|
15
dunstrc
15
dunstrc
@ -279,7 +279,7 @@
|
|||||||
# override settings for certain messages.
|
# override settings for certain messages.
|
||||||
# Messages can be matched by "appname", "summary", "body", "icon", "category",
|
# Messages can be matched by "appname", "summary", "body", "icon", "category",
|
||||||
# "msg_urgency" and you can override the "timeout", "urgency", "foreground",
|
# "msg_urgency" and you can override the "timeout", "urgency", "foreground",
|
||||||
# "background", "new_icon" and "format".
|
# "background", "new_icon" and "format", "fullscreen".
|
||||||
# Shell-like globbing will get expanded.
|
# Shell-like globbing will get expanded.
|
||||||
#
|
#
|
||||||
# SCRIPTING
|
# SCRIPTING
|
||||||
@ -294,6 +294,19 @@
|
|||||||
# NOTE: It might be helpful to run dunst -print in a terminal in order
|
# NOTE: It might be helpful to run dunst -print in a terminal in order
|
||||||
# to find fitting options for rules.
|
# to find fitting options for rules.
|
||||||
|
|
||||||
|
# fullscreen values
|
||||||
|
# show: show the notifications, regardless if there is a fullscreen window opened
|
||||||
|
# delay: displays the new notification, if there is there is no fullscreen window active
|
||||||
|
# If the notification is already drawn, it won't get undrawn.
|
||||||
|
# pushback: same as delay, but when switching into fullscreen, the notification will get
|
||||||
|
# withdrawn from screen again and will get delayed like a new notification
|
||||||
|
|
||||||
|
#[fullscreen_delay_everything]
|
||||||
|
# fullscreen = delay
|
||||||
|
#[fullscreen_show_critical]
|
||||||
|
# msg_urgency = critical
|
||||||
|
# fullscreen = show
|
||||||
|
|
||||||
#[espeak]
|
#[espeak]
|
||||||
# summary = "*"
|
# summary = "*"
|
||||||
# script = dunst_espeak.sh
|
# script = dunst_espeak.sh
|
||||||
|
@ -48,8 +48,12 @@ void wake_up(void)
|
|||||||
|
|
||||||
static gboolean run(void *data)
|
static gboolean run(void *data)
|
||||||
{
|
{
|
||||||
queues_check_timeouts(x_is_idle());
|
LOG_D("RUN");
|
||||||
queues_update();
|
|
||||||
|
bool fullscreen = have_fullscreen_window();
|
||||||
|
|
||||||
|
queues_check_timeouts(x_is_idle(), fullscreen);
|
||||||
|
queues_update(fullscreen);
|
||||||
|
|
||||||
static gint64 next_timeout = 0;
|
static gint64 next_timeout = 0;
|
||||||
|
|
||||||
|
@ -28,6 +28,19 @@ static void notification_extract_urls(notification *n);
|
|||||||
static void notification_format_message(notification *n);
|
static void notification_format_message(notification *n);
|
||||||
static void notification_dmenu_string(notification *n);
|
static void notification_dmenu_string(notification *n);
|
||||||
|
|
||||||
|
/* see notification.h */
|
||||||
|
const char *enum_to_string_fullscreen(enum behavior_fullscreen in)
|
||||||
|
{
|
||||||
|
switch (in) {
|
||||||
|
case FS_SHOW: return "show";
|
||||||
|
case FS_DELAY: return "delay";
|
||||||
|
case FS_PUSHBACK: return "pushback";
|
||||||
|
case FS_NULL: return "(null)";
|
||||||
|
default:
|
||||||
|
LOG_E("Enum behavior_fullscreen has wrong value.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* print a human readable representation
|
* print a human readable representation
|
||||||
* of the given notification to stdout.
|
* of the given notification to stdout.
|
||||||
@ -49,6 +62,7 @@ void notification_print(notification *n)
|
|||||||
printf("\tfg: %s\n", n->colors[ColFG]);
|
printf("\tfg: %s\n", n->colors[ColFG]);
|
||||||
printf("\tbg: %s\n", n->colors[ColBG]);
|
printf("\tbg: %s\n", n->colors[ColBG]);
|
||||||
printf("\tframe: %s\n", n->colors[ColFrame]);
|
printf("\tframe: %s\n", n->colors[ColFrame]);
|
||||||
|
printf("\tfullscreen: %s\n", enum_to_string_fullscreen(n->fullscreen));
|
||||||
printf("\tid: %d\n", n->id);
|
printf("\tid: %d\n", n->id);
|
||||||
if (n->urls) {
|
if (n->urls) {
|
||||||
char *urls = string_replace_all("\n", "\t\t\n", g_strdup(n->urls));
|
char *urls = string_replace_all("\n", "\t\t\n", g_strdup(n->urls));
|
||||||
@ -284,6 +298,8 @@ notification *notification_create(void)
|
|||||||
n->transient = false;
|
n->transient = false;
|
||||||
n->progress = -1;
|
n->progress = -1;
|
||||||
|
|
||||||
|
n->fullscreen = FS_SHOW;
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,13 @@
|
|||||||
|
|
||||||
#define DUNST_NOTIF_MAX_CHARS 5000
|
#define DUNST_NOTIF_MAX_CHARS 5000
|
||||||
|
|
||||||
|
enum behavior_fullscreen {
|
||||||
|
FS_NULL, //!< Invalid value
|
||||||
|
FS_DELAY, //!< Delay the notification until leaving fullscreen mode
|
||||||
|
FS_PUSHBACK, //!< When entering fullscreen mode, push the notification back to waiting
|
||||||
|
FS_SHOW, //!< Show the message when in fullscreen mode
|
||||||
|
};
|
||||||
|
|
||||||
/// Representing the urgencies according to the notification spec
|
/// Representing the urgencies according to the notification spec
|
||||||
enum urgency {
|
enum urgency {
|
||||||
URG_NONE = -1, /**< Urgency not set (invalid) */
|
URG_NONE = -1, /**< Urgency not set (invalid) */
|
||||||
@ -69,6 +76,7 @@ typedef struct _notification {
|
|||||||
bool first_render; /**< markup has been rendered before? */
|
bool first_render; /**< markup has been rendered before? */
|
||||||
int dup_count; /**< amount of duplicate notifications stacked onto this */
|
int dup_count; /**< amount of duplicate notifications stacked onto this */
|
||||||
int displayed_height;
|
int displayed_height;
|
||||||
|
enum behavior_fullscreen fullscreen; //!< The instruction what to do with it, when desktop enters fullscreen
|
||||||
|
|
||||||
/* derived fields */
|
/* derived fields */
|
||||||
char *msg; /**< formatted message */
|
char *msg; /**< formatted message */
|
||||||
@ -94,5 +102,14 @@ void notification_update_text_to_render(notification *n);
|
|||||||
void notification_do_action(notification *n);
|
void notification_do_action(notification *n);
|
||||||
|
|
||||||
const char *notification_urgency_to_string(enum urgency urgency);
|
const char *notification_urgency_to_string(enum urgency urgency);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the string representation for fullscreen behavior
|
||||||
|
*
|
||||||
|
* @param in the #behavior_fullscreen enum value to represent
|
||||||
|
* @return the string representation for `in`
|
||||||
|
*/
|
||||||
|
const char *enum_to_string_fullscreen(enum behavior_fullscreen in);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
||||||
|
@ -551,4 +551,22 @@ const char *cmdline_create_usage(void)
|
|||||||
return usage_str;
|
return usage_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* see option_parser.h */
|
||||||
|
enum behavior_fullscreen parse_enum_fullscreen(const char *string, enum behavior_fullscreen def)
|
||||||
|
{
|
||||||
|
if (!string)
|
||||||
|
return def;
|
||||||
|
|
||||||
|
if (strcmp(string, "show") == 0)
|
||||||
|
return FS_SHOW;
|
||||||
|
else if (strcmp(string, "delay") == 0)
|
||||||
|
return FS_DELAY;
|
||||||
|
else if (strcmp(string, "pushback") == 0)
|
||||||
|
return FS_PUSHBACK;
|
||||||
|
else {
|
||||||
|
LOG_W("Unknown fullscreen value: '%s'\n", string);
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "dunst.h"
|
||||||
|
|
||||||
int load_ini_file(FILE *);
|
int load_ini_file(FILE *);
|
||||||
char *ini_get_path(const char *section, const char *key, const char *def);
|
char *ini_get_path(const char *section, const char *key, const char *def);
|
||||||
char *ini_get_string(const char *section, const char *key, const char *def);
|
char *ini_get_string(const char *section, const char *key, const char *def);
|
||||||
@ -63,5 +65,17 @@ int option_get_bool(const char *ini_section,
|
|||||||
*/
|
*/
|
||||||
const char *next_section(const char *section);
|
const char *next_section(const char *section);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the fullscreen behavior value of the given string
|
||||||
|
*
|
||||||
|
* @param string the string representation of #behavior_fullscreen.
|
||||||
|
* The string must not contain any waste characters.
|
||||||
|
* @param def value to return in case of errors
|
||||||
|
*
|
||||||
|
* @return the #behavior_fullscreen representation of `string`
|
||||||
|
* @return `def` if `string` is invalid or `NULL`
|
||||||
|
*/
|
||||||
|
enum behavior_fullscreen parse_enum_fullscreen(const char *string, enum behavior_fullscreen def);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
||||||
|
40
src/queues.c
40
src/queues.c
@ -284,12 +284,14 @@ void queues_history_push_all(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* see queues.h */
|
/* see queues.h */
|
||||||
void queues_check_timeouts(bool idle)
|
void queues_check_timeouts(bool idle, bool fullscreen)
|
||||||
{
|
{
|
||||||
/* nothing to do */
|
/* nothing to do */
|
||||||
if (displayed->length == 0)
|
if (displayed->length == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
bool is_idle = fullscreen ? false : idle;
|
||||||
|
|
||||||
GList *iter = g_queue_peek_head_link(displayed);
|
GList *iter = g_queue_peek_head_link(displayed);
|
||||||
while (iter) {
|
while (iter) {
|
||||||
notification *n = iter->data;
|
notification *n = iter->data;
|
||||||
@ -302,7 +304,7 @@ void queues_check_timeouts(bool idle)
|
|||||||
iter = iter->next;
|
iter = iter->next;
|
||||||
|
|
||||||
/* don't timeout when user is idle */
|
/* don't timeout when user is idle */
|
||||||
if (idle && !n->transient) {
|
if (is_idle && !n->transient) {
|
||||||
n->start = g_get_monotonic_time();
|
n->start = g_get_monotonic_time();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -320,7 +322,7 @@ void queues_check_timeouts(bool idle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* see queues.h */
|
/* see queues.h */
|
||||||
void queues_update(void)
|
void queues_update(bool fullscreen)
|
||||||
{
|
{
|
||||||
if (pause_displayed) {
|
if (pause_displayed) {
|
||||||
while (displayed->length > 0) {
|
while (displayed->length > 0) {
|
||||||
@ -330,26 +332,52 @@ void queues_update(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* move notifications back to queue, which are set to pushback */
|
||||||
|
if (fullscreen) {
|
||||||
|
GList *iter = g_queue_peek_head_link(displayed);
|
||||||
|
while (iter) {
|
||||||
|
notification *n = iter->data;
|
||||||
|
GList *nextiter = iter->next;
|
||||||
|
|
||||||
|
if (n->fullscreen == FS_PUSHBACK){
|
||||||
|
g_queue_delete_link(displayed, iter);
|
||||||
|
g_queue_insert_sorted(waiting, n, notification_cmp_data, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
iter = nextiter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* move notifications from queue to displayed */
|
/* move notifications from queue to displayed */
|
||||||
while (waiting->length > 0) {
|
GList *iter = g_queue_peek_head_link(waiting);
|
||||||
|
while (iter) {
|
||||||
|
notification *n = iter->data;
|
||||||
|
GList *nextiter = iter->next;
|
||||||
|
|
||||||
if (displayed_limit > 0 && displayed->length >= displayed_limit) {
|
if (displayed_limit > 0 && displayed->length >= displayed_limit) {
|
||||||
/* the list is full */
|
/* the list is full */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
notification *n = g_queue_pop_head(waiting);
|
|
||||||
|
|
||||||
if (!n)
|
if (!n)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (fullscreen
|
||||||
|
&& (n->fullscreen == FS_DELAY || n->fullscreen == FS_PUSHBACK)) {
|
||||||
|
iter = nextiter;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
n->start = g_get_monotonic_time();
|
n->start = g_get_monotonic_time();
|
||||||
|
|
||||||
if (!n->redisplayed && n->script) {
|
if (!n->redisplayed && n->script) {
|
||||||
notification_run_script(n);
|
notification_run_script(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_queue_delete_link(waiting, iter);
|
||||||
g_queue_insert_sorted(displayed, n, notification_cmp_data, NULL);
|
g_queue_insert_sorted(displayed, n, notification_cmp_data, NULL);
|
||||||
|
|
||||||
|
iter = nextiter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,8 +125,10 @@ void queues_history_push_all(void);
|
|||||||
*
|
*
|
||||||
* @param idle the program's idle status. Important to calculate the
|
* @param idle the program's idle status. Important to calculate the
|
||||||
* timeout for transient notifications
|
* timeout for transient notifications
|
||||||
|
* @param fullscreen the desktop's fullscreen status. Important to
|
||||||
|
* calculate the timeout for transient notifications
|
||||||
*/
|
*/
|
||||||
void queues_check_timeouts(bool idle);
|
void queues_check_timeouts(bool idle, bool fullscreen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move inserted notifications from waiting queue to displayed queue
|
* Move inserted notifications from waiting queue to displayed queue
|
||||||
@ -135,8 +137,11 @@ void queues_check_timeouts(bool idle);
|
|||||||
*
|
*
|
||||||
* @post Call wake_up() to synchronize the queues with the UI
|
* @post Call wake_up() to synchronize the queues with the UI
|
||||||
* (which closes old and shows new notifications on screen)
|
* (which closes old and shows new notifications on screen)
|
||||||
|
*
|
||||||
|
* @param fullscreen the desktop's fullscreen status. Important to
|
||||||
|
* move notifications to the right queue
|
||||||
*/
|
*/
|
||||||
void queues_update(void);
|
void queues_update(bool fullscreen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the distance to the next event, when an element in the
|
* Calculate the distance to the next event, when an element in the
|
||||||
|
@ -16,6 +16,8 @@ void rule_apply(rule_t *r, notification *n)
|
|||||||
n->timeout = r->timeout;
|
n->timeout = r->timeout;
|
||||||
if (r->urgency != URG_NONE)
|
if (r->urgency != URG_NONE)
|
||||||
n->urgency = r->urgency;
|
n->urgency = r->urgency;
|
||||||
|
if (r->fullscreen != FS_NULL)
|
||||||
|
n->fullscreen = r->fullscreen;
|
||||||
if (r->history_ignore != -1)
|
if (r->history_ignore != -1)
|
||||||
n->history_ignore = r->history_ignore;
|
n->history_ignore = r->history_ignore;
|
||||||
if (r->set_transient != -1)
|
if (r->set_transient != -1)
|
||||||
@ -69,6 +71,7 @@ void rule_init(rule_t *r)
|
|||||||
r->msg_urgency = URG_NONE;
|
r->msg_urgency = URG_NONE;
|
||||||
r->timeout = -1;
|
r->timeout = -1;
|
||||||
r->urgency = URG_NONE;
|
r->urgency = URG_NONE;
|
||||||
|
r->fullscreen = FS_NULL;
|
||||||
r->markup = MARKUP_NULL;
|
r->markup = MARKUP_NULL;
|
||||||
r->new_icon = NULL;
|
r->new_icon = NULL;
|
||||||
r->history_ignore = false;
|
r->history_ignore = false;
|
||||||
|
@ -30,6 +30,7 @@ typedef struct _rule_t {
|
|||||||
char *bg;
|
char *bg;
|
||||||
const char *format;
|
const char *format;
|
||||||
const char *script;
|
const char *script;
|
||||||
|
enum behavior_fullscreen fullscreen;
|
||||||
} rule_t;
|
} rule_t;
|
||||||
|
|
||||||
extern GSList *rules;
|
extern GSList *rules;
|
||||||
|
@ -684,6 +684,15 @@ void load_settings(char *cmdline_config_path)
|
|||||||
r->history_ignore = ini_get_bool(cur_section, "history_ignore", r->history_ignore);
|
r->history_ignore = ini_get_bool(cur_section, "history_ignore", r->history_ignore);
|
||||||
r->match_transient = ini_get_bool(cur_section, "match_transient", r->match_transient);
|
r->match_transient = ini_get_bool(cur_section, "match_transient", r->match_transient);
|
||||||
r->set_transient = ini_get_bool(cur_section, "set_transient", r->set_transient);
|
r->set_transient = ini_get_bool(cur_section, "set_transient", r->set_transient);
|
||||||
|
{
|
||||||
|
char *c = ini_get_string(
|
||||||
|
cur_section,
|
||||||
|
"fullscreen", NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
r->fullscreen = parse_enum_fullscreen(c, r->fullscreen);
|
||||||
|
g_free(c);
|
||||||
|
}
|
||||||
r->script = ini_get_path(cur_section, "script", NULL);
|
r->script = ini_get_path(cur_section, "script", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,6 +146,8 @@ void screen_check_event(XEvent event)
|
|||||||
{
|
{
|
||||||
if (event.type == randr_event_base + RRScreenChangeNotify)
|
if (event.type == randr_event_base + RRScreenChangeNotify)
|
||||||
randr_update();
|
randr_update();
|
||||||
|
else
|
||||||
|
LOG_D("XEvent: Ignored '%d'", event.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void xinerama_update(void)
|
void xinerama_update(void)
|
||||||
@ -186,6 +188,89 @@ void screen_update_fallback(void)
|
|||||||
screens[0].dim.h = DisplayHeight(xctx.dpy, screen);
|
screens[0].dim.h = DisplayHeight(xctx.dpy, screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* see screen.h */
|
||||||
|
bool have_fullscreen_window(void)
|
||||||
|
{
|
||||||
|
return window_is_fullscreen(get_focused_window());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* X11 ErrorHandler to mainly discard BadWindow parameter error
|
||||||
|
*/
|
||||||
|
static int XErrorHandlerFullscreen(Display *display, XErrorEvent *e)
|
||||||
|
{
|
||||||
|
/* Ignore BadWindow errors. Window may have been gone */
|
||||||
|
if (e->error_code == BadWindow) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char err_buf[BUFSIZ];
|
||||||
|
XGetErrorText(display, e->error_code, err_buf, BUFSIZ);
|
||||||
|
fputs(err_buf, stderr);
|
||||||
|
fputs("\n", stderr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* see screen.h */
|
||||||
|
bool window_is_fullscreen(Window window)
|
||||||
|
{
|
||||||
|
bool fs = false;
|
||||||
|
|
||||||
|
if (!window)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Atom has_wm_state = XInternAtom(xctx.dpy, "_NET_WM_STATE", True);
|
||||||
|
if (has_wm_state == None){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
XFlush(xctx.dpy);
|
||||||
|
XSetErrorHandler(XErrorHandlerFullscreen);
|
||||||
|
|
||||||
|
Atom actual_type_return;
|
||||||
|
int actual_format_return;
|
||||||
|
unsigned long bytes_after_return;
|
||||||
|
unsigned char *prop_to_return;
|
||||||
|
unsigned long n_items;
|
||||||
|
int result = XGetWindowProperty(
|
||||||
|
xctx.dpy,
|
||||||
|
window,
|
||||||
|
has_wm_state,
|
||||||
|
0, /* long_offset */
|
||||||
|
sizeof(window), /* long_length */
|
||||||
|
false, /* delete */
|
||||||
|
AnyPropertyType, /* req_type */
|
||||||
|
&actual_type_return,
|
||||||
|
&actual_format_return,
|
||||||
|
&n_items,
|
||||||
|
&bytes_after_return,
|
||||||
|
&prop_to_return);
|
||||||
|
|
||||||
|
XFlush(xctx.dpy);
|
||||||
|
XSync(xctx.dpy, false);
|
||||||
|
XSetErrorHandler(NULL);
|
||||||
|
|
||||||
|
if (result == Success) {
|
||||||
|
for(int i = 0; i < n_items; i++) {
|
||||||
|
char *atom = XGetAtomName(xctx.dpy, ((Atom*)prop_to_return)[i]);
|
||||||
|
|
||||||
|
if (atom) {
|
||||||
|
if(0 == strcmp("_NET_WM_STATE_FULLSCREEN", atom))
|
||||||
|
fs = true;
|
||||||
|
XFree(atom);
|
||||||
|
if(fs)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prop_to_return)
|
||||||
|
XFree(prop_to_return);
|
||||||
|
|
||||||
|
return fs;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Select the screen on which the Window
|
* Select the screen on which the Window
|
||||||
* should be displayed.
|
* should be displayed.
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#define DUNST_SCREEN_H
|
#define DUNST_SCREEN_H
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#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))
|
||||||
|
|
||||||
@ -27,5 +28,24 @@ void screen_check_event(XEvent event);
|
|||||||
screen_info *get_active_screen(void);
|
screen_info *get_active_screen(void);
|
||||||
double get_dpi_for_screen(screen_info *scr);
|
double get_dpi_for_screen(screen_info *scr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the currently focused window and check if it's in
|
||||||
|
* fullscreen mode
|
||||||
|
*
|
||||||
|
* @see window_is_fullscreen()
|
||||||
|
* @see get_focused_window()
|
||||||
|
*
|
||||||
|
* @return `true` if the focused window is in fullscreen mode
|
||||||
|
*/
|
||||||
|
bool have_fullscreen_window(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if window is in fullscreen mode
|
||||||
|
*
|
||||||
|
* @param window the x11 window object
|
||||||
|
* @return `true` if `window` is in fullscreen mode
|
||||||
|
*/
|
||||||
|
bool window_is_fullscreen(Window window);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
||||||
|
17
src/x11/x.c
17
src/x11/x.c
@ -60,6 +60,7 @@ typedef struct _colored_layout {
|
|||||||
} colored_layout;
|
} colored_layout;
|
||||||
|
|
||||||
cairo_ctx_t cairo_ctx;
|
cairo_ctx_t cairo_ctx;
|
||||||
|
static bool fullscreen_last = false;
|
||||||
|
|
||||||
/* FIXME refactor setup teardown handlers into one setup and one teardown */
|
/* FIXME refactor setup teardown handlers into one setup and one teardown */
|
||||||
static void x_shortcut_setup_error_handler(void);
|
static void x_shortcut_setup_error_handler(void);
|
||||||
@ -848,10 +849,13 @@ gboolean x_mainloop_fd_check(GSource *source)
|
|||||||
*/
|
*/
|
||||||
gboolean x_mainloop_fd_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
|
gboolean x_mainloop_fd_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
|
||||||
{
|
{
|
||||||
|
bool fullscreen_now;
|
||||||
XEvent ev;
|
XEvent ev;
|
||||||
unsigned int state;
|
unsigned int state;
|
||||||
while (XPending(xctx.dpy) > 0) {
|
while (XPending(xctx.dpy) > 0) {
|
||||||
XNextEvent(xctx.dpy, &ev);
|
XNextEvent(xctx.dpy, &ev);
|
||||||
|
LOG_D("XEvent: processing '%d'", ev.type);
|
||||||
|
|
||||||
switch (ev.type) {
|
switch (ev.type) {
|
||||||
case Expose:
|
case Expose:
|
||||||
if (ev.xexpose.count == 0 && xctx.visible) {
|
if (ev.xexpose.count == 0 && xctx.visible) {
|
||||||
@ -908,13 +912,20 @@ gboolean x_mainloop_fd_dispatch(GSource *source, GSourceFunc callback, gpointer
|
|||||||
wake_up();
|
wake_up();
|
||||||
break;
|
break;
|
||||||
case PropertyNotify:
|
case PropertyNotify:
|
||||||
|
fullscreen_now = have_fullscreen_window();
|
||||||
|
|
||||||
|
if (fullscreen_now != fullscreen_last) {
|
||||||
|
fullscreen_last = fullscreen_now;
|
||||||
|
wake_up();
|
||||||
|
} else if ( settings.f_mode != FOLLOW_NONE
|
||||||
/* Ignore PropertyNotify, when we're still on the
|
/* Ignore PropertyNotify, when we're still on the
|
||||||
* same screen. PropertyNotify is only neccessary
|
* same screen. PropertyNotify is only neccessary
|
||||||
* to detect a focus change to another screen
|
* to detect a focus change to another screen
|
||||||
*/
|
*/
|
||||||
if( settings.f_mode != FOLLOW_NONE
|
&& xctx.visible
|
||||||
&& get_active_screen()->scr != xctx.cur_screen)
|
&& get_active_screen()->scr != xctx.cur_screen) {
|
||||||
wake_up();
|
x_win_draw();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
screen_check_event(ev);
|
screen_check_event(ev);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user