วิธีย้ายหน้าต่างทั้งหมดไปยังพื้นที่ทำงานอื่น


8

เป็นไปได้ที่จะย้าย windows ทั้งหมด (หรือ windows ที่ไม่ย่อเล็กสุด) จากพื้นที่ทำงานหนึ่งไปยังอีกที่หนึ่งหรือไม่

ฉันรู้ว่าฉันสามารถย้ายหน้าต่างหนึ่งไปยังพื้นที่ทำงานอื่นด้วยShift+ Ctrl+ Alt+ arrowแต่มันจะย้ายเฉพาะหน้าต่างที่โฟกัสเท่านั้น


คุณยังสนใจในโซลูชัน Unity หรือไม่?
Jacob Vlijm

ใช่ฉันต้องการทางออกเพื่อความสามัคคี ขออภัยฉันไม่ได้ระบุอย่างแน่นอนว่าฉันใช้ Unity
betatester07

คุณสังเกตเห็นสิ่งนี้หรือไม่? ฉันไม่ลองไม่รู้ว่ายังใช้งานได้หรือไม่ ถ้าไม่ฉันสามารถหาทางเลือกอื่นภายใต้คีย์ลัด
Jacob Vlijm

ขอโทษที่มีไว้สำหรับหน้าต่างเดียวจะมองเข้าไปในนั้น!
Jacob Vlijm

ได้ทำงานกับมันและมีสคริปต์การทำงาน "ชนิด" อย่างไรก็ตามปัญหาที่เกิดขึ้นแบบสุ่มทำให้ใช้งานได้ยาก จะโพสต์มันหากฉันพบว่าอะไรเป็นสาเหตุ
Jacob Vlijm

คำตอบ:


5

ความสามัคคี: วิวพอร์ตคืออะไร?

Ubuntu Unity ใช้วิวพอร์ต - โดยทั่วไปคือระบบพิกัด (โดยมีพิกัด 0,0 เป็นมุมบนซ้าย) ซึ่งเดสก์ท็อปยักษ์หนึ่งตัวแบ่งย่อยเป็นส่วน ๆ ที่เหมาะกับความละเอียดหน้าจอของคุณ พิกัดเติบโตขึ้นในขณะที่คุณเลื่อนไปทางขวาและลง

ป้อนคำอธิบายรูปภาพที่นี่

ระบบพิกัดนั้นสัมพันธ์กัน ถ้าวิวพอร์ตปัจจุบันของฉันอยู่ด้านบนซ้ายทุกสิ่งที่สัมพันธ์กับวิวพอร์ตนั้นจะเป็นค่าบวกในการเพิ่มความกว้างและความสูง ตัวอย่างเช่นหากวิวพอร์ตปัจจุบันของฉันอยู่ด้านบนซ้ายสุดหน้าต่าง firefox ในพื้นที่ทำงานตรงกลางด้านบนที่คุณเห็นด้านบนจะอยู่ในตำแหน่งที่ค่า x 1366 และค่า y 0 เทียบกับวิวพอร์ตด้านซ้ายสุดด้านบน หากวิวพอร์ตที่ใช้งานอยู่ของฉันอยู่ตรงกลางสุดหน้าต่างเทอร์มินัลในวิวพอร์ตด้านซ้ายสุดด้านบนจะอยู่ในตำแหน่งที่ค่า x -1327 60 นี่เป็นปัญหาสำคัญสำหรับxdotoolเนื่องจากxdotoolไม่ได้จัดการกับจำนวนลบ

โปรดทราบว่ามุมบนซ้ายของวิวพอร์ตปัจจุบันของคุณจะถือว่า xdotool เป็นพิกัด 0 0 เสมอ นั่นหมายความว่าเราสามารถย้ายสิ่งที่ถูกต้องและลง

การทำให้ xdotool ใช้งานได้กับ Unity

ตอนนี้เรารู้แล้วว่าxdotoolสามารถย้ายหน้าต่างได้เฉพาะเมื่อเทียบกับมุมบนซ้ายของเรา (เช่นคุณสามารถเลื่อนหน้าต่างลงและขวาได้ตลอดเวลา แต่ไม่ขึ้นและซ้าย) เราจะทำให้งานนั้นเป็นเอกภาพได้อย่างไร แนวคิดพื้นฐานก็คือ

  1. คิดออกหน้าต่างทั้งหมดในวิวพอร์ตปัจจุบัน
  2. เลื่อนไปยังวิวพอร์ตที่ร้องขอชั่วขณะเพื่อให้มุมซ้ายบนถือว่าพิกัด 0 0 ที่วิวพอร์ตนั้น
  3. ย้ายหน้าต่างทั้งหมดไปยังพิกัดวิวพอร์ตที่ผู้ใช้กำหนด
  4. กลับไปที่วิวพอร์ตเดิม (เป็นตัวเลือกสามารถติดตามหน้าต่างได้เช่นกัน)

โซลูชันการเขียนสคริปต์

