mirror of
https://github.com/fcwu/docker-ubuntu-vnc-desktop
synced 2026-08-05 16:12:41 +02:00
Merge branch 'develop' into bionic-lxqt
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
server {
|
||||
listen 80 default_server;
|
||||
# listen [::]:80 default_server ipv6only=on;
|
||||
|
||||
#_SSL_PORT_#listen 443 ssl default_server;
|
||||
#_SSL_PORT_#listen [::]:443 ssl default_server ipv6only=on;
|
||||
#_SSL_PORT_#ssl_certificate /etc/nginx/ssl/nginx.crt;
|
||||
#_SSL_PORT_#ssl_certificate_key /etc/nginx/ssl/nginx.key;
|
||||
|
||||
#_HTTP_PASSWORD_#auth_basic "Private Property";
|
||||
#_HTTP_PASSWORD_#auth_basic_user_file /etc/nginx/.htpasswd;
|
||||
|
||||
root /usr/local/lib/web/frontend/;
|
||||
index index.html index.htm;
|
||||
|
||||
location ~ /api/ {
|
||||
try_files $uri @api;
|
||||
}
|
||||
|
||||
location ~ /resize$ {
|
||||
try_files $uri @api;
|
||||
}
|
||||
|
||||
#_RELATIVE_URL_ROOT_location /_RELATIVE_URL_ROOT_/ {
|
||||
#_RELATIVE_URL_ROOT_ rewrite /_RELATIVE_URL_ROOT_/(.*) /$1 break;
|
||||
#_RELATIVE_URL_ROOT_ root /usr/local/lib/web/frontend/;
|
||||
#_RELATIVE_URL_ROOT_}
|
||||
|
||||
location ~ /websockify$ {
|
||||
#_RELATIVE_URL_ROOT_rewrite /_RELATIVE_URL_ROOT_/(.*) $1 break;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_buffering off;
|
||||
proxy_connect_timeout 7d;
|
||||
proxy_send_timeout 7d;
|
||||
proxy_read_timeout 7d;
|
||||
proxy_pass http://127.0.0.1:6081;
|
||||
}
|
||||
|
||||
location @api {
|
||||
#_RELATIVE_URL_ROOT_rewrite /_RELATIVE_URL_ROOT_/(.*) $1 break;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header Host $host;
|
||||
proxy_pass http://127.0.0.1:6079;
|
||||
max_ranges 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
[supervisord]
|
||||
redirect_stderr=true
|
||||
stopsignal=QUIT
|
||||
autorestart=true
|
||||
directory=/root
|
||||
|
||||
[program:nginx]
|
||||
priority=10
|
||||
command=nginx -c /etc/nginx/nginx.conf -g 'daemon off;'
|
||||
|
||||
[program:web]
|
||||
priority=10
|
||||
directory=/usr/local/lib/web/backend
|
||||
command=/usr/local/lib/web/backend/run.py
|
||||
stdout_logfile=/dev/fd/1
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/fd/1
|
||||
stderr_logfile_maxbytes=0
|
||||
|
||||
|
||||
[group:x]
|
||||
# programs=xvfb,wm,lxpanel,pcmanfm,x11vnc,novnc
|
||||
programs=xvfb,wm,lxpanel,x11vnc,novnc
|
||||
|
||||
[program:wm]
|
||||
priority=15
|
||||
command=/usr/bin/openbox
|
||||
environment=DISPLAY=":1",HOME="/root",USER="root"
|
||||
|
||||
[program:lxpanel]
|
||||
priority=15
|
||||
directory=%HOME%
|
||||
command=/usr/bin/startlxqt
|
||||
user=%USER%
|
||||
environment=DISPLAY=":1",HOME="%HOME%",USER="%USER%"
|
||||
|
||||
# [program:pcmanfm]
|
||||
# priority=15
|
||||
# directory=%HOME%
|
||||
# command=/usr/bin/pcmanfm --desktop --profile LXDE
|
||||
# user=%USER%
|
||||
# environment=DISPLAY=":1",HOME="%HOME%",USER="%USER%"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[program:xvfb]
|
||||
priority=10
|
||||
command=/usr/local/bin/xvfb.sh
|
||||
stopsignal=KILL
|
||||
|
||||
[program:x11vnc]
|
||||
priority=20
|
||||
command=x11vnc -display :1 -xkb -forever -shared -repeat
|
||||
|
||||
[program:novnc]
|
||||
priority=25
|
||||
directory=/usr/local/lib/web/frontend/static/novnc
|
||||
command=bash /usr/local/lib/web/frontend/static/novnc/utils/launch.sh --listen 6081
|
||||
stopasgroup=true
|
||||
@@ -0,0 +1,86 @@
|
||||
[supervisord]
|
||||
redirect_stderr=true
|
||||
stopsignal=QUIT
|
||||
autorestart=true
|
||||
directory=/root
|
||||
|
||||
[program:nginx]
|
||||
priority=10
|
||||
command=nginx -c /etc/nginx/nginx.conf -g 'daemon off;'
|
||||
|
||||
[program:web]
|
||||
priority=10
|
||||
directory=/usr/local/lib/web/backend
|
||||
command=/usr/local/lib/web/backend/run.py
|
||||
stdout_logfile=/dev/fd/1
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/fd/1
|
||||
stderr_logfile_maxbytes=0
|
||||
|
||||
{% if desktop == "lxde" %}
|
||||
[group:x]
|
||||
programs=xvfb,wm,lxpanel,pcmanfm,x11vnc,novnc
|
||||
|
||||
[program:wm]
|
||||
priority=15
|
||||
command=/usr/bin/openbox
|
||||
environment=DISPLAY=":1",HOME="/root",USER="root"
|
||||
|
||||
[program:lxpanel]
|
||||
priority=15
|
||||
directory=%HOME%
|
||||
command=/usr/bin/lxpanel --profile LXDE
|
||||
user=%USER%
|
||||
environment=DISPLAY=":1",HOME="%HOME%",USER="%USER%"
|
||||
|
||||
[program:pcmanfm]
|
||||
priority=15
|
||||
directory=%HOME%
|
||||
command=/usr/bin/pcmanfm --desktop --profile LXDE
|
||||
user=%USER%
|
||||
environment=DISPLAY=":1",HOME="%HOME%",USER="%USER%"
|
||||
{% endif %}
|
||||
|
||||
{% if desktop == "lxqt" %}
|
||||
[group:x]
|
||||
programs=xvfb,wm,lxpanel,x11vnc,novnc
|
||||
|
||||
[program:wm]
|
||||
priority=15
|
||||
command=/usr/bin/openbox
|
||||
environment=DISPLAY=":1",HOME="/root",USER="root"
|
||||
|
||||
[program:lxpanel]
|
||||
priority=15
|
||||
directory=%HOME%
|
||||
command=/usr/bin/startlxqt
|
||||
user=%USER%
|
||||
environment=DISPLAY=":1",HOME="%HOME%",USER="%USER%"
|
||||
{% endif %}
|
||||
|
||||
{% if desktop == "xfce4" %}
|
||||
[group:x]
|
||||
programs=xvfb,lxpanel,x11vnc,novnc
|
||||
|
||||
[program:lxpanel]
|
||||
priority=15
|
||||
directory=%HOME%
|
||||
command=/usr/bin/startxfce4
|
||||
user=%USER%
|
||||
environment=DISPLAY=":1",HOME="%HOME%",USER="%USER%"
|
||||
{% endif %}
|
||||
|
||||
[program:xvfb]
|
||||
priority=10
|
||||
command=/usr/local/bin/xvfb.sh
|
||||
stopsignal=KILL
|
||||
|
||||
[program:x11vnc]
|
||||
priority=20
|
||||
command=x11vnc -display :1 -xkb -forever -shared -repeat
|
||||
|
||||
[program:novnc]
|
||||
priority=25
|
||||
directory=/usr/local/lib/web/frontend/static/novnc
|
||||
command=bash /usr/local/lib/web/frontend/static/novnc/utils/launch.sh --listen 6081
|
||||
stopasgroup=true
|
||||
@@ -0,0 +1,4 @@
|
||||
pcm.loop {
|
||||
type plug
|
||||
slave.pcm "hw:Loopback,2,0"
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
[General]
|
||||
AllowGrabBaseKeypad=true
|
||||
AllowGrabBaseSpecial=false
|
||||
AllowGrabLocks=false
|
||||
AllowGrabMiscKeypad=true
|
||||
AllowGrabMiscSpecial=true
|
||||
MultipleActionsBehaviour=first
|
||||
|
||||
[Alt%2BF1.1]
|
||||
Comment=Show/hide main menu
|
||||
Enabled=true
|
||||
path=/panel/mainmenu/show_hide
|
||||
|
||||
[Alt%2BF2.2]
|
||||
Comment=Show/hide runner dialog
|
||||
Enabled=true
|
||||
path=/runner/show_hide_dialog
|
||||
|
||||
[Control%2BAlt%2BD.3]
|
||||
Comment=Show desktop
|
||||
Enabled=true
|
||||
path=/panel/showdesktop/show_hide
|
||||
|
||||
[Control%2BAlt%2BE.4]
|
||||
Comment=Pcmanfm
|
||||
Enabled=true
|
||||
Exec=pcmanfm-qt
|
||||
|
||||
[Control%2BAlt%2BI.5]
|
||||
Comment=Web browser
|
||||
Enabled=true
|
||||
Exec=xdg-open, about:blank
|
||||
|
||||
[Control%2BAlt%2BT.6]
|
||||
Comment=QTerminal
|
||||
Enabled=true
|
||||
Exec=qterminal
|
||||
|
||||
[Control%2BF1.7]
|
||||
Comment=Switch to desktop 1
|
||||
Enabled=true
|
||||
path=/panel/desktopswitch/desktop_1
|
||||
|
||||
[Control%2BF10.8]
|
||||
Comment=Switch to desktop 10
|
||||
Enabled=true
|
||||
path=/panel/desktopswitch/desktop_10
|
||||
|
||||
[Control%2BF11.9]
|
||||
Comment=Switch to desktop 11
|
||||
Enabled=true
|
||||
path=/panel/desktopswitch/desktop_11
|
||||
|
||||
[Control%2BF12.10]
|
||||
Comment=Switch to desktop 12
|
||||
Enabled=true
|
||||
path=/panel/desktopswitch/desktop_12
|
||||
|
||||
[Control%2BF2.11]
|
||||
Comment=Switch to desktop 2
|
||||
Enabled=true
|
||||
path=/panel/desktopswitch/desktop_2
|
||||
|
||||
[Control%2BF3.12]
|
||||
Comment=Switch to desktop 3
|
||||
Enabled=true
|
||||
path=/panel/desktopswitch/desktop_3
|
||||
|
||||
[Control%2BF4.13]
|
||||
Comment=Switch to desktop 4
|
||||
Enabled=true
|
||||
path=/panel/desktopswitch/desktop_4
|
||||
|
||||
[Control%2BF5.14]
|
||||
Comment=Switch to desktop 5
|
||||
Enabled=true
|
||||
path=/panel/desktopswitch/desktop_5
|
||||
|
||||
[Control%2BF6.15]
|
||||
Comment=Switch to desktop 6
|
||||
Enabled=true
|
||||
path=/panel/desktopswitch/desktop_6
|
||||
|
||||
[Control%2BF7.16]
|
||||
Comment=Switch to desktop 7
|
||||
Enabled=true
|
||||
path=/panel/desktopswitch/desktop_7
|
||||
|
||||
[Control%2BF8.17]
|
||||
Comment=Switch to desktop 8
|
||||
Enabled=true
|
||||
path=/panel/desktopswitch/desktop_8
|
||||
|
||||
[Control%2BF9.18]
|
||||
Comment=Switch to desktop 9
|
||||
Enabled=true
|
||||
path=/panel/desktopswitch/desktop_9
|
||||
|
||||
[Meta%2B0.19]
|
||||
Comment=Activate task 10
|
||||
Enabled=true
|
||||
path=/panel/taskbar/task_10
|
||||
|
||||
[Meta%2B1.20]
|
||||
Comment=Activate task 1
|
||||
Enabled=true
|
||||
path=/panel/taskbar/task_1
|
||||
|
||||
[Meta%2B2.21]
|
||||
Comment=Activate task 2
|
||||
Enabled=true
|
||||
path=/panel/taskbar/task_2
|
||||
|
||||
[Meta%2B3.22]
|
||||
Comment=Activate task 3
|
||||
Enabled=true
|
||||
path=/panel/taskbar/task_3
|
||||
|
||||
[Meta%2B4.23]
|
||||
Comment=Activate task 4
|
||||
Enabled=true
|
||||
path=/panel/taskbar/task_4
|
||||
|
||||
[Meta%2B5.24]
|
||||
Comment=Activate task 5
|
||||
Enabled=true
|
||||
path=/panel/taskbar/task_5
|
||||
|
||||
[Meta%2B6.25]
|
||||
Comment=Activate task 6
|
||||
Enabled=true
|
||||
path=/panel/taskbar/task_6
|
||||
|
||||
[Meta%2B7.26]
|
||||
Comment=Activate task 7
|
||||
Enabled=true
|
||||
path=/panel/taskbar/task_7
|
||||
|
||||
[Meta%2B8.27]
|
||||
Comment=Activate task 8
|
||||
Enabled=true
|
||||
path=/panel/taskbar/task_8
|
||||
|
||||
[Meta%2B9.28]
|
||||
Comment=Activate task 9
|
||||
Enabled=true
|
||||
path=/panel/taskbar/task_9
|
||||
|
||||
[Print.29]
|
||||
Comment=screen shot
|
||||
Enabled=true
|
||||
Exec=lximage-qt, -s
|
||||
|
||||
[Shift%2BControl%2BF6.30]
|
||||
Comment=\x2600 \x2193
|
||||
Enabled=true
|
||||
Exec=lxqt-config-brightness, -d
|
||||
|
||||
[Shift%2BControl%2BF7.31]
|
||||
Comment=\x2600 \x2191
|
||||
Enabled=true
|
||||
Exec=lxqt-config-brightness, -i
|
||||
|
||||
[XF86AudioLowerVolume.32]
|
||||
Comment=Decrease sound volume
|
||||
Enabled=true
|
||||
path=/panel/volume/down
|
||||
|
||||
[XF86AudioMute.33]
|
||||
Comment=Mute/unmute sound volume
|
||||
Enabled=true
|
||||
path=/panel/volume/mute
|
||||
|
||||
[XF86AudioRaiseVolume.34]
|
||||
Comment=Increase sound volume
|
||||
Enabled=true
|
||||
path=/panel/volume/up
|
||||
|
||||
[XF86MonBrightnessDown.35]
|
||||
Comment=\x2600 \x2193
|
||||
Enabled=true
|
||||
Exec=lxqt-config-brightness, -d
|
||||
|
||||
[XF86MonBrightnessUp.36]
|
||||
Comment=\x2600 \x2191
|
||||
Enabled=true
|
||||
Exec=lxqt-config-brightness, -i
|
||||
@@ -0,0 +1,6 @@
|
||||
[General]
|
||||
__userfile__=true
|
||||
enableBatteryWatcher=false
|
||||
enableIdlenessWatcher=true
|
||||
enableLidWatcher=false
|
||||
runCheckLevel=1
|
||||
@@ -0,0 +1,2 @@
|
||||
[General]
|
||||
__userfile__=true
|
||||
@@ -0,0 +1,4 @@
|
||||
[General]
|
||||
__userfile__=true
|
||||
icon_theme=LoginIcons
|
||||
theme=light
|
||||
@@ -0,0 +1,2 @@
|
||||
[General]
|
||||
__userfile__=true
|
||||
@@ -0,0 +1,46 @@
|
||||
[General]
|
||||
__userfile__=true
|
||||
|
||||
[desktopswitch]
|
||||
alignment=Left
|
||||
type=desktopswitch
|
||||
|
||||
[mainmenu]
|
||||
alignment=Left
|
||||
type=mainmenu
|
||||
|
||||
[panel1]
|
||||
alignment=-1
|
||||
animation-duration=0
|
||||
background-color=@Variant(\0\0\0\x43\0\xff\xff\0\0\0\0\0\0\0\0)
|
||||
background-image=
|
||||
desktop=0
|
||||
font-color=@Variant(\0\0\0\x43\0\xff\xff\0\0\0\0\0\0\0\0)
|
||||
hidable=false
|
||||
iconSize=22
|
||||
lineCount=1
|
||||
lockPanel=false
|
||||
opacity=100
|
||||
panelSize=32
|
||||
plugins=mainmenu, desktopswitch, quicklaunch, taskbar, clock, showdesktop
|
||||
position=Bottom
|
||||
reserve-space=true
|
||||
show-delay=0
|
||||
width=100
|
||||
width-percent=true
|
||||
|
||||
[quicklaunch]
|
||||
alignment=Left
|
||||
apps\1\desktop=/usr/share/applications/chromium-browser.desktop
|
||||
apps\2\desktop=/usr/share/applications/pcmanfm-qt.desktop
|
||||
apps\3\desktop=/usr/share/applications/qterminal.desktop
|
||||
apps\size=3
|
||||
type=quicklaunch
|
||||
|
||||
[showdesktop]
|
||||
alignment=Right
|
||||
type=showdesktop
|
||||
|
||||
[taskbar]
|
||||
alignment=Left
|
||||
type=taskbar
|
||||
@@ -0,0 +1,2 @@
|
||||
[General]
|
||||
__userfile__=true
|
||||
@@ -0,0 +1,2 @@
|
||||
[General]
|
||||
__userfile__=true
|
||||
@@ -0,0 +1,744 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- Do not edit this file, it will be overwritten on install.
|
||||
Copy the file to $HOME/.config/openbox/lxqt-rc.xml instead. -->
|
||||
|
||||
<openbox_config xmlns="http://openbox.org/3.4/rc"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
|
||||
<resistance>
|
||||
<strength>10</strength>
|
||||
<screen_edge_strength>20</screen_edge_strength>
|
||||
</resistance>
|
||||
|
||||
<focus>
|
||||
<focusNew>yes</focusNew>
|
||||
<!-- always try to focus new windows when they appear. other rules do
|
||||
apply -->
|
||||
<followMouse>no</followMouse>
|
||||
<!-- move focus to a window when you move the mouse into it -->
|
||||
<focusLast>yes</focusLast>
|
||||
<!-- focus the last used window when changing desktops, instead of the one
|
||||
under the mouse pointer. when followMouse is enabled -->
|
||||
<underMouse>no</underMouse>
|
||||
<!-- move focus under the mouse, even when the mouse is not moving -->
|
||||
<focusDelay>200</focusDelay>
|
||||
<!-- when followMouse is enabled, the mouse must be inside the window for
|
||||
this many milliseconds (1000 = 1 sec) before moving focus to it -->
|
||||
<raiseOnFocus>no</raiseOnFocus>
|
||||
<!-- when followMouse is enabled, and a window is given focus by moving the
|
||||
mouse into it, also raise the window -->
|
||||
</focus>
|
||||
|
||||
<placement>
|
||||
<policy>Smart</policy>
|
||||
<!-- 'Smart' or 'UnderMouse' -->
|
||||
<center>yes</center>
|
||||
<!-- whether to place windows in the center of the free area found or
|
||||
the top left corner -->
|
||||
<monitor>Primary</monitor>
|
||||
<!-- with Smart placement on a multi-monitor system, try to place new windows
|
||||
on: 'Any' - any monitor, 'Mouse' - where the mouse is, 'Active' - where
|
||||
the active window is, 'Primary' - only on the primary monitor -->
|
||||
<primaryMonitor>1</primaryMonitor>
|
||||
<!-- The monitor where Openbox should place popup dialogs such as the
|
||||
focus cycling popup, or the desktop switch popup. It can be an index
|
||||
from 1, specifying a particular monitor. Or it can be one of the
|
||||
following: 'Mouse' - where the mouse is, or
|
||||
'Active' - where the active window is -->
|
||||
</placement>
|
||||
|
||||
<theme>
|
||||
<name>Onyx</name>
|
||||
<titleLayout>NLIMC</titleLayout>
|
||||
<!--
|
||||
available characters are NDSLIMC, each can occur at most once.
|
||||
N: window icon
|
||||
L: window label (AKA title).
|
||||
I: iconify
|
||||
M: maximize
|
||||
C: close
|
||||
S: shade (roll up/down)
|
||||
D: omnipresent (on all desktops).
|
||||
-->
|
||||
<keepBorder>yes</keepBorder>
|
||||
<animateIconify>yes</animateIconify>
|
||||
<font place="ActiveWindow">
|
||||
<name>sans</name>
|
||||
<size>10</size>
|
||||
<!-- font size in points -->
|
||||
<weight>bold</weight>
|
||||
<!-- 'bold' or 'normal' -->
|
||||
<slant>normal</slant>
|
||||
<!-- 'italic' or 'normal' -->
|
||||
</font>
|
||||
<font place="InactiveWindow">
|
||||
<name>sans</name>
|
||||
<size>10</size>
|
||||
<!-- font size in points -->
|
||||
<weight>bold</weight>
|
||||
<!-- 'bold' or 'normal' -->
|
||||
<slant>normal</slant>
|
||||
<!-- 'italic' or 'normal' -->
|
||||
</font>
|
||||
<font place="MenuHeader">
|
||||
<name>sans</name>
|
||||
<size>9</size>
|
||||
<!-- font size in points -->
|
||||
<weight>normal</weight>
|
||||
<!-- 'bold' or 'normal' -->
|
||||
<slant>normal</slant>
|
||||
<!-- 'italic' or 'normal' -->
|
||||
</font>
|
||||
<font place="MenuItem">
|
||||
<name>sans</name>
|
||||
<size>9</size>
|
||||
<!-- font size in points -->
|
||||
<weight>normal</weight>
|
||||
<!-- 'bold' or 'normal' -->
|
||||
<slant>normal</slant>
|
||||
<!-- 'italic' or 'normal' -->
|
||||
</font>
|
||||
<font place="ActiveOnScreenDisplay">
|
||||
<name>sans</name>
|
||||
<size>9</size>
|
||||
<!-- font size in points -->
|
||||
<weight>bold</weight>
|
||||
<!-- 'bold' or 'normal' -->
|
||||
<slant>normal</slant>
|
||||
<!-- 'italic' or 'normal' -->
|
||||
</font>
|
||||
<font place="InactiveOnScreenDisplay">
|
||||
<name>sans</name>
|
||||
<size>9</size>
|
||||
<!-- font size in points -->
|
||||
<weight>bold</weight>
|
||||
<!-- 'bold' or 'normal' -->
|
||||
<slant>normal</slant>
|
||||
<!-- 'italic' or 'normal' -->
|
||||
</font>
|
||||
</theme>
|
||||
|
||||
<desktops>
|
||||
<!-- this stuff is only used at startup, pagers allow you to change them
|
||||
during a session
|
||||
|
||||
these are default values to use when other ones are not already set
|
||||
by other applications, or saved in your session
|
||||
|
||||
use obconf if you want to change these without having to log out
|
||||
and back in -->
|
||||
<number>2</number>
|
||||
<firstdesk>1</firstdesk>
|
||||
<names>
|
||||
<!-- set names up here if you want to, like this:
|
||||
<name>desktop 1</name>
|
||||
<name>desktop 2</name>
|
||||
-->
|
||||
</names>
|
||||
<popupTime>875</popupTime>
|
||||
<!-- The number of milliseconds to show the popup for when switching
|
||||
desktops. Set this to 0 to disable the popup. -->
|
||||
</desktops>
|
||||
|
||||
<resize>
|
||||
<drawContents>yes</drawContents>
|
||||
<popupShow>Nonpixel</popupShow>
|
||||
<!-- 'Always', 'Never', or 'Nonpixel' (xterms and such) -->
|
||||
<popupPosition>Center</popupPosition>
|
||||
<!-- 'Center', 'Top', or 'Fixed' -->
|
||||
<popupFixedPosition>
|
||||
<!-- these are used if popupPosition is set to 'Fixed' -->
|
||||
|
||||
<x>10</x>
|
||||
<!-- positive number for distance from left edge, negative number for
|
||||
distance from right edge, or 'Center' -->
|
||||
<y>10</y>
|
||||
<!-- positive number for distance from top edge, negative number for
|
||||
distance from bottom edge, or 'Center' -->
|
||||
</popupFixedPosition>
|
||||
</resize>
|
||||
|
||||
<!-- You can reserve a portion of your screen where windows will not cover when
|
||||
they are maximized, or when they are initially placed.
|
||||
Many programs reserve space automatically, but you can use this in other
|
||||
cases. -->
|
||||
<margins>
|
||||
<top>0</top>
|
||||
<bottom>0</bottom>
|
||||
<left>0</left>
|
||||
<right>0</right>
|
||||
</margins>
|
||||
|
||||
<dock>
|
||||
<position>TopLeft</position>
|
||||
<!-- (Top|Bottom)(Left|Right|)|Top|Bottom|Left|Right|Floating -->
|
||||
<floatingX>0</floatingX>
|
||||
<floatingY>0</floatingY>
|
||||
<noStrut>no</noStrut>
|
||||
<stacking>Above</stacking>
|
||||
<!-- 'Above', 'Normal', or 'Below' -->
|
||||
<direction>Vertical</direction>
|
||||
<!-- 'Vertical' or 'Horizontal' -->
|
||||
<autoHide>no</autoHide>
|
||||
<hideDelay>300</hideDelay>
|
||||
<!-- in milliseconds (1000 = 1 second) -->
|
||||
<showDelay>300</showDelay>
|
||||
<!-- in milliseconds (1000 = 1 second) -->
|
||||
<moveButton>Middle</moveButton>
|
||||
<!-- 'Left', 'Middle', 'Right' -->
|
||||
</dock>
|
||||
|
||||
<keyboard>
|
||||
<chainQuitKey>C-g</chainQuitKey>
|
||||
|
||||
<!-- Keybindings for desktop switching -->
|
||||
<keybind key="C-A-Left">
|
||||
<action name="GoToDesktop"><to>left</to><wrap>no</wrap></action>
|
||||
</keybind>
|
||||
<keybind key="C-A-Right">
|
||||
<action name="GoToDesktop"><to>right</to><wrap>no</wrap></action>
|
||||
</keybind>
|
||||
<keybind key="C-A-Up">
|
||||
<action name="GoToDesktop"><to>up</to><wrap>no</wrap></action>
|
||||
</keybind>
|
||||
<keybind key="C-A-Down">
|
||||
<action name="GoToDesktop"><to>down</to><wrap>no</wrap></action>
|
||||
</keybind>
|
||||
<keybind key="S-A-Left">
|
||||
<action name="SendToDesktop"><to>left</to><wrap>no</wrap></action>
|
||||
</keybind>
|
||||
<keybind key="S-A-Right">
|
||||
<action name="SendToDesktop"><to>right</to><wrap>no</wrap></action>
|
||||
</keybind>
|
||||
<keybind key="S-A-Up">
|
||||
<action name="SendToDesktop"><to>up</to><wrap>no</wrap></action>
|
||||
</keybind>
|
||||
<keybind key="S-A-Down">
|
||||
<action name="SendToDesktop"><to>down</to><wrap>no</wrap></action>
|
||||
</keybind>
|
||||
<keybind key="W-F1">
|
||||
<action name="GoToDesktop"><to>1</to></action>
|
||||
</keybind>
|
||||
<keybind key="W-F2">
|
||||
<action name="GoToDesktop"><to>2</to></action>
|
||||
</keybind>
|
||||
<keybind key="W-F3">
|
||||
<action name="GoToDesktop"><to>3</to></action>
|
||||
</keybind>
|
||||
<keybind key="W-F4">
|
||||
<action name="GoToDesktop"><to>4</to></action>
|
||||
</keybind>
|
||||
<keybind key="W-d">
|
||||
<action name="ToggleShowDesktop"/>
|
||||
</keybind>
|
||||
|
||||
<!-- Keybindings for windows -->
|
||||
<keybind key="A-F4">
|
||||
<action name="Close"/>
|
||||
</keybind>
|
||||
<keybind key="A-Escape">
|
||||
<action name="Lower"/>
|
||||
<action name="FocusToBottom"/>
|
||||
<action name="Unfocus"/>
|
||||
</keybind>
|
||||
<keybind key="A-space">
|
||||
<action name="ShowMenu"><menu>client-menu</menu></action>
|
||||
</keybind>
|
||||
|
||||
<!-- Keybindings for window switching -->
|
||||
<keybind key="A-Tab">
|
||||
<action name="NextWindow">
|
||||
<finalactions>
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
<action name="Unshade"/>
|
||||
</finalactions>
|
||||
</action>
|
||||
</keybind>
|
||||
<keybind key="A-S-Tab">
|
||||
<action name="PreviousWindow">
|
||||
<finalactions>
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
<action name="Unshade"/>
|
||||
</finalactions>
|
||||
</action>
|
||||
</keybind>
|
||||
<keybind key="C-A-Tab">
|
||||
<action name="NextWindow">
|
||||
<panels>yes</panels><desktop>yes</desktop>
|
||||
<finalactions>
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
<action name="Unshade"/>
|
||||
</finalactions>
|
||||
</action>
|
||||
</keybind>
|
||||
|
||||
<!-- Keybindings for window switching with the arrow keys -->
|
||||
<keybind key="W-S-Right">
|
||||
<action name="DirectionalCycleWindows">
|
||||
<direction>right</direction>
|
||||
</action>
|
||||
</keybind>
|
||||
<keybind key="W-S-Left">
|
||||
<action name="DirectionalCycleWindows">
|
||||
<direction>left</direction>
|
||||
</action>
|
||||
</keybind>
|
||||
<keybind key="W-S-Up">
|
||||
<action name="DirectionalCycleWindows">
|
||||
<direction>up</direction>
|
||||
</action>
|
||||
</keybind>
|
||||
<keybind key="W-S-Down">
|
||||
<action name="DirectionalCycleWindows">
|
||||
<direction>down</direction>
|
||||
</action>
|
||||
</keybind>
|
||||
|
||||
<!-- Keybindings for running applications.
|
||||
Commented out as application shortcuts should be handled by lxqt-globalkeys in LXQt sessions.
|
||||
<keybind key="W-q">
|
||||
<action name="Execute">
|
||||
<startupnotify>
|
||||
<enabled>true</enabled>
|
||||
<name>Qupzilla</name>
|
||||
</startupnotify>
|
||||
<command>qupzilla</command>
|
||||
</action>
|
||||
</keybind> -->
|
||||
</keyboard>
|
||||
|
||||
<mouse>
|
||||
<dragThreshold>1</dragThreshold>
|
||||
<!-- number of pixels the mouse must move before a drag begins -->
|
||||
<doubleClickTime>500</doubleClickTime>
|
||||
<!-- in milliseconds (1000 = 1 second) -->
|
||||
<screenEdgeWarpTime>400</screenEdgeWarpTime>
|
||||
<!-- Time before changing desktops when the pointer touches the edge of the
|
||||
screen while moving a window, in milliseconds (1000 = 1 second).
|
||||
Set this to 0 to disable warping -->
|
||||
<screenEdgeWarpMouse>false</screenEdgeWarpMouse>
|
||||
<!-- Set this to TRUE to move the mouse pointer across the desktop when
|
||||
switching due to hitting the edge of the screen -->
|
||||
|
||||
<context name="Frame">
|
||||
<mousebind button="A-Left" action="Press">
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
</mousebind>
|
||||
<mousebind button="A-Left" action="Click">
|
||||
<action name="Unshade"/>
|
||||
</mousebind>
|
||||
<mousebind button="A-Left" action="Drag">
|
||||
<action name="Move"/>
|
||||
</mousebind>
|
||||
|
||||
<mousebind button="A-Right" action="Press">
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
<action name="Unshade"/>
|
||||
</mousebind>
|
||||
<mousebind button="A-Right" action="Drag">
|
||||
<action name="Resize"/>
|
||||
</mousebind>
|
||||
|
||||
<mousebind button="A-Middle" action="Press">
|
||||
<action name="Lower"/>
|
||||
<action name="FocusToBottom"/>
|
||||
<action name="Unfocus"/>
|
||||
</mousebind>
|
||||
|
||||
<mousebind button="A-Up" action="Click">
|
||||
<action name="GoToDesktop"><to>previous</to></action>
|
||||
</mousebind>
|
||||
<mousebind button="A-Down" action="Click">
|
||||
<action name="GoToDesktop"><to>next</to></action>
|
||||
</mousebind>
|
||||
<mousebind button="C-A-Up" action="Click">
|
||||
<action name="GoToDesktop"><to>previous</to></action>
|
||||
</mousebind>
|
||||
<mousebind button="C-A-Down" action="Click">
|
||||
<action name="GoToDesktop"><to>next</to></action>
|
||||
</mousebind>
|
||||
<mousebind button="A-S-Up" action="Click">
|
||||
<action name="SendToDesktop"><to>previous</to></action>
|
||||
</mousebind>
|
||||
<mousebind button="A-S-Down" action="Click">
|
||||
<action name="SendToDesktop"><to>next</to></action>
|
||||
</mousebind>
|
||||
</context>
|
||||
|
||||
<context name="Titlebar">
|
||||
<mousebind button="Left" action="Drag">
|
||||
<action name="Move"/>
|
||||
</mousebind>
|
||||
<mousebind button="Left" action="DoubleClick">
|
||||
<action name="ToggleMaximize"/>
|
||||
</mousebind>
|
||||
|
||||
<mousebind button="Up" action="Click">
|
||||
<action name="if">
|
||||
<shaded>no</shaded>
|
||||
<then>
|
||||
<action name="Shade"/>
|
||||
<action name="FocusToBottom"/>
|
||||
<action name="Unfocus"/>
|
||||
<action name="Lower"/>
|
||||
</then>
|
||||
</action>
|
||||
</mousebind>
|
||||
<mousebind button="Down" action="Click">
|
||||
<action name="if">
|
||||
<shaded>yes</shaded>
|
||||
<then>
|
||||
<action name="Unshade"/>
|
||||
<action name="Raise"/>
|
||||
</then>
|
||||
</action>
|
||||
</mousebind>
|
||||
</context>
|
||||
|
||||
<context name="Titlebar Top Right Bottom Left TLCorner TRCorner BRCorner BLCorner">
|
||||
<mousebind button="Left" action="Press">
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
<action name="Unshade"/>
|
||||
</mousebind>
|
||||
|
||||
<mousebind button="Middle" action="Press">
|
||||
<action name="Lower"/>
|
||||
<action name="FocusToBottom"/>
|
||||
<action name="Unfocus"/>
|
||||
</mousebind>
|
||||
|
||||
<mousebind button="Right" action="Press">
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
<action name="ShowMenu"><menu>client-menu</menu></action>
|
||||
</mousebind>
|
||||
</context>
|
||||
|
||||
<context name="Top">
|
||||
<mousebind button="Left" action="Drag">
|
||||
<action name="Resize"><edge>top</edge></action>
|
||||
</mousebind>
|
||||
</context>
|
||||
|
||||
<context name="Left">
|
||||
<mousebind button="Left" action="Drag">
|
||||
<action name="Resize"><edge>left</edge></action>
|
||||
</mousebind>
|
||||
</context>
|
||||
|
||||
<context name="Right">
|
||||
<mousebind button="Left" action="Drag">
|
||||
<action name="Resize"><edge>right</edge></action>
|
||||
</mousebind>
|
||||
</context>
|
||||
|
||||
<context name="Bottom">
|
||||
<mousebind button="Left" action="Drag">
|
||||
<action name="Resize"><edge>bottom</edge></action>
|
||||
</mousebind>
|
||||
|
||||
<mousebind button="Right" action="Press">
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
<action name="ShowMenu"><menu>client-menu</menu></action>
|
||||
</mousebind>
|
||||
</context>
|
||||
|
||||
<context name="TRCorner BRCorner TLCorner BLCorner">
|
||||
<mousebind button="Left" action="Press">
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
<action name="Unshade"/>
|
||||
</mousebind>
|
||||
<mousebind button="Left" action="Drag">
|
||||
<action name="Resize"/>
|
||||
</mousebind>
|
||||
</context>
|
||||
|
||||
<context name="Client">
|
||||
<mousebind button="Left" action="Press">
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
</mousebind>
|
||||
<mousebind button="Middle" action="Press">
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
</mousebind>
|
||||
<mousebind button="Right" action="Press">
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
</mousebind>
|
||||
</context>
|
||||
|
||||
<context name="Icon">
|
||||
<mousebind button="Left" action="Press">
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
<action name="Unshade"/>
|
||||
<action name="ShowMenu"><menu>client-menu</menu></action>
|
||||
</mousebind>
|
||||
<mousebind button="Right" action="Press">
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
<action name="ShowMenu"><menu>client-menu</menu></action>
|
||||
</mousebind>
|
||||
</context>
|
||||
|
||||
<context name="AllDesktops">
|
||||
<mousebind button="Left" action="Press">
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
<action name="Unshade"/>
|
||||
</mousebind>
|
||||
<mousebind button="Left" action="Click">
|
||||
<action name="ToggleOmnipresent"/>
|
||||
</mousebind>
|
||||
</context>
|
||||
|
||||
<context name="Shade">
|
||||
<mousebind button="Left" action="Press">
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
</mousebind>
|
||||
<mousebind button="Left" action="Click">
|
||||
<action name="ToggleShade"/>
|
||||
</mousebind>
|
||||
</context>
|
||||
|
||||
<context name="Iconify">
|
||||
<mousebind button="Left" action="Press">
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
</mousebind>
|
||||
<mousebind button="Left" action="Click">
|
||||
<action name="Iconify"/>
|
||||
</mousebind>
|
||||
</context>
|
||||
|
||||
<context name="Maximize">
|
||||
<mousebind button="Left" action="Press">
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
<action name="Unshade"/>
|
||||
</mousebind>
|
||||
<mousebind button="Middle" action="Press">
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
<action name="Unshade"/>
|
||||
</mousebind>
|
||||
<mousebind button="Right" action="Press">
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
<action name="Unshade"/>
|
||||
</mousebind>
|
||||
<mousebind button="Left" action="Click">
|
||||
<action name="ToggleMaximize"/>
|
||||
</mousebind>
|
||||
<mousebind button="Middle" action="Click">
|
||||
<action name="ToggleMaximize"><direction>vertical</direction></action>
|
||||
</mousebind>
|
||||
<mousebind button="Right" action="Click">
|
||||
<action name="ToggleMaximize"><direction>horizontal</direction></action>
|
||||
</mousebind>
|
||||
</context>
|
||||
|
||||
<context name="Close">
|
||||
<mousebind button="Left" action="Press">
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
<action name="Unshade"/>
|
||||
</mousebind>
|
||||
<mousebind button="Left" action="Click">
|
||||
<action name="Close"/>
|
||||
</mousebind>
|
||||
</context>
|
||||
|
||||
<context name="Desktop">
|
||||
<mousebind button="Up" action="Click">
|
||||
<action name="GoToDesktop"><to>previous</to></action>
|
||||
</mousebind>
|
||||
<mousebind button="Down" action="Click">
|
||||
<action name="GoToDesktop"><to>next</to></action>
|
||||
</mousebind>
|
||||
|
||||
<mousebind button="A-Up" action="Click">
|
||||
<action name="GoToDesktop"><to>previous</to></action>
|
||||
</mousebind>
|
||||
<mousebind button="A-Down" action="Click">
|
||||
<action name="GoToDesktop"><to>next</to></action>
|
||||
</mousebind>
|
||||
<mousebind button="C-A-Up" action="Click">
|
||||
<action name="GoToDesktop"><to>previous</to></action>
|
||||
</mousebind>
|
||||
<mousebind button="C-A-Down" action="Click">
|
||||
<action name="GoToDesktop"><to>next</to></action>
|
||||
</mousebind>
|
||||
|
||||
<mousebind button="Left" action="Press">
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
</mousebind>
|
||||
<mousebind button="Right" action="Press">
|
||||
<action name="Focus"/>
|
||||
<action name="Raise"/>
|
||||
</mousebind>
|
||||
</context>
|
||||
|
||||
<context name="Root">
|
||||
<!-- Menus -->
|
||||
<mousebind button="Middle" action="Press">
|
||||
<action name="ShowMenu"><menu>client-list-combined-menu</menu></action>
|
||||
</mousebind>
|
||||
<mousebind button="Right" action="Press">
|
||||
<action name="ShowMenu"><menu>root-menu</menu></action>
|
||||
</mousebind>
|
||||
</context>
|
||||
|
||||
<context name="MoveResize">
|
||||
<mousebind button="Up" action="Click">
|
||||
<action name="GoToDesktop"><to>previous</to></action>
|
||||
</mousebind>
|
||||
<mousebind button="Down" action="Click">
|
||||
<action name="GoToDesktop"><to>next</to></action>
|
||||
</mousebind>
|
||||
<mousebind button="A-Up" action="Click">
|
||||
<action name="GoToDesktop"><to>previous</to></action>
|
||||
</mousebind>
|
||||
<mousebind button="A-Down" action="Click">
|
||||
<action name="GoToDesktop"><to>next</to></action>
|
||||
</mousebind>
|
||||
</context>
|
||||
</mouse>
|
||||
|
||||
<menu>
|
||||
<!-- You can specify more than one menu file in here and they are all loaded,
|
||||
just don't make menu ids clash or, well, it'll be kind of pointless -->
|
||||
|
||||
<!-- default menu file (or custom one in $HOME/.config/openbox/) -->
|
||||
<file>menu.xml</file>
|
||||
<hideDelay>200</hideDelay>
|
||||
<!-- if a press-release lasts longer than this setting (in milliseconds), the
|
||||
menu is hidden again -->
|
||||
<middle>no</middle>
|
||||
<!-- center submenus vertically about the parent entry -->
|
||||
<submenuShowDelay>100</submenuShowDelay>
|
||||
<!-- time to delay before showing a submenu after hovering over the parent
|
||||
entry.
|
||||
if this is a negative value, then the delay is infinite and the
|
||||
submenu will not be shown until it is clicked on -->
|
||||
<submenuHideDelay>400</submenuHideDelay>
|
||||
<!-- time to delay before hiding a submenu when selecting another
|
||||
entry in parent menu
|
||||
if this is a negative value, then the delay is infinite and the
|
||||
submenu will not be hidden until a different submenu is opened -->
|
||||
<showIcons>yes</showIcons>
|
||||
<!-- controls if icons appear in the client-list-(combined-)menu -->
|
||||
<manageDesktops>yes</manageDesktops>
|
||||
<!-- show the manage desktops section in the client-list-(combined-)menu -->
|
||||
</menu>
|
||||
|
||||
<applications>
|
||||
<!--
|
||||
# this is an example with comments through out. use these to make your
|
||||
# own rules, but without the comments of course.
|
||||
# you may use one or more of the name/class/role/title/type rules to specify
|
||||
# windows to match
|
||||
|
||||
<application name="the window's _OB_APP_NAME property (see obxprop)"
|
||||
class="the window's _OB_APP_CLASS property (see obxprop)"
|
||||
groupname="the window's _OB_APP_GROUP_NAME property (see obxprop)"
|
||||
groupclass="the window's _OB_APP_GROUP_CLASS property (see obxprop)"
|
||||
role="the window's _OB_APP_ROLE property (see obxprop)"
|
||||
title="the window's _OB_APP_TITLE property (see obxprop)"
|
||||
type="the window's _OB_APP_TYPE property (see obxprob)..
|
||||
(if unspecified, then it is 'dialog' for child windows)">
|
||||
# you may set only one of name/class/role/title/type, or you may use more
|
||||
# than one together to restrict your matches.
|
||||
|
||||
# the name, class, role, and title use simple wildcard matching such as those
|
||||
# used by a shell. you can use * to match any characters and ? to match
|
||||
# any single character.
|
||||
|
||||
# the type is one of: normal, dialog, splash, utility, menu, toolbar, dock,
|
||||
# or desktop
|
||||
|
||||
# when multiple rules match a window, they will all be applied, in the
|
||||
# order that they appear in this list
|
||||
|
||||
|
||||
# each rule element can be left out or set to 'default' to specify to not
|
||||
# change that attribute of the window
|
||||
|
||||
<decor>yes</decor>
|
||||
# enable or disable window decorations
|
||||
|
||||
<shade>no</shade>
|
||||
# make the window shaded when it appears, or not
|
||||
|
||||
<position force="no">
|
||||
# the position is only used if both an x and y coordinate are provided
|
||||
# (and not set to 'default')
|
||||
# when force is "yes", then the window will be placed here even if it
|
||||
# says you want it placed elsewhere. this is to override buggy
|
||||
# applications who refuse to behave
|
||||
<x>center</x>
|
||||
# a number like 50, or 'center' to center on screen. use a negative number
|
||||
# to start from the right (or bottom for <y>), ie -50 is 50 pixels from
|
||||
# the right edge (or bottom). use 'default' to specify using value
|
||||
# provided by the application, or chosen by openbox, instead.
|
||||
<y>200</y>
|
||||
<monitor>1</monitor>
|
||||
# specifies the monitor in a xinerama setup.
|
||||
# 1 is the first head, or 'mouse' for wherever the mouse is
|
||||
</position>
|
||||
|
||||
<size>
|
||||
# the size to make the window.
|
||||
<width>20</width>
|
||||
# a number like 20, or 'default' to use the size given by the application.
|
||||
# you can use fractions such as 1/2 or percentages such as 75% in which
|
||||
# case the value is relative to the size of the monitor that the window
|
||||
# appears on.
|
||||
<height>30%</height>
|
||||
</size>
|
||||
|
||||
<focus>yes</focus>
|
||||
# if the window should try be given focus when it appears. if this is set
|
||||
# to yes it doesn't guarantee the window will be given focus. some
|
||||
# restrictions may apply, but Openbox will try to
|
||||
|
||||
<desktop>1</desktop>
|
||||
# 1 is the first desktop, 'all' for all desktops
|
||||
|
||||
<layer>normal</layer>
|
||||
# 'above', 'normal', or 'below'
|
||||
|
||||
<iconic>no</iconic>
|
||||
# make the window iconified when it appears, or not
|
||||
|
||||
<skip_pager>no</skip_pager>
|
||||
# asks to not be shown in pagers
|
||||
|
||||
<skip_taskbar>no</skip_taskbar>
|
||||
# asks to not be shown in taskbars. window cycling actions will also
|
||||
# skip past such windows
|
||||
|
||||
<fullscreen>yes</fullscreen>
|
||||
# make the window in fullscreen mode when it appears
|
||||
|
||||
<maximized>true</maximized>
|
||||
# 'Horizontal', 'Vertical' or boolean (yes/no)
|
||||
</application>
|
||||
|
||||
# end of the example
|
||||
-->
|
||||
</applications>
|
||||
|
||||
</openbox_config>
|
||||
@@ -0,0 +1,98 @@
|
||||
[Behavior]
|
||||
AutoSelectionDelay=600
|
||||
BookmarkOpenMethod=current_tab
|
||||
ConfirmDelete=true
|
||||
ConfirmTrash=false
|
||||
NoUsbTrash=false
|
||||
QuickExec=false
|
||||
SingleClick=false
|
||||
UseTrash=true
|
||||
|
||||
[Desktop]
|
||||
BgColor=#000000
|
||||
DesktopCellMargins=@Size(3 1)
|
||||
DesktopIconSize=48
|
||||
FgColor=#ffffff
|
||||
Font="Sans Serif,10,-1,5,50,0,0,0,0,0"
|
||||
LastSlide=
|
||||
ShadowColor=#000000
|
||||
ShowHidden=false
|
||||
ShowWmMenu=false
|
||||
SlideShowInterval=0
|
||||
SortColumn=name
|
||||
SortFolderFirst=true
|
||||
SortOrder=ascending
|
||||
Wallpaper=/usr/share/lxqt/themes/light/simple_blue_widescreen.png
|
||||
WallpaperDirectory=
|
||||
WallpaperMode=stretch
|
||||
WallpaperRandomize=false
|
||||
|
||||
[FolderView]
|
||||
BackupAsHidden=false
|
||||
BigIconSize=48
|
||||
FolderViewCellMargins=@Size(3 3)
|
||||
Mode=icon
|
||||
ShadowHidden=false
|
||||
ShowFilter=false
|
||||
ShowFullNames=false
|
||||
ShowHidden=false
|
||||
SidePaneIconSize=24
|
||||
SmallIconSize=24
|
||||
SortCaseSensitive=false
|
||||
SortColumn=name
|
||||
SortFolderFirst=true
|
||||
SortOrder=ascending
|
||||
ThumbnailIconSize=128
|
||||
|
||||
[Places]
|
||||
PlacesApplications=true
|
||||
PlacesComputer=true
|
||||
PlacesDesktop=true
|
||||
PlacesHome=true
|
||||
PlacesNetwork=true
|
||||
PlacesRoot=true
|
||||
PlacesTrash=true
|
||||
|
||||
[Search]
|
||||
searchContentCaseInsensitive=false
|
||||
searchContentRegexp=true
|
||||
searchNameCaseInsensitive=false
|
||||
searchNameRegexp=true
|
||||
searchRecursive=false
|
||||
searchhHidden=false
|
||||
|
||||
[System]
|
||||
Archiver=file-roller
|
||||
FallbackIconThemeName=oxygen
|
||||
OnlyUserTemplates=false
|
||||
SIUnit=false
|
||||
SuCommand=lxqt-sudo %s
|
||||
TemplateRunApp=false
|
||||
TemplateTypeOnce=false
|
||||
Terminal=xterm
|
||||
|
||||
[Thumbnail]
|
||||
MaxThumbnailFileSize=4096
|
||||
ShowThumbnails=true
|
||||
ThumbnailLocalFilesOnly=true
|
||||
|
||||
[Volume]
|
||||
AutoRun=true
|
||||
CloseOnUnmount=true
|
||||
MountOnStartup=true
|
||||
MountRemovable=true
|
||||
|
||||
[Window]
|
||||
AlwaysShowTabs=false
|
||||
FixedHeight=480
|
||||
FixedWidth=640
|
||||
FullWidthTabBar=true
|
||||
LastWindowHeight=480
|
||||
LastWindowMaximized=false
|
||||
LastWindowWidth=640
|
||||
PathBarButtons=true
|
||||
RememberWindowSize=true
|
||||
ShowMenuBar=true
|
||||
ShowTabClose=true
|
||||
SidePaneMode=places
|
||||
SplitterPos=150
|
||||
@@ -0,0 +1 @@
|
||||
/usr/local/share/doro-lxde-wallpapers/desktop-items-0.conf
|
||||
@@ -0,0 +1 @@
|
||||
/tmp/pulse-PKdhtXMmr18n
|
||||
@@ -0,0 +1,12 @@
|
||||
[General]
|
||||
HideTabBarWithOneTab=false
|
||||
TerminalTransparency=0
|
||||
version=0.8.0
|
||||
|
||||
[MainWindow]
|
||||
ApplicationTransparency=0
|
||||
pos=@Point(0 0)
|
||||
size=@Size(640 480)
|
||||
|
||||
[Shortcuts]
|
||||
Paste%20Clipboard=Ctrl+Shift+V
|
||||
@@ -0,0 +1,20 @@
|
||||
# DO NOT EDIT! This file will be overwritten by LXAppearance.
|
||||
# Any customization should be done in ~/.gtkrc-2.0.mine instead.
|
||||
include "/usr/share/themes/Arc/gtk-2.0/gtkrc"
|
||||
|
||||
gtk-theme-name="Arc"
|
||||
gtk-icon-theme-name="nuoveXT2"
|
||||
gtk-font-name="Sans 10"
|
||||
gtk-cursor-theme-name="DMZ-White"
|
||||
gtk-cursor-theme-size=18
|
||||
gtk-toolbar-style=GTK_TOOLBAR_BOTH_HORIZ
|
||||
gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR
|
||||
gtk-button-images=1
|
||||
gtk-menu-images=1
|
||||
gtk-enable-event-sounds=1
|
||||
gtk-enable-input-feedback-sounds=1
|
||||
gtk-xft-antialias=1
|
||||
gtk-xft-hinting=1
|
||||
gtk-xft-hintstyle="hintslight"
|
||||
gtk-xft-rgba="rgb"
|
||||
include "/root/.gtkrc-2.0.mine"
|
||||
Executable
+74
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ -n "$VNC_PASSWORD" ]; then
|
||||
echo -n "$VNC_PASSWORD" > /.password1
|
||||
x11vnc -storepasswd $(cat /.password1) /.password2
|
||||
chmod 400 /.password*
|
||||
sed -i 's/^command=x11vnc.*/& -rfbauth \/.password2/' /etc/supervisor/conf.d/supervisord.conf
|
||||
export VNC_PASSWORD=
|
||||
fi
|
||||
|
||||
if [ -n "$X11VNC_ARGS" ]; then
|
||||
sed -i "s/^command=x11vnc.*/& ${X11VNC_ARGS}/" /etc/supervisor/conf.d/supervisord.conf
|
||||
fi
|
||||
|
||||
if [ -n "$OPENBOX_ARGS" ]; then
|
||||
sed -i "s#^command=/usr/bin/openbox.*#& ${OPENBOX_ARGS}#" /etc/supervisor/conf.d/supervisord.conf
|
||||
fi
|
||||
|
||||
if [ -n "$RESOLUTION" ]; then
|
||||
sed -i "s/1024x768/$RESOLUTION/" /usr/local/bin/xvfb.sh
|
||||
fi
|
||||
|
||||
USER=${USER:-root}
|
||||
HOME=/root
|
||||
if [ "$USER" != "root" ]; then
|
||||
echo "* enable custom user: $USER"
|
||||
useradd --create-home --shell /bin/bash --user-group --groups adm,sudo $USER
|
||||
if [ -z "$PASSWORD" ]; then
|
||||
echo " set default password to \"ubuntu\""
|
||||
PASSWORD=ubuntu
|
||||
fi
|
||||
HOME=/home/$USER
|
||||
echo "$USER:$PASSWORD" | chpasswd
|
||||
cp -r /root/{.config,.gtkrc-2.0,.asoundrc} ${HOME}
|
||||
[ -d "/dev/snd" ] && chgrp -R adm /dev/snd
|
||||
fi
|
||||
sed -i -e "s|%USER%|$USER|" -e "s|%HOME%|$HOME|" /etc/supervisor/conf.d/supervisord.conf
|
||||
|
||||
# home folder
|
||||
if [ ! -x "$HOME/.config/pcmanfm/LXDE/" ]; then
|
||||
mkdir -p $HOME/.config/pcmanfm/LXDE/
|
||||
ln -sf /usr/local/share/doro-lxde-wallpapers/desktop-items-0.conf $HOME/.config/pcmanfm/LXDE/
|
||||
chown -R $USER:$USER $HOME
|
||||
fi
|
||||
|
||||
# nginx workers
|
||||
sed -i 's|worker_processes .*|worker_processes 1;|' /etc/nginx/nginx.conf
|
||||
|
||||
# nginx ssl
|
||||
if [ -n "$SSL_PORT" ] && [ -e "/etc/nginx/ssl/nginx.key" ]; then
|
||||
echo "* enable SSL"
|
||||
sed -i 's|#_SSL_PORT_#\(.*\)443\(.*\)|\1'$SSL_PORT'\2|' /etc/nginx/sites-enabled/default
|
||||
sed -i 's|#_SSL_PORT_#||' /etc/nginx/sites-enabled/default
|
||||
fi
|
||||
|
||||
# nginx http base authentication
|
||||
if [ -n "$HTTP_PASSWORD" ]; then
|
||||
echo "* enable HTTP base authentication"
|
||||
htpasswd -bc /etc/nginx/.htpasswd $USER $HTTP_PASSWORD
|
||||
sed -i 's|#_HTTP_PASSWORD_#||' /etc/nginx/sites-enabled/default
|
||||
fi
|
||||
|
||||
# dynamic prefix path renaming
|
||||
if [ -n "$RELATIVE_URL_ROOT" ]; then
|
||||
echo "* enable RELATIVE_URL_ROOT: $RELATIVE_URL_ROOT"
|
||||
sed -i 's|#_RELATIVE_URL_ROOT_||' /etc/nginx/sites-enabled/default
|
||||
sed -i 's|_RELATIVE_URL_ROOT_|'$RELATIVE_URL_ROOT'|' /etc/nginx/sites-enabled/default
|
||||
fi
|
||||
|
||||
# clearup
|
||||
PASSWORD=
|
||||
HTTP_PASSWORD=
|
||||
|
||||
exec /bin/tini -- supervisord -n -c /etc/supervisor/supervisord.conf
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -z "$ALSADEV" ]; then
|
||||
zenity --error --text "To support audio, please read README.md and run container with --device /dev/snd -e ALSADEV=..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exec /usr/bin/chromium-browser --no-sandbox --alsa-output-device="$ALSADEV" "$@"
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec /usr/bin/Xvfb :1 -screen 0 1024x768x24
|
||||
@@ -0,0 +1,11 @@
|
||||
class Default(object):
|
||||
DEBUG = True
|
||||
|
||||
|
||||
class Development(Default):
|
||||
PHASE = 'development'
|
||||
|
||||
|
||||
class Production(Default):
|
||||
PHASE = 'production'
|
||||
DEBUG = False
|
||||
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env python
|
||||
import sys
|
||||
import logging
|
||||
import logging.handlers
|
||||
|
||||
|
||||
# The terminal has 8 colors with codes from 0 to 7
|
||||
BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
|
||||
|
||||
# These are the sequences need to get colored ouput
|
||||
RESET_SEQ = "\033[0m"
|
||||
COLOR_SEQ = "\033[1;%dm"
|
||||
BOLD_SEQ = "\033[1m"
|
||||
|
||||
# The background is set with 40 plus the number of the color,
|
||||
# and the foreground with 30
|
||||
COLORS = {
|
||||
'WARNING': COLOR_SEQ % (30 + YELLOW) + 'WARN ' + RESET_SEQ,
|
||||
'INFO': COLOR_SEQ % (30 + WHITE) + 'INFO ' + RESET_SEQ,
|
||||
'DEBUG': COLOR_SEQ % (30 + BLUE) + 'DEBUG' + RESET_SEQ,
|
||||
'CRITICAL': COLOR_SEQ % (30 + YELLOW) + 'CRITI' + RESET_SEQ,
|
||||
'ERROR': COLOR_SEQ % (30 + RED) + 'ERROR' + RESET_SEQ,
|
||||
}
|
||||
|
||||
|
||||
class ColoredFormatter(logging.Formatter):
|
||||
def __init__(self, msg, use_color=True):
|
||||
logging.Formatter.__init__(self, msg)
|
||||
self.use_color = use_color
|
||||
|
||||
def format(self, record):
|
||||
if self.use_color:
|
||||
record.levelname = COLORS.get(record.levelname, record.levelname)
|
||||
return logging.Formatter.format(self, record)
|
||||
|
||||
|
||||
class LoggingConfiguration(object):
|
||||
COLOR_FORMAT = "%(asctime)s" + \
|
||||
" %(levelname)s %(message)s " + \
|
||||
"(" + BOLD_SEQ + "%(filename)s" + RESET_SEQ + ":%(lineno)d)"
|
||||
NO_COLOR_FORMAT = "%(asctime)s %(levelname)s " + \
|
||||
"%(message)s " + \
|
||||
"(%(filename)s:%(lineno)d)"
|
||||
FILE_FORMAT = "%(asctime)s %(levelname)s " + \
|
||||
"%(message)s "
|
||||
|
||||
@classmethod
|
||||
def set(cls, log_level, log_filename, append=None, **kwargs):
|
||||
""" Configure a rotating file logging
|
||||
"""
|
||||
logger = logging.getLogger()
|
||||
logger.setLevel(log_level)
|
||||
|
||||
COLOR_FORMAT = cls.COLOR_FORMAT
|
||||
NO_COLOR_FORMAT = cls.NO_COLOR_FORMAT
|
||||
FILE_FORMAT = cls.FILE_FORMAT
|
||||
if 'name' in kwargs:
|
||||
COLOR_FORMAT = COLOR_FORMAT.replace('%(threadName)-22s',
|
||||
'%-22s' % (kwargs['name']))
|
||||
NO_COLOR_FORMAT = NO_COLOR_FORMAT.replace(
|
||||
'%(threadName)-22s', '%-22s' % (kwargs['name']))
|
||||
FILE_FORMAT = FILE_FORMAT.replace(
|
||||
'%(threadName)-22s', '%s' % (kwargs['name']))
|
||||
|
||||
# Log to rotating file
|
||||
try:
|
||||
fh = logging.handlers.RotatingFileHandler(
|
||||
log_filename,
|
||||
mode='a+',
|
||||
backupCount=3
|
||||
)
|
||||
fh.setFormatter(ColoredFormatter(FILE_FORMAT, False))
|
||||
fh.setLevel(log_level)
|
||||
logger.addHandler(fh)
|
||||
if not append:
|
||||
# Create a new log file on every new
|
||||
fh.doRollover()
|
||||
except IOError as e:
|
||||
print('ignore to log to {}: {}'.format(log_filename, e))
|
||||
|
||||
# Log to sys.stderr using log level passed through command line
|
||||
if log_level != logging.NOTSET:
|
||||
log_handler = logging.StreamHandler(sys.stdout)
|
||||
if sys.platform.find('linux') >= 0:
|
||||
formatter = ColoredFormatter(COLOR_FORMAT)
|
||||
else:
|
||||
formatter = ColoredFormatter(NO_COLOR_FORMAT, False)
|
||||
log_handler.setFormatter(formatter)
|
||||
log_handler.setLevel(log_level)
|
||||
logger.addHandler(log_handler)
|
||||
@@ -0,0 +1,20 @@
|
||||
backports.ssl-match-hostname==3.7.0.1
|
||||
certifi==2019.9.11
|
||||
chardet==3.0.4
|
||||
Click==7.0
|
||||
Flask==1.1.1
|
||||
Flask-Login==0.4.1
|
||||
gevent==1.4.0
|
||||
gevent-websocket==0.10.1
|
||||
greenlet==0.4.15
|
||||
idna==2.8
|
||||
itsdangerous==1.1.0
|
||||
Jinja2==2.10.3
|
||||
MarkupSafe==1.1.1
|
||||
meld3==2.0.0
|
||||
requests==2.22.0
|
||||
six==1.12.0
|
||||
supervisor==4.1.0
|
||||
urllib3==1.25.6
|
||||
websocket-client==0.47.0
|
||||
Werkzeug==0.16.0
|
||||
Executable
+122
@@ -0,0 +1,122 @@
|
||||
#!/usr/bin/env python
|
||||
from __future__ import (
|
||||
absolute_import, division, print_function, with_statement
|
||||
)
|
||||
import os
|
||||
import time
|
||||
import sys
|
||||
import subprocess
|
||||
from vnc.util import ignored
|
||||
|
||||
|
||||
def main():
|
||||
def run_with_reloader(main_func, extra_files=None, interval=3):
|
||||
"""Run the given function in an independent python interpreter."""
|
||||
def find_files(directory="./"):
|
||||
for root, dirs, files in os.walk(directory):
|
||||
for basename in files:
|
||||
if basename.endswith('.py'):
|
||||
filename = os.path.join(root, basename)
|
||||
yield filename
|
||||
|
||||
if os.environ.get('WERKZEUG_RUN_MAIN') == 'true':
|
||||
try:
|
||||
main_func()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
return
|
||||
|
||||
proc = None
|
||||
try:
|
||||
while True:
|
||||
log.info('Restarting with reloader {} {}'.format(
|
||||
sys.executable,
|
||||
' '.join(sys.argv))
|
||||
)
|
||||
args = [sys.executable] + sys.argv
|
||||
new_environ = os.environ.copy()
|
||||
new_environ['WERKZEUG_RUN_MAIN'] = 'true'
|
||||
|
||||
proc = subprocess.Popen(
|
||||
args,
|
||||
env=new_environ,
|
||||
close_fds=True,
|
||||
preexec_fn=os.setsid
|
||||
)
|
||||
mtimes = {}
|
||||
restart = False
|
||||
while not restart:
|
||||
for filename in find_files():
|
||||
try:
|
||||
mtime = os.stat(filename).st_mtime
|
||||
except OSError:
|
||||
continue
|
||||
|
||||
old_time = mtimes.get(filename)
|
||||
if old_time is None:
|
||||
mtimes[filename] = mtime
|
||||
continue
|
||||
elif mtime > old_time:
|
||||
log.info(
|
||||
'Detected change in {}, reloading'.format(
|
||||
filename
|
||||
)
|
||||
)
|
||||
restart = True
|
||||
proc.terminate()
|
||||
break
|
||||
time.sleep(interval)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
finally:
|
||||
with ignored(Exception):
|
||||
proc.terminate()
|
||||
|
||||
def run_server():
|
||||
import socket
|
||||
from gevent.pywsgi import WSGIServer
|
||||
from vnc.app import app
|
||||
|
||||
# websocket conflict: WebSocketHandler
|
||||
if DEBUG:
|
||||
# from werkzeug.debug import DebuggedApplication
|
||||
app.debug = True
|
||||
# app = DebuggedApplication(app, evalex=True)
|
||||
|
||||
try:
|
||||
log.info('Listening on http://localhost:{}'.format(PORT))
|
||||
http_server = WSGIServer(('localhost', PORT), app)
|
||||
http_server.serve_forever()
|
||||
# app.run(host='localhost', port=PORT)
|
||||
except socket.error as e:
|
||||
log.exception(e)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
finally:
|
||||
http_server.stop(timeout=10)
|
||||
log.info('shutdown gracefully')
|
||||
|
||||
PORT = 6079
|
||||
DEBUG = False
|
||||
os.environ['CONFIG'] = 'config.Production'
|
||||
entrypoint = run_server
|
||||
if '--debug' in sys.argv:
|
||||
DEBUG = True
|
||||
os.environ['CONFIG'] = 'config.Development'
|
||||
entrypoint = lambda: run_with_reloader(run_server)
|
||||
|
||||
# logging
|
||||
import logging
|
||||
from log.config import LoggingConfiguration
|
||||
LoggingConfiguration.set(
|
||||
logging.DEBUG if DEBUG else logging.INFO,
|
||||
'/var/log/web.log'
|
||||
)
|
||||
logging.getLogger("werkzeug").setLevel(logging.WARNING)
|
||||
log = logging.getLogger('novnc2')
|
||||
|
||||
entrypoint()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,203 @@
|
||||
from __future__ import (
|
||||
absolute_import, division, print_function, with_statement
|
||||
)
|
||||
import re
|
||||
import os
|
||||
from flask import (
|
||||
Flask,
|
||||
request,
|
||||
Response,
|
||||
jsonify,
|
||||
abort,
|
||||
)
|
||||
from gevent import subprocess as gsp, spawn, sleep
|
||||
from geventwebsocket.exceptions import WebSocketError
|
||||
from .response import httperror
|
||||
from .util import ignored
|
||||
from .state import state
|
||||
from .log import log
|
||||
|
||||
|
||||
# Flask app
|
||||
app = Flask('novnc2')
|
||||
app.config.from_object('config.Default')
|
||||
app.config.from_object(os.environ.get('CONFIG') or 'config.Development')
|
||||
|
||||
|
||||
@app.route('/api/state')
|
||||
@httperror
|
||||
def apistate():
|
||||
state.wait(int(request.args.get('id', -1)), 30)
|
||||
state.switch_video(request.args.get('video', 'false') == 'true')
|
||||
mystate = state.to_dict()
|
||||
return jsonify({
|
||||
'code': 200,
|
||||
'data': mystate,
|
||||
})
|
||||
|
||||
|
||||
@app.route('/api/health')
|
||||
def apihealth():
|
||||
if state.health:
|
||||
return 'success'
|
||||
abort(503, 'unhealthy')
|
||||
|
||||
|
||||
@app.route('/api/reset')
|
||||
def reset():
|
||||
if 'w' in request.args and 'h' in request.args:
|
||||
args = {
|
||||
'w': int(request.args.get('w')),
|
||||
'h': int(request.args.get('h')),
|
||||
}
|
||||
state.set_size(args['w'], args['h'])
|
||||
|
||||
state.apply_and_restart()
|
||||
|
||||
# check all running
|
||||
for i in range(40):
|
||||
if state.health:
|
||||
break
|
||||
sleep(1)
|
||||
log.info('wait services is ready...')
|
||||
else:
|
||||
return jsonify({
|
||||
'code': 500,
|
||||
'errorMessage': 'service is not ready, please restart container'
|
||||
})
|
||||
return jsonify({'code': 200})
|
||||
|
||||
|
||||
@app.route('/resize')
|
||||
@httperror
|
||||
def apiresize():
|
||||
state.reset_size()
|
||||
return '<html><head><script type = "text/javascript">var h=window.location.href;window.location.href=h.substring(0,h.length-6);</script></head></html>'
|
||||
|
||||
|
||||
@app.route('/api/live.flv')
|
||||
@httperror
|
||||
def liveflv():
|
||||
def generate():
|
||||
xenvs = {
|
||||
'DISPLAY': ':1',
|
||||
}
|
||||
bufsize = 1024 * 1
|
||||
framerate = 20
|
||||
|
||||
# sound
|
||||
sound_cmd_input = []
|
||||
sound_cmd_parameters = []
|
||||
zero_latency_make_sound_not_good = [
|
||||
'-tune', 'zerolatency',
|
||||
]
|
||||
|
||||
xenvs['X_WIDTH'] = state.w
|
||||
xenvs['X_HEIGHT'] = state.h
|
||||
xenvs['X_WIDTH'] -= state.w % 2
|
||||
xenvs['X_HEIGHT'] -= state.h % 2
|
||||
|
||||
pixels_count = xenvs['X_WIDTH'] * xenvs['X_HEIGHT']
|
||||
# factor (720p)
|
||||
# 383: 2400k
|
||||
# 300: 3000k
|
||||
# 230: 4000k
|
||||
factor = 265
|
||||
maxbitrate_cmd = [
|
||||
'-maxrate', str(int(pixels_count / factor)) + 'k',
|
||||
'-bufsize', str(int(pixels_count / factor / 3)) + 'k'
|
||||
]
|
||||
|
||||
# TODO move to global
|
||||
# get default source
|
||||
sound_cmd_input = [
|
||||
'-f', 'alsa',
|
||||
'-i', 'hw:2,1',
|
||||
]
|
||||
sound_cmd_parameters = [
|
||||
'-ar', '44100',
|
||||
'-c:a', 'mp3',
|
||||
]
|
||||
# flv.js report error if enabling hw acceleration
|
||||
# hwaccel_dev = ['-vaapi_device', '/dev/dri/renderD128']
|
||||
# hwaccel_if = ['-vf', 'format=nv12,hwupload']
|
||||
# vcodec = 'h264_vaapi'
|
||||
hwaccel_dev = []
|
||||
hwaccel_if = []
|
||||
vcodec = 'libx264'
|
||||
# zero_latency_make_sound_not_good = []
|
||||
# sound_cmd_parameters = []
|
||||
# sound_cmd_input = []
|
||||
cmd = ['/usr/local/ffmpeg/ffmpeg'] + sound_cmd_input + hwaccel_dev + [
|
||||
'-video_size', '{X_WIDTH}x{X_HEIGHT}'.format(**xenvs),
|
||||
'-framerate', '{}'.format(framerate),
|
||||
'-f', 'x11grab', '-draw_mouse', '1',
|
||||
'-i', '{DISPLAY}'.format(**xenvs),
|
||||
] + hwaccel_if + [
|
||||
'-r', '{}'.format(framerate),
|
||||
'-g', '{}'.format(framerate),
|
||||
'-flags:v', '+global_header',
|
||||
'-vcodec', vcodec,
|
||||
'-preset', 'ultrafast',
|
||||
'-b_strategy', '0',
|
||||
'-pix_fmt', 'yuv420p',
|
||||
'-bsf:v', 'dump_extra=freq=e',
|
||||
] + maxbitrate_cmd \
|
||||
+ sound_cmd_parameters + zero_latency_make_sound_not_good + [
|
||||
'-f', 'flv', 'pipe:1',
|
||||
]
|
||||
log.info('command: ' + ' '.join(cmd))
|
||||
pobj = gsp.Popen(
|
||||
cmd,
|
||||
stdout=gsp.PIPE,
|
||||
stderr=gsp.PIPE,
|
||||
env={k: str(v) for k, v in xenvs.iteritems()},
|
||||
)
|
||||
|
||||
def readerr(f):
|
||||
reobj = re.compile(r'bitrate=(\S+)')
|
||||
global av_bitrate
|
||||
try:
|
||||
while True:
|
||||
buf = f.read(bufsize)
|
||||
if len(buf) == 0:
|
||||
break
|
||||
patterns = reobj.findall(buf.decode('utf-8', 'ignore'))
|
||||
if len(patterns) > 0:
|
||||
av_bitrate = patterns[-1]
|
||||
# log.info(str(buf))
|
||||
except Exception as e:
|
||||
log.exception(e)
|
||||
|
||||
preaderr = None
|
||||
try:
|
||||
preaderr = spawn(readerr, pobj.stderr)
|
||||
try:
|
||||
while True:
|
||||
buf = pobj.stdout.read(bufsize)
|
||||
if len(buf) == 0:
|
||||
break
|
||||
# ws.send(buf)
|
||||
yield buf
|
||||
except WebSocketError:
|
||||
pass
|
||||
except Exception as e:
|
||||
log.exception(e)
|
||||
finally:
|
||||
with ignored(Exception):
|
||||
pobj.kill()
|
||||
preaderr.join()
|
||||
except Exception as e:
|
||||
log.exception(e)
|
||||
finally:
|
||||
log.info('exiting')
|
||||
with ignored(Exception):
|
||||
pobj.kill()
|
||||
with ignored(Exception):
|
||||
preaderr.kill()
|
||||
log.info('exited')
|
||||
return Response(generate(), mimetype='video/x-flv')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host=app.config['ADDRESS'], port=app.config['PORT'])
|
||||
@@ -0,0 +1,2 @@
|
||||
import logging
|
||||
log = logging.getLogger('novnc2')
|
||||
@@ -0,0 +1,40 @@
|
||||
from __future__ import (
|
||||
absolute_import, division, print_function, with_statement
|
||||
)
|
||||
from functools import wraps
|
||||
import logging
|
||||
from flask import jsonify
|
||||
|
||||
|
||||
log = logging.getLogger()
|
||||
|
||||
|
||||
class PermissionDenied(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class BadRequest(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def httperror(f):
|
||||
@wraps(f)
|
||||
def func(*args, **kwargs):
|
||||
result = {
|
||||
'code': 400,
|
||||
'errorMessage': '',
|
||||
}
|
||||
try:
|
||||
return f(*args, **kwargs)
|
||||
except PermissionDenied as e:
|
||||
result['code'] = 403
|
||||
result['errorMessage'] = str(e)
|
||||
except BadRequest as e:
|
||||
result['code'] = 400
|
||||
result['errorMessage'] = str(e)
|
||||
except Exception as e:
|
||||
logging.exception(e)
|
||||
result['code'] = 500
|
||||
result['errorMessage'] = str(e)
|
||||
return jsonify(result)
|
||||
return func
|
||||
@@ -0,0 +1,133 @@
|
||||
from __future__ import (
|
||||
absolute_import, division, print_function, with_statement
|
||||
)
|
||||
from os import environ
|
||||
from gevent.event import Event
|
||||
from gevent import subprocess as gsp
|
||||
from re import search as research
|
||||
from .log import log
|
||||
|
||||
|
||||
class State(object):
|
||||
def __init__(self):
|
||||
self._eid = 0
|
||||
self._event = Event()
|
||||
self._w = self._h = self._health = None
|
||||
self.size_changed_count = 0
|
||||
|
||||
def wait(self, eid, timeout=5):
|
||||
if eid < self._eid:
|
||||
return
|
||||
self._event.clear()
|
||||
self._event.wait(timeout)
|
||||
return self._eid
|
||||
|
||||
def notify(self):
|
||||
self._eid += 1
|
||||
self._event.set()
|
||||
|
||||
def _update_health(self):
|
||||
health = True
|
||||
output = gsp.check_output([
|
||||
'supervisorctl', '-c', '/etc/supervisor/supervisord.conf',
|
||||
'status'
|
||||
])
|
||||
for line in output.strip().split('\n'):
|
||||
if not line.startswith('web') and line.find('RUNNING') < 0:
|
||||
health = False
|
||||
break
|
||||
if self._health != health:
|
||||
self._health = health
|
||||
self.notify()
|
||||
return self._health
|
||||
|
||||
def to_dict(self):
|
||||
self._update_health()
|
||||
|
||||
state = {
|
||||
'id': self._eid,
|
||||
'config': {
|
||||
'fixedResolution': 'RESOLUTION' in environ,
|
||||
'sizeChangedCount': self.size_changed_count
|
||||
}
|
||||
}
|
||||
|
||||
self._update_size()
|
||||
state.update({
|
||||
'width': self.w,
|
||||
'height': self.h,
|
||||
})
|
||||
|
||||
return state
|
||||
|
||||
def set_size(self, w, h):
|
||||
gsp.check_call((
|
||||
'sed -i \'s#'
|
||||
'^exec /usr/bin/Xvfb.*$'
|
||||
'#'
|
||||
'exec /usr/bin/Xvfb :1 -screen 0 {}x{}x16'
|
||||
'#\' /usr/local/bin/xvfb.sh'
|
||||
).format(w, h), shell=True)
|
||||
self.size_changed_count += 1
|
||||
|
||||
def apply_and_restart(self):
|
||||
gsp.check_call([
|
||||
'supervisorctl', '-c', '/etc/supervisor/supervisord.conf',
|
||||
'restart', 'x:'
|
||||
])
|
||||
self._w = self._h = self._health = None
|
||||
self.notify()
|
||||
|
||||
def switch_video(self, onoff):
|
||||
xenvs = {
|
||||
'DISPLAY': ':1',
|
||||
}
|
||||
try:
|
||||
cmd = 'nofb' if onoff else 'fb'
|
||||
gsp.check_output(['x11vnc', '-remote', cmd], env=xenvs)
|
||||
except gsp.CalledProcessError as e:
|
||||
log.warn('failed to set x11vnc fb: ' + str(e))
|
||||
|
||||
def _update_size(self):
|
||||
if self._w is not None and self._h is not None:
|
||||
return
|
||||
xenvs = {
|
||||
'DISPLAY': ':1',
|
||||
}
|
||||
try:
|
||||
output = gsp.check_output([
|
||||
'x11vnc', '-query', 'dpy_x,dpy_y'
|
||||
], env=xenvs).decode('utf-8')
|
||||
mobj = research(r'dpy_x:(\d+).*dpy_y:(\d+)', output)
|
||||
if mobj is not None:
|
||||
w, h = int(mobj.group(1)), int(mobj.group(2))
|
||||
changed = False
|
||||
if self._w != w:
|
||||
changed = True
|
||||
self._w = w
|
||||
if self._h != h:
|
||||
changed = True
|
||||
self._h = h
|
||||
if changed:
|
||||
self.notify()
|
||||
except gsp.CalledProcessError as e:
|
||||
log.warn('failed to get dispaly size: ' + str(e))
|
||||
|
||||
def reset_size(self):
|
||||
self.size_changed_count = 0
|
||||
|
||||
@property
|
||||
def w(self):
|
||||
return self._w
|
||||
|
||||
@property
|
||||
def h(self):
|
||||
return self._h
|
||||
|
||||
@property
|
||||
def health(self):
|
||||
self._update_health()
|
||||
return self._health
|
||||
|
||||
|
||||
state = State()
|
||||
@@ -0,0 +1,15 @@
|
||||
from __future__ import (
|
||||
absolute_import, division, print_function, with_statement
|
||||
)
|
||||
from contextlib import contextmanager
|
||||
from gevent import GreenletExit
|
||||
|
||||
|
||||
@contextmanager
|
||||
def ignored(*exceptions):
|
||||
try:
|
||||
yield
|
||||
except GreenletExit as e:
|
||||
raise e
|
||||
except exceptions:
|
||||
pass
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 339 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 527 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 246 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 870 KiB |
@@ -0,0 +1,18 @@
|
||||
[*]
|
||||
wallpaper_mode=stretch
|
||||
wallpaper_common=0
|
||||
wallpapers_configured=4
|
||||
wallpaper0=/usr/local/share/doro-lxde-wallpapers/bg1.jpg
|
||||
wallpaper1=/usr/local/share/doro-lxde-wallpapers/bg2.jpg
|
||||
wallpaper2=/usr/local/share/doro-lxde-wallpapers/bg3.jpg
|
||||
wallpaper3=/usr/local/share/doro-lxde-wallpapers/bg4.jpg
|
||||
desktop_bg=#000000
|
||||
desktop_fg=#ffffff
|
||||
desktop_shadow=#000000
|
||||
desktop_font=Sans 12
|
||||
show_wm_menu=0
|
||||
sort=mtime;ascending;mingle;
|
||||
show_documents=0
|
||||
show_trash=0
|
||||
show_mounts=0
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Name=Chromium Web Browser Sound
|
||||
GenericName=Web Browser
|
||||
GenericName[ar]=متصفح الشبكة
|
||||
GenericName[ast]=Restolador web
|
||||
GenericName[bg]=Уеб браузър
|
||||
GenericName[bn]=ওয়েব ব্রাউজার
|
||||
GenericName[bs]=Web preglednik
|
||||
GenericName[ca]=Navegador web
|
||||
GenericName[ca@valencia]=Navegador web
|
||||
GenericName[cs]=WWW prohlížeč
|
||||
GenericName[da]=Browser
|
||||
GenericName[de]=Web-Browser
|
||||
GenericName[el]=Περιηγητής ιστού
|
||||
GenericName[en_AU]=Web Browser
|
||||
GenericName[en_GB]=Web Browser
|
||||
GenericName[eo]=Retfoliumilo
|
||||
GenericName[es]=Navegador web
|
||||
GenericName[et]=Veebibrauser
|
||||
GenericName[eu]=Web-nabigatzailea
|
||||
GenericName[fi]=WWW-selain
|
||||
GenericName[fil]=Web Browser
|
||||
GenericName[fr]=Navigateur Web
|
||||
GenericName[gl]=Navegador web
|
||||
GenericName[gu]=વેબ બ્રાઉઝર
|
||||
GenericName[he]=דפדפן אינטרנט
|
||||
GenericName[hi]=वेब ब्राउज़र
|
||||
GenericName[hr]=Web preglednik
|
||||
GenericName[hu]=Webböngésző
|
||||
GenericName[hy]=Ոստայն զննարկիչ
|
||||
GenericName[ia]=Navigator del Web
|
||||
GenericName[id]=Peramban Web
|
||||
GenericName[it]=Browser web
|
||||
GenericName[ja]=ウェブ・ブラウザ
|
||||
GenericName[ka]=ვებ ბრაუზერი
|
||||
GenericName[kn]=ಜಾಲ ವೀಕ್ಷಕ
|
||||
GenericName[ko]=웹 브라우저
|
||||
GenericName[kw]=Peurel wias
|
||||
GenericName[lt]=Žiniatinklio naršyklė
|
||||
GenericName[lv]=Tīmekļa pārlūks
|
||||
GenericName[ml]=വെബ് ബ്രൌസര്
|
||||
GenericName[mr]=वेब ब्राऊजर
|
||||
GenericName[ms]=Pelayar Web
|
||||
GenericName[nb]=Nettleser
|
||||
GenericName[nl]=Webbrowser
|
||||
GenericName[or]=ଓ୍ବେବ ବ୍ରାଉଜର
|
||||
GenericName[pl]=Przeglądarka WWW
|
||||
GenericName[pt]=Navegador Web
|
||||
GenericName[pt_BR]=Navegador web
|
||||
GenericName[ro]=Navigator de Internet
|
||||
GenericName[ru]=Веб-браузер
|
||||
GenericName[sk]=WWW prehliadač
|
||||
GenericName[sl]=Spletni brskalnik
|
||||
GenericName[sr]=Интернет прегледник
|
||||
GenericName[sv]=Webbläsare
|
||||
GenericName[ta]=இணைய உலாவி
|
||||
GenericName[te]=మహాతల అన్వేషి
|
||||
GenericName[th]=เว็บเบราว์เซอร์
|
||||
GenericName[tr]=Web Tarayıcı
|
||||
GenericName[ug]=توركۆرگۈ
|
||||
GenericName[uk]=Навігатор Тенет
|
||||
GenericName[vi]=Bộ duyệt Web
|
||||
GenericName[zh_CN]=网页浏览器
|
||||
GenericName[zh_HK]=網頁瀏覽器
|
||||
GenericName[zh_TW]=網頁瀏覽器
|
||||
Comment=Access the Internet
|
||||
Comment[ar]=الدخول إلى الإنترنت
|
||||
Comment[ast]=Accesu a Internet
|
||||
Comment[bg]=Достъп до интернет
|
||||
Comment[bn]=ইন্টারনেটে প্রবেশ করুন
|
||||
Comment[bs]=Pristup internetu
|
||||
Comment[ca]=Accediu a Internet
|
||||
Comment[ca@valencia]=Accediu a Internet
|
||||
Comment[cs]=Přístup k internetu
|
||||
Comment[da]=Få adgang til internettet
|
||||
Comment[de]=Internetzugriff
|
||||
Comment[el]=Πρόσβαση στο Διαδίκτυο
|
||||
Comment[en_AU]=Access the Internet
|
||||
Comment[en_GB]=Access the Internet
|
||||
Comment[eo]=Akiri interreton
|
||||
Comment[es]=Acceda a Internet
|
||||
Comment[et]=Pääs Internetti
|
||||
Comment[eu]=Sartu Internetera
|
||||
Comment[fi]=Käytä internetiä
|
||||
Comment[fil]=I-access ang Internet
|
||||
Comment[fr]=Accéder à Internet
|
||||
Comment[gl]=Acceda a Internet
|
||||
Comment[gu]=ઇંટરનેટ ઍક્સેસ કરો
|
||||
Comment[he]=גישה לאינטרנט
|
||||
Comment[hi]=इंटरनेट तक पहुंच स्थापित करें
|
||||
Comment[hr]=Pristupite Internetu
|
||||
Comment[hu]=Az internet elérése
|
||||
Comment[hy]=Մուտք համացանց
|
||||
Comment[ia]=Accede a le Interrete
|
||||
Comment[id]=Akses Internet
|
||||
Comment[it]=Accesso a Internet
|
||||
Comment[ja]=インターネットにアクセス
|
||||
Comment[ka]=ინტერნეტში შესვლა
|
||||
Comment[kn]=ಇಂಟರ್ನೆಟ್ ಅನ್ನು ಪ್ರವೇಶಿಸಿ
|
||||
Comment[ko]=인터넷에 연결합니다
|
||||
Comment[kw]=Hedhes an Kesrosweyth
|
||||
Comment[lt]=Interneto prieiga
|
||||
Comment[lv]=Piekļūt internetam
|
||||
Comment[ml]=ഇന്റര്നെറ്റ് ആക്സസ് ചെയ്യുക
|
||||
Comment[mr]=इंटरनेटमध्ये प्रवेश करा
|
||||
Comment[ms]=Mengakses Internet
|
||||
Comment[nb]=Bruk internett
|
||||
Comment[nl]=Verbinding maken met internet
|
||||
Comment[or]=ଇଣ୍ଟର୍ନେଟ୍ ପ୍ରବେଶ କରନ୍ତୁ
|
||||
Comment[pl]=Skorzystaj z internetu
|
||||
Comment[pt]=Aceder à Internet
|
||||
Comment[pt_BR]=Acessar a internet
|
||||
Comment[ro]=Accesați Internetul
|
||||
Comment[ru]=Доступ в Интернет
|
||||
Comment[sk]=Prístup do siete Internet
|
||||
Comment[sl]=Dostop do interneta
|
||||
Comment[sr]=Приступите Интернету
|
||||
Comment[sv]=Surfa på Internet
|
||||
Comment[ta]=இணையத்தை அணுகுதல்
|
||||
Comment[te]=ఇంటర్నెట్ను ఆక్సెస్ చెయ్యండి
|
||||
Comment[th]=เข้าถึงอินเทอร์เน็ต
|
||||
Comment[tr]=İnternet'e erişin
|
||||
Comment[ug]=ئىنتېرنېت زىيارىتى
|
||||
Comment[uk]=Доступ до Інтернету
|
||||
Comment[vi]=Truy cập Internet
|
||||
Comment[zh_CN]=访问互联网
|
||||
Comment[zh_HK]=連線到網際網路
|
||||
Comment[zh_TW]=連線到網際網路
|
||||
Exec=/usr/local/bin/chromium-browser-sound.sh %U
|
||||
Terminal=false
|
||||
X-MultipleArgs=false
|
||||
Type=Application
|
||||
Icon=chromium-browser
|
||||
Categories=Network;WebBrowser;
|
||||
MimeType=text/html;text/xml;application/xhtml_xml;x-scheme-handler/http;x-scheme-handler/https;
|
||||
StartupNotify=true
|
||||
Actions=NewWindow;Incognito;TempProfile;
|
||||
X-AppInstall-Package=chromium-browser
|
||||
@@ -0,0 +1,23 @@
|
||||
[General]
|
||||
leave_confirmation=true
|
||||
|
||||
[Environment]
|
||||
GTK_CSD=0
|
||||
GTK_OVERLAY_SCROLLING=0
|
||||
|
||||
[Mouse]
|
||||
cursor_size=18
|
||||
cursor_theme=whiteglass
|
||||
acc_factor=20
|
||||
acc_threshold=10
|
||||
left_handed=false
|
||||
|
||||
[Keyboard]
|
||||
delay=500
|
||||
interval=30
|
||||
beep=false
|
||||
|
||||
[Font]
|
||||
antialias=true
|
||||
hinting=true
|
||||
dpi=96
|
||||
Reference in New Issue
Block a user