Fixed click to close Control Center not working on some WMs (#139)

This commit is contained in:
Erik Reider
2022-06-29 22:55:56 +02:00
committed by GitHub
parent c8c10dff08
commit 04e59cbc41
5 changed files with 96 additions and 56 deletions

View File

@@ -1,7 +1,7 @@
namespace SwayNotificationCenter { namespace SwayNotificationCenter {
public class BlankWindow : Gtk.Window { public class BlankWindow : Gtk.Window {
unowned Gdk.Display display; public unowned Gdk.Display display { get; private set; }
unowned Gdk.Monitor monitor; public unowned Gdk.Monitor monitor { get; private set; }
unowned SwayncDaemon daemon; unowned SwayncDaemon daemon;
Gtk.Button button; Gtk.Button button;

View File

@@ -3,6 +3,7 @@
<interface> <interface>
<requires lib="gtk+" version="3.24"/> <requires lib="gtk+" version="3.24"/>
<template class="SwayNotificationCenterControlCenter" parent="GtkApplicationWindow"> <template class="SwayNotificationCenterControlCenter" parent="GtkApplicationWindow">
<property name="name">control-center-window</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="resizable">False</property> <property name="resizable">False</property>
<property name="skip-taskbar-hint">True</property> <property name="skip-taskbar-hint">True</property>
@@ -16,6 +17,7 @@
<object class="GtkBox" id="box"> <object class="GtkBox" id="box">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="vexpand">True</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="GtkScrolledWindow" id="scrolled_window"> <object class="GtkScrolledWindow" id="scrolled_window">
@@ -50,10 +52,13 @@
<property name="position">2</property> <property name="position">2</property>
</packing> </packing>
</child> </child>
<style>
<class name="control-center"/>
</style>
</object> </object>
</child> </child>
<style> <style>
<class name="control-center"/> <class name="blank-window"/>
</style> </style>
</template> </template>
</interface> </interface>

View File

@@ -35,10 +35,31 @@ namespace SwayNotificationCenter {
Process.exit (1); Process.exit (1);
} }
GtkLayerShell.init_for_window (this); GtkLayerShell.init_for_window (this);
this.set_anchor (); GtkLayerShell.set_anchor (this, GtkLayerShell.Edge.TOP, true);
GtkLayerShell.set_anchor (this, GtkLayerShell.Edge.LEFT, true);
GtkLayerShell.set_anchor (this, GtkLayerShell.Edge.RIGHT, true);
GtkLayerShell.set_anchor (this, GtkLayerShell.Edge.BOTTOM, true);
viewport.size_allocate.connect (size_alloc); viewport.size_allocate.connect (size_alloc);
this.map.connect (set_anchor);
this.map.connect (() => {
set_anchor ();
// Wait until the layer has attached
ulong id = 0;
id = notify["has-toplevel-focus"].connect (() => {
disconnect (id);
unowned Gdk.Monitor monitor = null;
unowned Gdk.Window ? win = get_window ();
if (win != null) {
monitor = get_display ().get_monitor_at_window (win);
}
swaync_daemon.show_blank_windows (monitor);
});
});
this.unmap.connect (swaync_daemon.hide_blank_windows);
this.button_press_event.connect (blank_window_press);
this.touch_event.connect (blank_window_press);
// Only use release for closing notifications due to Escape key // Only use release for closing notifications due to Escape key
// sometimes being passed through to unfucused application // sometimes being passed through to unfucused application
@@ -134,6 +155,26 @@ namespace SwayNotificationCenter {
this.box.add (new TopAction ("Do Not Disturb", dnd_button, false)); this.box.add (new TopAction ("Do Not Disturb", dnd_button, false));
} }
private bool blank_window_press (Gdk.Event event) {
// Calculate if the clicked coords intersect the ControlCenter
double x, y;
event.get_coords (out x, out y);
Gdk.Rectangle click_rectangle = Gdk.Rectangle () {
width = 1,
height = 1,
x = (int) x,
y = (int) y,
};
if (box.intersect (click_rectangle, null)) return true;
try {
swaync_daemon.set_visibility (false);
} catch (Error e) {
stderr.printf ("ControlCenter BlankWindow Click Error: %s\n",
e.message);
}
return true;
}
/** Resets the UI positions */ /** Resets the UI positions */
private void set_anchor () { private void set_anchor () {
// Grabs the keyboard input until closed // Grabs the keyboard input until closed
@@ -148,51 +189,49 @@ namespace SwayNotificationCenter {
#endif #endif
GtkLayerShell.set_layer (this, GtkLayerShell.Layer.TOP); GtkLayerShell.set_layer (this, GtkLayerShell.Layer.TOP);
GtkLayerShell.set_margin (this, // Set the box margins
GtkLayerShell.Edge.TOP, box.set_margin_top (ConfigModel.instance.control_center_margin_top);
ConfigModel.instance.control_center_margin_top); box.set_margin_start (ConfigModel.instance.control_center_margin_left);
GtkLayerShell.set_margin (this, box.set_margin_end (ConfigModel.instance.control_center_margin_right);
GtkLayerShell.Edge.BOTTOM, box.set_margin_bottom (ConfigModel.instance.control_center_margin_bottom);
ConfigModel.instance.control_center_margin_bottom);
GtkLayerShell.set_margin (this,
GtkLayerShell.Edge.RIGHT,
ConfigModel.instance.control_center_margin_right);
GtkLayerShell.set_margin (this,
GtkLayerShell.Edge.LEFT,
ConfigModel.instance.control_center_margin_left);
// Anchor to north/south edges as needed // Anchor box to north/south edges as needed
bool anchor_top = ConfigModel.instance.positionY == PositionY.TOP; Gtk.Align align_x = Gtk.Align.END;
GtkLayerShell.set_anchor (this, switch (ConfigModel.instance.positionX) {
GtkLayerShell.Edge.TOP, case PositionX.LEFT:
ConfigModel.instance.fit_to_screen || anchor_top); align_x = Gtk.Align.START;
GtkLayerShell.set_anchor (this,
GtkLayerShell.Edge.BOTTOM,
ConfigModel.instance.fit_to_screen || !anchor_top);
bool anchor_left = ConfigModel.instance.positionX == PositionX.LEFT;
bool anchor_right = ConfigModel.instance.positionX == PositionX.RIGHT;
GtkLayerShell.set_anchor (this,
GtkLayerShell.Edge.RIGHT,
anchor_right);
GtkLayerShell.set_anchor (this,
GtkLayerShell.Edge.LEFT,
anchor_left);
switch (ConfigModel.instance.positionY) {
case PositionY.BOTTOM:
list_reverse = true;
list_align = Gtk.Align.END;
this.box.set_child_packing (
scrolled_window, true, true, 0, Gtk.PackType.START);
break; break;
case PositionX.CENTER:
align_x = Gtk.Align.CENTER;
break;
case PositionX.RIGHT:
align_x = Gtk.Align.END;
break;
}
Gtk.Align align_y = Gtk.Align.START;
switch (ConfigModel.instance.positionY) {
case PositionY.TOP: case PositionY.TOP:
align_y = Gtk.Align.START;
// Set cc widget position
list_reverse = false; list_reverse = false;
list_align = Gtk.Align.START; list_align = Gtk.Align.START;
this.box.set_child_packing ( this.box.set_child_packing (
scrolled_window, true, true, 0, Gtk.PackType.END); scrolled_window, true, true, 0, Gtk.PackType.END);
break; break;
case PositionY.BOTTOM:
align_y = Gtk.Align.END;
// Set cc widget position
list_reverse = true;
list_align = Gtk.Align.END;
this.box.set_child_packing (
scrolled_window, true, true, 0, Gtk.PackType.START);
break;
} }
// Fit the ControlCenter to the monitor height
if (ConfigModel.instance.fit_to_screen) align_y = Gtk.Align.FILL;
// Set the ControlCenter alignment
box.set_halign (align_x);
box.set_valign (align_y);
list_box.set_valign (list_align); list_box.set_valign (list_align);
list_box.set_sort_func ((w1, w2) => { list_box.set_sort_func ((w1, w2) => {
@@ -206,9 +245,8 @@ namespace SwayNotificationCenter {
}); });
// Always set the size request in all events. // Always set the size request in all events.
int configured_width = ConfigModel.instance.control_center_width; box.set_size_request (ConfigModel.instance.control_center_width,
int configured_height = ConfigModel.instance.control_center_height; ConfigModel.instance.control_center_height);
this.set_size_request (configured_width, configured_height);
} }
private void size_alloc () { private void size_alloc () {
@@ -261,8 +299,6 @@ namespace SwayNotificationCenter {
private void on_visibility_change () { private void on_visibility_change () {
if (this.visible) { if (this.visible) {
// Reload the settings from config
this.set_anchor ();
// Focus the first notification // Focus the first notification
list_position = list_reverse ? list_position = list_reverse ?
(list_box.get_children ().length () - 1) : 0; (list_box.get_children ().length () - 1) : 0;
@@ -275,7 +311,6 @@ 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);

View File

@@ -180,17 +180,10 @@
border-radius: 12px; border-radius: 12px;
} }
/* The .control-center Window.
* Can't apply padding and margin so may be easier to use "> box" instead
*/
.control-center { .control-center {
background: @cc-bg; background: @cc-bg;
} }
/* The first control-center child. May be easier to style this than .control-center */
.control-center > box {
}
.control-center-list { .control-center-list {
background: transparent; background: transparent;
} }

View File

@@ -111,9 +111,16 @@ namespace SwayNotificationCenter {
} }
[DBus (visible = false)] [DBus (visible = false)]
public void set_blank_window_visibility (bool visibility) { public void show_blank_windows (Gdk.Monitor? monitor) {
foreach (unowned BlankWindow win in blank_windows.data) { foreach (unowned BlankWindow win in blank_windows.data) {
win.set_visible (visibility); if (win.monitor != monitor) win.show ();
}
}
[DBus (visible = false)]
public void hide_blank_windows () {
foreach (unowned BlankWindow win in blank_windows.data) {
win.hide ();
} }
} }