สคริปต์ด้านล่างดำเนินการตามขั้นตอนที่อธิบายไว้ด้านบนทั้งหมด มันสามารถเรียกได้ด้วยการ-vตั้งค่าสถานะเพื่อระบุพิกัดด้วยตนเองหรือคุณสามารถใช้การ-gตั้งค่าสถานะเพื่อแสดงกล่องโต้ตอบ GUI -fธงจะบอกสคริปต์เพื่อสลับวิวพอร์ตเช่นกัน หากไม่ได้ใช้ค่าสถานะนั้นคุณจะยังคงอยู่ในวิวพอร์ตปัจจุบันและจะมีเพียงหน้าต่างที่ถูกย้ายไป

การรับสคริปต์

หนึ่งสามารถคัดลอกรหัสที่มาจากโพสต์นี้โดยตรงหรือผ่าน Github โดยใช้ขั้นตอนต่อไปนี้:

  1. sudo apt-get install git
  2. cd /opt ; sudo git clone https://github.com/SergKolo/sergrep.git
  3. sudo chmod -R +x sergrep

ไฟล์สคริปต์จะเป็น /opt/sergrep/move_viewport_windows.sh

หากต้องการผูกสคริปต์กับทางลัดอ้างอิงฉันจะผูกไฟล์. sh กับชุดแป้นพิมพ์ได้อย่างไร

โปรดทราบว่าwmctrlและxdotoolจำเป็นสำหรับสคริปต์นี้เพื่อให้ทำงานได้อย่างถูกต้อง คุณสามารถติดตั้งผ่าน sudo apt-get install xdotool และ wmctrl

รหัสแหล่งที่มา

#!/usr/bin/env bash
#
###########################################################
# Author: Serg Kolo , contact: 1047481448@qq.com 
# Date: April 17 2016
# Purpose: Move all windows on the current viewport
#          to a user-defined one
# Written for:
# Tested on: Ubuntu 14.04 LTS , Unity 7.2.6
###########################################################
# Copyright: Serg Kolo , 2016
#    
#     Permission to use, copy, modify, and distribute this software is hereby granted
#     without fee, provided that  the copyright notice above and this permission statement
#     appear in all copies.
#
#     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
#     THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
#     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
#     DEALINGS IN THE SOFTWARE.

get_active_viewport()
{
  xprop -root -notype _NET_DESKTOP_VIEWPORT
}

get_screen_geometry()
{
 xwininfo -root | awk '/-geometry/{gsub(/+|x/," ");print $2,$3}'  
}

current_wins()
{  
   HEX="$(wmctrl -lG | \
   awk -v xlim="$XMAX" -v ylim="$YMAX" \
      'BEGIN{printf "ibase=16;"} $3>0 && $3<xlim  && $4>0 && $4<ylim \
      { gsub(/0x/,""); printf "%s;",toupper($1)  } ')"
   echo $HEX | bc | tr '\n' ' '
}

gui_selection()
{
  SCHEMA="org.compiz.core:/org/compiz/profiles/unity/plugins/core/"
  read swidth sdepth  <<< "$(get_screen_geometry)"
  vwidth=$(gsettings get $SCHEMA hsize)
  vheight=$(gsettings get $SCHEMA vsize)

 width=0
 for horizontal in $(seq 1 $vwidth); do
    height=0 
    for vertical in $(seq 1 $vheight);  do

      array+=( FALSE  )
      array+=( $(echo "$width"x"$height") )

    height=$(($height+$sdepth))
    done
 width=$(($width+$swidth))
 done

 zenity --list --radiolist --column="" --column "CHOICE" ${array[@]} --width 350 --height 350 2> /dev/null
}

print_usage()
{
cat << EOF
move_viewport_windows.sh [-v 'XPOS YPOS' ] [-g] [-f ] [-h]

Copyright Serg Kolo , 2016

The script gets list of all windows on the current Unity 
viewport and moves them to user-specified viewport. If
ran without flags specified, script prints this text

-g flag brings up GUI dialog with list of viewports

-v allows manually specifying viewoport. Argument must be
   quoted, X and Y position space separated

-f if set, the viewport will switch to the same one where
   windows were sent

-h prints this text

** NOTE ** 
wmctrl and xdotool are required for this script to work
properly. You can install them via sudo apt-get install
xdotool and wmctrl

EOF
}

parse_args()
{
  if [ $# -eq 0  ];then
    print_usage
    exit
  fi
  while getopts "v:ghf" opt
 do
   case ${opt} in
     v) NEWVP=${OPTARG}
        ;;
     g) NEWVP="$(gui_selection | tr 'x' ' ' )"
        [ -z "$NEWVP" ] && exit 1
        ;;
     f) FOLLOW=true
        ;; 
     h) print_usage
        exit 0
        ;;
     \?)
      echo "Invalid option: -$OPTARG" >&2
      ;;
    esac
  done
  shift $((OPTIND-1))
}

main()
{
 # Basic idea:
 #-------------------
 # 1. get current viewport and list of windows
 # 2. go to viewport 0 0 and move all windows from list
 #    to desired viewport
 # 3. go back to original viewport or follow the windows,
 #    depending on user choice
 # 4. Tell the user where they are currently

 local FOLLOW
 local NEWVP # coordinates of desired viewport
 local XMAX YMAX # must be two vals for awk to work
 local OLDVP=$(get_active_viewport | awk -F '=' '{sub(/,/," ");print $2}' )

 parse_args "$@"

 read XMAX YMAX  <<< "$(get_screen_geometry)" # move to getopts

 windows=( $(current_wins) )

 xdotool set_desktop_viewport 0 0 
 for win in ${windows[@]} ; do
    echo "$win"
    xdotool windowmove $win $NEWVP
 done
 # sleep 0.25 # uncomment if necessary

 if [ $FOLLOW  ]; then
     xdotool set_desktop_viewport $NEWVP
 else
     xdotool set_desktop_viewport $OLDVP
 fi

 sleep 0.25 # delay to allow catching active viewport
 notify-send "current viewport is $(get_active_viewport | awk -F '=' '{sub(/,/," ");print $2}' )"
 exit 0
}
main "$@"

การสาธิต

การดำเนินการบันทึกสคริปต์ของ Webm:

https://www.youtube.com/watch?v=cJMlC41CWWo

ประเด็น

เนื่องจากgridปลั๊กอินของ Unity ที่รับผิดชอบการจัดเรียงหน้าต่างสคริปต์ไม่สามารถย้ายหน้าต่างที่ถูกขยายให้ใหญ่สุดหรือขวา / ซ้าย มันจะพยายามเพิ่มการตั้งค่าและการรีเซ็ตชั่วขณะของปลั๊กอินนั้นเพื่อให้สคริปต์ทำงานกับ windows ทั้งหมด แต่เนื่องจากการยกเลิกและการรีเซ็ตมีความล่าช้าในเวลา หากคุณต้องการให้สคริปต์ทำงานกับ windows ทั้งหมดให้ติดตั้งunity-tweak-toolและยกเลิกการตั้งค่า snapping หน้าต่างภายใต้ตัวเลือก Window Manager


น่าประหลาดใจที่คำตอบเฉพาะนี้ได้รับเพียง 2-3 upvotes ...
บ้าเกี่ยวกับ natty

3

สภาพแวดล้อมเดสก์ท็อปที่ไม่ใช้ Compiz (XFCE, LXDE, GNOME, KDE ... )

คุณสามารถใช้การรวมกันของwmctrlและxdotoolสำหรับสิ่งนี้ ก่อนอื่นตรวจสอบให้แน่ใจว่าได้ติดตั้งอรรถประโยชน์ทั้งสองนี้แล้ว:

sudo apt-get install xdotool wmctrl

ด้วยการพึ่งพาที่พึงพอใจคุณควรจะสามารถใช้หนึ่งซับรองต่อไปนี้เพื่อย้ายหน้าต่างทั้งหมดบนเดสก์ท็อปปัจจุบันไปยังอันอื่น:

while read i; do wmctrl -i -t 2 -r "$i"  ; done  < <(wmctrl -l | awk -v var=$(xdotool get_desktop) '{if ($2 == var) print $0;}' | cut -d' '  -f1)

การแบ่งคำสั่งอย่างรวดเร็วที่ใช้:

  • wmctrl -l | awk -v var=$(xdotool get_desktop) '{if ($2 == var) print $0;}' | cut -d' ' -f1

    แสดงรายการ windows ทั้งหมดกรองหน้าต่างที่ไม่อยู่ในพื้นที่ทำงานปัจจุบันและแยก ID หน้าต่าง

  • wmctrl -i -t 2 -r "$i"

    ย้ายหน้าต่างด้วย ID หน้าต่าง$iไปยังพื้นที่ทำงาน 2

  • ทั้งหมดนี้บรรจุในwhile read ... do; doneลูปแบบง่ายที่วนซ้ำทุกหน้าต่างบนเดสก์ท็อปปัจจุบัน

สภาพแวดล้อมเดสก์ทอปที่ใช้ Compiz (เช่น Unity)

หาวิธีการแก้ปัญหาสำหรับสภาพแวดล้อมเดสก์ทอปเช่นเอกภาพทำยากจากข้อเท็จจริงที่ว่า Compiz (จัดการหน้าต่างของความสามัคคี) ไม่ได้ใช้เดสก์ท็ในความรู้สึกแบบดั้งเดิม


ขอบคุณมันดูดี แต่ฉันกำลังใช้ Unity และหวังหาวิธีแก้ปัญหาง่ายๆ แต่อย่างที่คุณพูดถึงทางออกสำหรับ Unity จะยากขึ้นอีกนิด
betatester07

เพียงคำพูดเล็ก ๆ เวิร์กสเปซ 2 ใน "ย้ายหน้าต่างพร้อม ID หน้าต่าง $ i ไปยังพื้นที่ทำงาน 2" จริงๆแล้วเป็นเวิร์กสเปซที่สามไม่ใช่ที่สองเนื่องจากเวิร์กสเปซแรกเริ่มต้นด้วยศูนย์ ดังนั้นหากคุณมีพื้นที่ทำงานเพียงสองแห่งสคริปต์อาจดูไม่ทำงาน
Mohamad Fakih
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.