6

I have gone into compizconfig's grid section and customized all the tiling commands.

When I was testing the commands, I didn't see that any of them effectively centered the screen.

I went into the window placement section and configured new windows to open centered. But if I move a window to the right side and then want to center it, I don't know how I should do that with a keyboard command. The "put center" will maximize it and "restore" will move it to its most recent position / size.

To summarize

say I have a window covering the right half of the screen. I want to keep the dimensions / size the same, but just center it.

4

2 Answers 2

3

Introduction:

The following script aligns the center of the user's active window with screen's center. It is intended to be bound to a keyboard shortcut in Settings -> Keyboard ->Shortcuts menu.


Usage:

  1. Save the script as ~/bin/center_active_window.py. Ensure it has executable permissions with chmod +x ~/bin/center_active_window.py
  2. Open System Settings -> Keyboard -> Shortcuts -> Custom. Click +.
  3. You will be prompted with a popup asking for Name and Command. Name can be anything, command has to be full path to your new script, i.e. /home/your_user_name/bin/center_active_window.py. Click Apply
  4. Click on the Disabled text and assign it a custom keybinding once prompted. I'm using Ctrl+Super+C , but you can use whatever you like.

Source code

Also available as gist on GitHub

#!/usr/bin/env python3

# Author: Serg Kolo
# Date: Oct 3rd, 2016
# Description: Script for aligning the center of 
#     user's active window with the center of the monitor
# Tested on: Ubuntu 16.04
# Written for: http://askubuntu.com/q/832720/295286

from __future__ import print_function
from gi.repository import Gdk
import subprocess

def get_offset(*args):
    command = ['xprop','-notype','_NET_FRAME_EXTENTS',
               '-id',str(args[0])
    ]

    out = subprocess.check_output(command)
    return int(out.decode().strip().split(',')[-2])

def main():

    screen = Gdk.Screen.get_default()
    window = screen.get_active_window()
    window.unmaximize()
    window_width = window.get_width()
    window_y = window.get_origin()[-1]
    print(window_y)
    window_monitor = screen.get_monitor_at_window(window)
    monitor_center = screen.get_monitor_geometry(window_monitor).width/2

    # if centers of window and screen are aligned
    # the top left corner will be at screen_center - window_width/2    
    new_position = monitor_center - window_width /2

    # For some reason there is vertical offset necessary
    # Apparently this comes form _NET_FRAME_EXTENTS value
    offset = get_offset(int(window.get_xid()))

    window.move(new_position,window_y-offset)
    print(window.get_origin()) 

if __name__ == '__main__':
    main()

5
  • Thanks for the example of such a script. This works but doesn't maintain the size of window. For example if I first "put right" a window (so it's covering the right half of the screen) then run center_active_window, the window is not centered, but it get larger (to it's default launch size). Then when I run center_active_window again, this larger windows gets centered. Is there a way to combine these into a single step and to prevent the window from growing in size? Oct 4, 2016 at 18:15
  • @macsplean the issue with "put right" shortcuts in Unity is that they often interfere with custom commands for moving windows around. I've been testing this with unmaximized regular windows - that part would work ok, size preserved and window centered. Right and Left maximized windows have to be unmaximized first for it to get centered. I'll work on it a bit more, but there's not a lot i can do against Unity desktop Oct 4, 2016 at 18:24
  • the main piece of functionality is to put a window at the center with a custom width/height. If I first put it in the top right corner it is 25% of the screen; I want to center it at this smaller size. I guess I should look at alternate tiling programs / desktop managers. Oct 4, 2016 at 18:27
  • @macsplean what's your Ubuntu version by the way ? I'll keep working on this script, will see what else can be done. Oct 4, 2016 at 18:39
  • sixteen zero four Oct 4, 2016 at 18:55
1

guys. I know this is an old question, but I've been searching for the same thing and, after a lot of testing, I came up with my own script and, if you don't mind, I'd really like to share it with you.

#!/bin/sh

ScreenX=$(xdpyinfo | awk -F'[ x]+' '/dimensions:/{print $3}')
ScreenY=$(xdpyinfo | awk -F'[ x]+' '/dimensions:/{print $4}')

WindowX=$(xwininfo -id $(xdotool getactivewindow) | awk -F'[ :]+' '/Width:/{print $3}')
WindowY=$(xwininfo -id $(xdotool getactivewindow) | awk -F'[ :]+' '/Height:/{print $3}')

#WindowX=$(xwininfo -id $(xdotool getactivewindow) | sed -n -e "s/^ \+Width: \([0-9]\+\).*/\1/p")
#WindowY=$(xwininfo -id $(xdotool getactivewindow) | sed -n -e "s/^ \+Height: \([0-9]\+\).*/\1/p")

PositionX=$(((ScreenX/2)-(WindowX/2)))
PositionY=$(((ScreenY/2)-(WindowY/2)))

#echo "Screen X: " $ScreenX
#echo "Window X: " $WindowX
#echo "Position X: " $PositionX

#echo "Screen Y: " $ScreenY
#echo "Window Y: " $WindowY
#echo "Position Y: " $PositionY

wmctrl -r :ACTIVE: -e 1,$PositionX,$PositionY,$WindowX,$WindowY

Some commands are commented. I decided to keep them just for curiosity purposes because they worked very well while I was trying to figure out what to do (I'm not very familiar with bash scripts).

If anyone knows how to make this script cleaner and/or smoother, feel free to enlighten us. That'd be very cool.

I hope it's useful.

Cheers.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .