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 ();
|
||||
}
|
||||
}
|
||||
swaync_daemon.set_blank_window_visibility (this.visible);
|
||||
swaync_daemon.subscribe (notification_count (),
|
||||
noti_daemon.dnd,
|
||||
this.visible);
|
||||
|
@ -1,5 +1,15 @@
|
||||
namespace SwayNotificationCenter {
|
||||
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,
|
||||
Gtk.Image img,
|
||||
int icon_size,
|
||||
@ -55,29 +65,45 @@ namespace SwayNotificationCenter {
|
||||
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) {
|
||||
try {
|
||||
Gtk.CssProvider css_provider = new Gtk.CssProvider ();
|
||||
css_provider.load_from_path (get_style_path (style_path));
|
||||
// Load packaged CSS as backup
|
||||
string system_css = get_style_path (null, true);
|
||||
system_css_provider.load_from_path (system_css);
|
||||
Gtk.StyleContext.add_provider_for_screen (
|
||||
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);
|
||||
return true;
|
||||
} 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 = {};
|
||||
if (custom_path != null && custom_path.length > 0) {
|
||||
paths += custom_path;
|
||||
}
|
||||
paths += Path.build_path (Path.DIR_SEPARATOR.to_string (),
|
||||
GLib.Environment.get_user_config_dir (),
|
||||
"swaync/style.css");
|
||||
if (!only_system) {
|
||||
paths += Path.build_path (Path.DIR_SEPARATOR.to_string (),
|
||||
GLib.Environment.get_user_config_dir (),
|
||||
"swaync/style.css");
|
||||
}
|
||||
|
||||
foreach (var path in GLib.Environment.get_system_config_dirs ()) {
|
||||
paths += Path.build_path (Path.DIR_SEPARATOR.to_string (),
|
||||
|
@ -6,6 +6,7 @@ namespace SwayNotificationCenter {
|
||||
public void main (string[] args) {
|
||||
Gtk.init (ref args);
|
||||
Hdy.init ();
|
||||
Functions.init ();
|
||||
|
||||
if (args.length > 0) {
|
||||
for (uint i = 1; i < args.length; i++) {
|
||||
|
@ -33,6 +33,7 @@ app_sources = [
|
||||
'controlCenter/controlCenter.vala',
|
||||
'controlCenter/topAction/topAction.vala',
|
||||
'cacher/cacher.vala',
|
||||
'blankWindow/blankWindow.vala',
|
||||
'functions.vala',
|
||||
constants,
|
||||
]
|
||||
|
@ -25,8 +25,7 @@
|
||||
.notification {
|
||||
border-radius: 12px;
|
||||
margin: 6px 12px;
|
||||
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3),
|
||||
0 1px 3px 1px rgba(0, 0, 0, 0.7),
|
||||
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3), 0 1px 3px 1px rgba(0, 0, 0, 0.7),
|
||||
0 2px 6px 2px rgba(0, 0, 0, 0.3);
|
||||
padding: 0;
|
||||
}
|
||||
@ -120,7 +119,8 @@
|
||||
border-right: 1px solid @noti-border-color;
|
||||
}
|
||||
|
||||
.image {}
|
||||
.image {
|
||||
}
|
||||
|
||||
.body-image {
|
||||
margin-top: 6px;
|
||||
@ -191,3 +191,8 @@
|
||||
.floating-notifications {
|
||||
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;
|
||||
|
||||
private Array<BlankWindow> blank_windows = new Array<BlankWindow> ();
|
||||
private unowned Gdk.Display ? display = Gdk.Display.get_default ();
|
||||
|
||||
public SwayncDaemon () {
|
||||
this.cache_state = Cacher.instance.get_state_cache ();
|
||||
this.cache_state.notify.connect ((x, r) => {
|
||||
@ -51,6 +54,31 @@ namespace SwayNotificationCenter {
|
||||
} catch (Error e) {
|
||||
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) {
|
||||
@ -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 */
|
||||
[DBus (name = "GetSubscribeData")]
|
||||
public Data get_subscribe_data () throws Error {
|
||||
|
Loading…
Reference in New Issue
Block a user