3

I have a hotcorner in the top-left, to show all windows, and in the bottom-right to show workspaces. It's annoying when these keep activating while playing a game. Is there anyway to set Compiz to ignore hot corners when there's a full screen window?

Jacob Vlijm
  • 83,767
John
  • 917
  • 1
    Could be done, either by setting a custom command (script) for compiz (http://askubuntu.com/a/884851/72216) or running an alternative corner app. What would be your preference? – Jacob Vlijm Feb 28 '17 at 17:09
  • There are other hot corner apps? What are the alternatives? – John Feb 28 '17 at 17:23
  • 1
    Two of the scripts in the link above can be used as an alternative, but then you still need an addition to distinguish between full screen windows or not. Interested? I can write it for you, either as an addition to one of the scripts or to run separately from compiz. – Jacob Vlijm Feb 28 '17 at 17:26
  • Yes, if you could write that for me, that would be wonderful. I really appreciate it. – John Feb 28 '17 at 17:48
  • Hi John, I am an idiot. I forgot that showing spread windows and workspaces are coded into Unity. Had to take another way, which is probably even better. :) Please mention if al is clear. – Jacob Vlijm Feb 28 '17 at 19:35
  • Hi John, as promised, added a version that will disable all hotcorners, no matter which one(s) you set. – Jacob Vlijm Mar 04 '17 at 09:31

1 Answers1

5

Below two options; one script to disable all hotcorners (temporarily) if your active window is maximized, and one to only disable the specific hotcorners and actions you mention in the question.

Both scripts are extremely light weight and add no noticeable burden to your system whatsoever.

1. Disable all hotcorners if the active window is full screen

The background patch below will disable all hotcorners if (and as long as) the active window is maximized (fullscreen).

The script

#!/usr/bin/env python3
import subprocess
import time
import ast
import os

edgedata = os.path.join(os.environ["HOME"], ".stored_edges")
key = "/org/compiz/profiles/unity/plugins/"
corners = [
    "|TopRight", "|TopLeft", "|BottomLeft", "|Right",
    "|Left", "|Top", "|Bottom", "|BottomRight",
    ]

def get(cmd):
    # just a helper function
    try:
        return subprocess.check_output(cmd).decode("utf-8").strip()
    except subprocess.CalledProcessError:
        pass

def setval(cmd):
    # just another helper function
    subprocess.Popen(cmd)

def check_win():
    # see if the active window is maximized
    # get the active window, convert the id to wmctrl format
    windata = get(["wmctrl", "-lG"])
    if windata: 
        w = hex(int(get(["xdotool", "getactivewindow"])))
        front = w[:2]+((10-len(w))*"0")+w[2:]
        # look up the window size
        match = [l for l in windata.splitlines() if front in l][0].split()[4:6]
        # and compare them, if equal -> window is maximized
        return match == res

def get_res():
    # look up screen resolution
    scrdata = get("xrandr").split(); resindex = scrdata.index("connected")+2
    return [n for n in scrdata[resindex].split("+")[0].split("x")]

def get_edges():
    # get data from dump, remember 
    data = get(["dconf", "dump", key]).split()
    for s in data:
        if s.startswith("["):
            k = s.replace("[", "").replace("]", "/")
        elif any([[c in s][0] for c in corners]):
            currval = s.split("=")
            stored = ["dconf", "write", key+k+currval[0], currval[1]]
            tempval = ["dconf", "write", key+k+currval[0], "''"]
            open(edgedata, "a+").write(str(stored)+"\n")
            setval(tempval)

def set_stored():
    # set the stored values
    try:
        prev = open(edgedata).readlines()
    except FileNotFoundError:
        pass
    else:
        for l in  [l.strip() for l in open(edgedata).readlines()]:
            toset = ast.literal_eval(l)
            setval(toset)
        os.remove(edgedata)

res = get_res()
state1 = None

while True:
    time.sleep(1)
    state2 = check_win()
    if state2 != None:
        if state2 != state1:
            get_edges() if state2 else set_stored()
        state1 = state2

How to use

  1. The script needs both xdotool and wmctrl:

    sudo apt-get install wmctrl xdotool
    
  2. Copy the script into an empty file, safe it as disable_corners.py
  3. Test- run the script from a terminal with the command:

    python3 /path/to/disable_corners.py
    
  4. If all works fine, add it to Startup Applications: Dash > Startup Applications > Add. Add the command:

    /bin/bash -c "sleep 10 && python3 /path/to/disable_corners.py"
    

2. Disable only specific edges if the active window is full screen

The (background) script below will disable both corners actions you mention if the active window is maximized.

The script

#!/usr/bin/env python3
import subprocess
import time

key = "/org/compiz/profiles/unity/plugins"
active1 = "'|BottomRight'"; active2 = "'|TopLeft'"

def get(cmd):
    # just a helper function
    try:
        return subprocess.check_output(cmd).decode("utf-8")
    except subprocess.CalledProcessError:
        pass

def setval(cmd):
    # just another helper function
    subprocess.Popen(cmd)

def check_win():
    # see if the active window is maximized
    # get the active window, convert the id to wmctrl format
    windata = get(["wmctrl", "-lG"])
    if windata: 
        w = hex(int(get(["xdotool", "getactivewindow"])))
        front = w[:2]+((10-len(w))*"0")+w[2:]
        # look up the window size
        match = [l for l in windata.splitlines() if front in l][0].split()[4:6]
        # and compare them, if equal -> window is maximized
        return match == res

def get_res():
    # look up screen resolution
    scrdata = get("xrandr").split(); resindex = scrdata.index("connected")+2
    return [n for n in scrdata[resindex].split("+")[0].split("x")]

res = get_res()
state1 = None

while True:
    time.sleep(1)
    state2 = check_win()
    if state2 != None:
        if state2 != state1:
            newws = "''" if state2 else active1
            # below the specific edges to take care of
            setval(["dconf", "write", key+"/expo/expo-edge", newws])
            newspread = "''" if state2 else active2
            setval(["dconf", "write", key+"/scale/initiate-edge", newspread])
        state1 = state2

How to use

Usage and set up is exactly the same as option 1.

Explanation

  • On startup of the script, the script checks the screen's resolution.
  • Once per second, the script checks the size of the active window, and compares it to the screen's resolution.
  • If the window size and the resolution are equal, the window is obviously maximized.
  • If there is a change in the situation (maximized/unmaximized), the script sets/unsets your set hotcorners using the commands:

    dconf write /org/compiz/profiles/unity/plugins/expo/expo-edge "''"
    
    dconf write /org/compiz/profiles/unity/plugins/scale/initiate-edge "''"
    

    to disable, or

    dconf write /org/compiz/profiles/unity/plugins "'|BottomRight'"
    
    dconf write /org/compiz/profiles/unity/plugins "'|TopLeft'"
    

    to enable.

Jacob Vlijm
  • 83,767