mirror of
https://github.com/ErikReider/SwayNotificationCenter.git
synced 2024-11-22 09:43:52 +03:00
[Feature] Click outside Control Center to close (#133)
* Initial implementation * Fixed linter errors * Fixed Ubuntu build error * Added comment to .blank-window css class, formatted file with prettier * Use packaged css file as backup
This commit is contained in:
parent
8a96948e1b
commit
8425afbfa8
55
src/blankWindow/blankWindow.vala
Normal file
55
src/blankWindow/blankWindow.vala
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
namespace SwayNotificationCenter {
|
||||||
|
public class BlankWindow : Gtk.Window {
|
||||||
|
unowned Gdk.Display display;
|
||||||
|
unowned Gdk.Monitor monitor;
|
||||||
|
unowned SwayncDaemon daemon;
|
||||||
|
|
||||||
|
Gtk.Button button;
|
||||||
|
|
||||||
|
public BlankWindow (Gdk.Display disp,
|
||||||
|
Gdk.Monitor mon,
|
||||||
|
SwayncDaemon dae) {
|
||||||
|
display = disp;
|
||||||
|
monitor = mon;
|
||||||
|
daemon = dae;
|
||||||
|
|
||||||
|
// Use button click event instead of Window button_press_event due
|
||||||
|
// to Gtk layer shell bug. This would grab focus instead of ControlCenter
|
||||||
|
button = new Gtk.Button () {
|
||||||
|
expand = true,
|
||||||
|
opacity = 0,
|
||||||
|
relief = Gtk.ReliefStyle.NONE,
|
||||||
|
visible = true,
|
||||||
|
};
|
||||||
|
button.clicked.connect (() => {
|
||||||
|
try {
|
||||||
|
daemon.set_visibility (false);
|
||||||
|
} catch (Error e) {
|
||||||
|
stderr.printf ("BlankWindow Click Error: %s\n", e.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
add (button);
|
||||||
|
|
||||||
|
if (!GtkLayerShell.is_supported ()) {
|
||||||
|
stderr.printf ("GTKLAYERSHELL IS NOT SUPPORTED!\n");
|
||||||
|
stderr.printf ("Swaync only works on Wayland!\n");
|
||||||
|
stderr.printf ("If running waylans session, try running:\n");
|
||||||
|
stderr.printf ("\tGDK_BACKEND=wayland swaync\n");
|
||||||
|
Process.exit (1);
|
||||||
|
}
|
||||||
|
GtkLayerShell.init_for_window (this);
|
||||||
|
GtkLayerShell.set_monitor (this, monitor);
|
||||||
|
|
||||||
|
GtkLayerShell.set_anchor (this, GtkLayerShell.Edge.TOP, true);
|
||||||
|
GtkLayerShell.set_anchor (this, GtkLayerShell.Edge.BOTTOM, true);
|
||||||
|
GtkLayerShell.set_anchor (this, GtkLayerShell.Edge.LEFT, true);
|
||||||
|
GtkLayerShell.set_anchor (this, GtkLayerShell.Edge.RIGHT, true);
|
||||||
|
|
||||||
|
GtkLayerShell.set_exclusive_zone (this, -1);
|
||||||
|
|
||||||
|
GtkLayerShell.set_layer (this, GtkLayerShell.Layer.TOP);
|
||||||
|
|
||||||
|
get_style_context ().add_class ("blank-window");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -275,6 +275,7 @@ namespace SwayNotificationCenter {
|
|||||||
if (noti != null) noti.set_time ();
|
if (noti != null) noti.set_time ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
swaync_daemon.set_blank_window_visibility (this.visible);
|
||||||
swaync_daemon.subscribe (notification_count (),
|
swaync_daemon.subscribe (notification_count (),
|
||||||
noti_daemon.dnd,
|
noti_daemon.dnd,
|
||||||
this.visible);
|
this.visible);
|
||||||
|
@ -1,5 +1,15 @@
|
|||||||
namespace SwayNotificationCenter {
|
namespace SwayNotificationCenter {
|
||||||
public class Functions {
|
public class Functions {
|
||||||
|
private static Gtk.CssProvider system_css_provider;
|
||||||
|
private static Gtk.CssProvider user_css_provider;
|
||||||
|
|
||||||
|
private Functions () {}
|
||||||
|
|
||||||
|
public static void init () {
|
||||||
|
system_css_provider = new Gtk.CssProvider ();
|
||||||
|
user_css_provider = new Gtk.CssProvider ();
|
||||||
|
}
|
||||||
|
|
||||||
public static void set_image_path (owned string path,
|
public static void set_image_path (owned string path,
|
||||||
Gtk.Image img,
|
Gtk.Image img,
|
||||||
int icon_size,
|
int icon_size,
|
||||||
@ -55,29 +65,45 @@ namespace SwayNotificationCenter {
|
|||||||
img.set_from_surface (surface);
|
img.set_from_surface (surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Load the package provided CSS file as a base.
|
||||||
|
* Without this, an empty user CSS file would result in widgets
|
||||||
|
* with default GTK style properties
|
||||||
|
*/
|
||||||
public static bool load_css (string ? style_path) {
|
public static bool load_css (string ? style_path) {
|
||||||
try {
|
try {
|
||||||
Gtk.CssProvider css_provider = new Gtk.CssProvider ();
|
// Load packaged CSS as backup
|
||||||
css_provider.load_from_path (get_style_path (style_path));
|
string system_css = get_style_path (null, true);
|
||||||
|
system_css_provider.load_from_path (system_css);
|
||||||
Gtk.StyleContext.add_provider_for_screen (
|
Gtk.StyleContext.add_provider_for_screen (
|
||||||
Gdk.Screen.get_default (),
|
Gdk.Screen.get_default (),
|
||||||
css_provider,
|
system_css_provider,
|
||||||
|
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||||
|
|
||||||
|
// Load user CSS
|
||||||
|
string user_css = get_style_path (style_path);
|
||||||
|
user_css_provider.load_from_path (user_css);
|
||||||
|
Gtk.StyleContext.add_provider_for_screen (
|
||||||
|
Gdk.Screen.get_default (),
|
||||||
|
user_css_provider,
|
||||||
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
|
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||||
return true;
|
return true;
|
||||||
} catch (Error e) {
|
} catch (Error e) {
|
||||||
print ("Error: %s\n", e.message);
|
print ("Load CSS Error: %s\n", e.message);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string get_style_path (string ? custom_path) {
|
public static string get_style_path (string ? custom_path,
|
||||||
|
bool only_system = false) {
|
||||||
string[] paths = {};
|
string[] paths = {};
|
||||||
if (custom_path != null && custom_path.length > 0) {
|
if (custom_path != null && custom_path.length > 0) {
|
||||||
paths += custom_path;
|
paths += custom_path;
|
||||||
}
|
}
|
||||||
paths += Path.build_path (Path.DIR_SEPARATOR.to_string (),
|
if (!only_system) {
|
||||||
GLib.Environment.get_user_config_dir (),
|
paths += Path.build_path (Path.DIR_SEPARATOR.to_string (),
|
||||||
"swaync/style.css");
|
GLib.Environment.get_user_config_dir (),
|
||||||
|
"swaync/style.css");
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var path in GLib.Environment.get_system_config_dirs ()) {
|
foreach (var path in GLib.Environment.get_system_config_dirs ()) {
|
||||||
paths += Path.build_path (Path.DIR_SEPARATOR.to_string (),
|
paths += Path.build_path (Path.DIR_SEPARATOR.to_string (),
|
||||||
|
@ -6,6 +6,7 @@ namespace SwayNotificationCenter {
|
|||||||
public void main (string[] args) {
|
public void main (string[] args) {
|
||||||
Gtk.init (ref args);
|
Gtk.init (ref args);
|
||||||
Hdy.init ();
|
Hdy.init ();
|
||||||
|
Functions.init ();
|
||||||
|
|
||||||
if (args.length > 0) {
|
if (args.length > 0) {
|
||||||
for (uint i = 1; i < args.length; i++) {
|
for (uint i = 1; i < args.length; i++) {
|
||||||
|
@ -33,6 +33,7 @@ app_sources = [
|
|||||||
'controlCenter/controlCenter.vala',
|
'controlCenter/controlCenter.vala',
|
||||||
'controlCenter/topAction/topAction.vala',
|
'controlCenter/topAction/topAction.vala',
|
||||||
'cacher/cacher.vala',
|
'cacher/cacher.vala',
|
||||||
|
'blankWindow/blankWindow.vala',
|
||||||
'functions.vala',
|
'functions.vala',
|
||||||
constants,
|
constants,
|
||||||
]
|
]
|
||||||
|
@ -25,8 +25,7 @@
|
|||||||
.notification {
|
.notification {
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
margin: 6px 12px;
|
margin: 6px 12px;
|
||||||
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3),
|
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3), 0 1px 3px 1px rgba(0, 0, 0, 0.7),
|
||||||
0 1px 3px 1px rgba(0, 0, 0, 0.7),
|
|
||||||
0 2px 6px 2px rgba(0, 0, 0, 0.3);
|
0 2px 6px 2px rgba(0, 0, 0, 0.3);
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
@ -120,7 +119,8 @@
|
|||||||
border-right: 1px solid @noti-border-color;
|
border-right: 1px solid @noti-border-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.image {}
|
.image {
|
||||||
|
}
|
||||||
|
|
||||||
.body-image {
|
.body-image {
|
||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
@ -191,3 +191,8 @@
|
|||||||
.floating-notifications {
|
.floating-notifications {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Window behind control center and on all other monitors */
|
||||||
|
.blank-window {
|
||||||
|
background: alpha(black, 0.25);
|
||||||
|
}
|
||||||
|
@ -11,6 +11,9 @@ namespace SwayNotificationCenter {
|
|||||||
|
|
||||||
public NotiDaemon noti_daemon;
|
public NotiDaemon noti_daemon;
|
||||||
|
|
||||||
|
private Array<BlankWindow> blank_windows = new Array<BlankWindow> ();
|
||||||
|
private unowned Gdk.Display ? display = Gdk.Display.get_default ();
|
||||||
|
|
||||||
public SwayncDaemon () {
|
public SwayncDaemon () {
|
||||||
this.cache_state = Cacher.instance.get_state_cache ();
|
this.cache_state = Cacher.instance.get_state_cache ();
|
||||||
this.cache_state.notify.connect ((x, r) => {
|
this.cache_state.notify.connect ((x, r) => {
|
||||||
@ -51,6 +54,31 @@ namespace SwayNotificationCenter {
|
|||||||
} catch (Error e) {
|
} catch (Error e) {
|
||||||
stderr.printf (e.message + "\n");
|
stderr.printf (e.message + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Blank windows
|
||||||
|
|
||||||
|
if (display == null) return;
|
||||||
|
init_blank_windows (false);
|
||||||
|
|
||||||
|
display.closed.connect ((is_error) => {
|
||||||
|
clear_blank_windows ();
|
||||||
|
if (is_error) stderr.printf ("Display closed due to error!\n");
|
||||||
|
});
|
||||||
|
|
||||||
|
display.opened.connect ((d) => {
|
||||||
|
bool visibility = noti_daemon.control_center.get_visibility ();
|
||||||
|
init_blank_windows (visibility);
|
||||||
|
});
|
||||||
|
|
||||||
|
display.monitor_added.connect ((d, m) => {
|
||||||
|
bool visibility = noti_daemon.control_center.get_visibility ();
|
||||||
|
add_blank_window (d, m, visibility);
|
||||||
|
});
|
||||||
|
|
||||||
|
display.monitor_removed.connect ((monitor) => {
|
||||||
|
bool visibility = noti_daemon.control_center.get_visibility ();
|
||||||
|
init_blank_windows (visibility);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void on_noti_bus_aquired (DBusConnection conn) {
|
private void on_noti_bus_aquired (DBusConnection conn) {
|
||||||
@ -63,6 +91,42 @@ namespace SwayNotificationCenter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void add_blank_window (Gdk.Display display,
|
||||||
|
Gdk.Monitor monitor,
|
||||||
|
bool visible) {
|
||||||
|
var win = new BlankWindow (display, monitor, this);
|
||||||
|
win.set_visible (visible);
|
||||||
|
blank_windows.append_val (win);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init_blank_windows (bool visible) {
|
||||||
|
clear_blank_windows ();
|
||||||
|
// Add a window to all monitors
|
||||||
|
for (int i = 0; i < display.get_n_monitors (); i++) {
|
||||||
|
unowned Gdk.Monitor ? monitor = display.get_monitor (i);
|
||||||
|
if (monitor == null) continue;
|
||||||
|
add_blank_window (display, monitor, visible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clear_blank_windows () {
|
||||||
|
while (blank_windows.length > 0) {
|
||||||
|
uint i = blank_windows.length - 1;
|
||||||
|
unowned BlankWindow ? win = blank_windows.index (i);
|
||||||
|
win.close ();
|
||||||
|
blank_windows.remove_index (i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[DBus (visible = false)]
|
||||||
|
public void set_blank_window_visibility (bool visibility) {
|
||||||
|
foreach (unowned BlankWindow win in blank_windows.data) {
|
||||||
|
win.set_visible (visibility);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// DBus
|
||||||
|
|
||||||
/** Gets subscribe data but in one call */
|
/** Gets subscribe data but in one call */
|
||||||
[DBus (name = "GetSubscribeData")]
|
[DBus (name = "GetSubscribeData")]
|
||||||
public Data get_subscribe_data () throws Error {
|
public Data get_subscribe_data () throws Error {
|
||||||
|
Loading…
Reference in New Issue
Block a user