Skip to content

Commit

Permalink
Add support for multiple monitors and workspaces
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielfin authored and flexiondotorg committed Mar 4, 2021
1 parent 5bc45f7 commit a70fcdf
Show file tree
Hide file tree
Showing 3 changed files with 201 additions and 98 deletions.
99 changes: 66 additions & 33 deletions window-buttons-applet/window-buttons-applet.vala
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ namespace WindowButtonsApplet{
bool maximize ;
}

public Gdk.Monitor monitor;
private Wnck.Window* window = null;
private Wnck.Window *active_window = null;
private Gdk.Monitor active_window_monitor;

public GLib.Settings gsettings = new GLib.Settings("org.mate.window-applets.window-buttons");
public GLib.Settings marco_gsettings = new GLib.Settings("org.mate.Marco.general");
Expand Down Expand Up @@ -91,9 +93,10 @@ namespace WindowButtonsApplet{
window->state_changed.disconnect(reload);
}

if(active_window != null)
if(active_window != null){
active_window->state_changed.disconnect(reload);

active_window->geometry_changed.disconnect(detect_monitor_change);
}

window = get_current_window();

Expand All @@ -105,11 +108,15 @@ namespace WindowButtonsApplet{
window->state_changed.connect(reload);
}

// When active window is not the controlled window (because it is unmaximized),
// we need to watch its state as well
active_window = Wnck.Screen.get_default().get_active_window();
if(active_window != null && active_window != window)
active_window->state_changed.connect(reload);
if(active_window != null){
// When active window is not the controlled window (because it is unmaximized),
// we need to watch its state as well
if(active_window != window)
active_window->state_changed.connect(reload);

active_window->geometry_changed.connect(detect_monitor_change);
}
}

public void change_layout(){
Expand Down Expand Up @@ -216,38 +223,62 @@ namespace WindowButtonsApplet{
Wnck.Screen.get_default().window_closed.connect( reload );
}

private Wnck.Window get_current_window(){
Wnck.Window* win = null;
private Wnck.Window? get_current_window(){
Wnck.WindowType window_type;
string behaviour = gsettings.get_string("behaviour");
Wnck.Workspace active_workspace = Wnck.Screen.get_default().get_active_workspace();

List<weak Wnck.Window> windows = Wnck.Screen.get_default().get_windows_stacked().copy();
windows.reverse();

foreach(Wnck.Window* win in windows) {
window_type = win->get_window_type();
if(window_type == Wnck.WindowType.DESKTOP || window_type == Wnck.WindowType.DOCK)
continue;

if(win->is_minimized())
continue;

if(!win->is_on_workspace(active_workspace))
continue;

if(monitor != get_monitor_at_window(win))
continue;

switch(behaviour){
case "active-always":
return win;

switch(behaviour){
case "active-always":
win = Wnck.Screen.get_default().get_active_window();
if(win != null){
window_type = win->get_window_type();
if(window_type == Wnck.WindowType.DESKTOP || window_type == Wnck.WindowType.DOCK)
win = null;
}
break;
case "active-maximized":
win = Wnck.Screen.get_default().get_active_window();
if(win != null && !win->is_maximized())
win = null;
break;
case "topmost-maximized":
List<weak Wnck.Window> windows = Wnck.Screen.get_default().get_windows_stacked().copy();
windows.reverse();
foreach(Wnck.Window* w in windows) {
if(w->is_maximized() && !w->is_minimized()){
win = w;
break;
}
}
break;
case "active-maximized":
if(win->is_maximized())
return win;
else
return null;

case "topmost-maximized":
if(win->is_maximized())
return win;
break;
}
}

return win;
return null;
}

private Gdk.Monitor? get_monitor_at_window(Wnck.Window *win){
int x, y, w, h;

win->get_client_window_geometry(out x, out y, out w, out h);

return Gdk.Display.get_default().get_monitor_at_point(x + w/2, y + h/2);
}

private void detect_monitor_change(){
Gdk.Monitor mon = get_monitor_at_window(active_window);
if(mon != active_window_monitor){
active_window_monitor = mon;
reload();
}
}
}

Expand All @@ -273,6 +304,8 @@ namespace WindowButtonsApplet{

var widget_container = new ButtonsApplet(Gtk.Orientation.HORIZONTAL, applet.get_style_context());

widget_container.monitor = applet.get_parent_window().get_screen().get_display().get_monitor_at_window(applet.get_parent_window());

widget_container.show();
widget_container.change_orient(applet.get_orient());
widget_container.change_size(applet.get_size());
Expand Down
98 changes: 66 additions & 32 deletions window-menu-applet/window-menu-applet.vala
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ namespace WindowMenuApplet{

class WindowMenu {
public WindowWidgets.WindowMenuButton button;
public Gdk.Monitor monitor;
private Wnck.Window *window;
private Wnck.Window *active_window;
private Gdk.Monitor active_window_monitor;

public GLib.Settings gsettings = new GLib.Settings("org.mate.window-applets.window-menu");

Expand All @@ -22,8 +24,10 @@ namespace WindowMenuApplet{
window->state_changed.disconnect(reload);
}

if(active_window != null)
if(active_window != null){
active_window->state_changed.disconnect(reload);
active_window->geometry_changed.disconnect(detect_monitor_change);
}


window = get_current_window();
Expand All @@ -40,11 +44,15 @@ namespace WindowMenuApplet{
window->state_changed.connect(reload);
}

// When active window is not the controlled window (because it is unmaximized),
// we need to watch its state as well
active_window = Wnck.Screen.get_default().get_active_window();
if(active_window != null && active_window != window)
active_window->state_changed.connect(reload);
if(active_window != null){
// When active window is not the controlled window (because it is unmaximized),
// we need to watch its state as well
if(active_window != window)
active_window->state_changed.connect(reload);

active_window->geometry_changed.connect(detect_monitor_change);
}
}

public void change_orient(MatePanel.Applet applet){
Expand Down Expand Up @@ -77,38 +85,62 @@ namespace WindowMenuApplet{
Wnck.Screen.get_default().window_closed.connect( reload );
}

private Wnck.Window get_current_window(){
Wnck.Window* win = null;
private Wnck.Window? get_current_window(){
Wnck.WindowType window_type;
string behaviour = gsettings.get_string("behaviour");
Wnck.Workspace active_workspace = Wnck.Screen.get_default().get_active_workspace();

List<weak Wnck.Window> windows = Wnck.Screen.get_default().get_windows_stacked().copy();
windows.reverse();

foreach(Wnck.Window* win in windows) {
window_type = win->get_window_type();
if(window_type == Wnck.WindowType.DESKTOP || window_type == Wnck.WindowType.DOCK)
continue;

if(win->is_minimized())
continue;

if(!win->is_on_workspace(active_workspace))
continue;

if(monitor != get_monitor_at_window(win))
continue;

switch(behaviour){
case "active-always":
return win;

case "active-maximized":
if(win->is_maximized())
return win;
else
return null;

switch(behaviour){
case "active-always":
win = Wnck.Screen.get_default().get_active_window();
if(win != null){
window_type = win->get_window_type();
if(window_type == Wnck.WindowType.DESKTOP || window_type == Wnck.WindowType.DOCK)
win = null;
}
break;
case "active-maximized":
win = Wnck.Screen.get_default().get_active_window();
if(win != null && !win->is_maximized())
win = null;
break;
case "topmost-maximized":
List<weak Wnck.Window> windows = Wnck.Screen.get_default().get_windows_stacked().copy();
windows.reverse();
foreach(Wnck.Window* w in windows) {
if(w->is_maximized() && !w->is_minimized()){
win = w;
break;
}
}
break;
case "topmost-maximized":
if(win->is_maximized())
return win;
break;
}
}

return win;
return null;
}

private Gdk.Monitor? get_monitor_at_window(Wnck.Window *win){
int x, y, w, h;

win->get_client_window_geometry(out x, out y, out w, out h);

return Gdk.Display.get_default().get_monitor_at_point(x + w/2, y + h/2);
}

private void detect_monitor_change(){
Gdk.Monitor mon = get_monitor_at_window(active_window);
if(mon != active_window_monitor){
active_window_monitor = mon;
reload();
}
}
}

Expand Down Expand Up @@ -163,6 +195,8 @@ namespace WindowMenuApplet{

Wnck.Screen.get_default().active_window_changed.connect( windowMenu.reload );

windowMenu.monitor = applet.get_parent_window().get_screen().get_display().get_monitor_at_window(applet.get_parent_window());

windowMenu.change_orient(applet);
windowMenu.change_behaviour();
windowMenu.reload();
Expand Down
Loading

0 comments on commit a70fcdf

Please sign in to comment.