diff --git a/web/kvm/index.html b/web/kvm/index.html
index 8736ff4b..e2f6b263 100644
--- a/web/kvm/index.html
+++ b/web/kvm/index.html
@@ -982,14 +982,16 @@
-
+
@@ -1032,10 +1034,13 @@
-
+
-
-
+
@@ -2961,15 +2972,18 @@
PiKVM Project | Documentation | Support
-
+
-
+
-
diff --git a/web/kvm/window-about.pug b/web/kvm/window-about.pug
index 8a1dc361..5a82987b 100644
--- a/web/kvm/window-about.pug
+++ b/web/kvm/window-about.pug
@@ -10,10 +10,12 @@ mixin about_tab(name, title, checked=false)
span.code-comment No data
-.window#about-window
+.window#about-window(data-show-centered)
.window-header
.window-grab About
- button.window-button-close #[b ×]
+ .window-buttons
+ button.window-button-original •
+ button.window-button-close #[b ×]
#about
table
diff --git a/web/kvm/window-keyboard.pug b/web/kvm/window-keyboard.pug
index 34921f95..e134e628 100644
--- a/web/kvm/window-keyboard.pug
+++ b/web/kvm/window-keyboard.pug
@@ -30,10 +30,12 @@ mixin lamp(cls)
img(class=`inline-lamp-small ${cls} led-gray` src=`${svg_dir}/led-square.svg`)
-.window#keyboard-window
+.window#keyboard-window(data-show-centered)
.window-header#keyboard-window-header
.window-grab Virtual Keyboard
- button.window-button-close #[b ×]
+ .window-buttons
+ button.window-button-original •
+ button.window-button-close #[b ×]
.keypad#keyboard-desktop(align="center")
.keypad-block
diff --git a/web/kvm/window-stream.pug b/web/kvm/window-stream.pug
index 4fc3c42f..76ba0c49 100644
--- a/web/kvm/window-stream.pug
+++ b/web/kvm/window-stream.pug
@@ -1,14 +1,15 @@
.window#stream-ocr-window
.hidden#stream-ocr-selection
-.window.window-resizable#stream-window
+.window.window-resizable#stream-window(data-show-maximized)
.window-header#stream-window-header
.window-grab MJPEG
- button.window-button-close #[b ×]
- button.window-button-maximize ☐
- button.window-button-original •
- button.window-button-enter-full-tab ▲
- button.window-button-full-screen ⤢
+ .window-buttons
+ button.window-button-full-screen ⤢
+ button.window-button-enter-full-tab ▲
+ button.window-button-original •
+ button.window-button-maximize ☐
+ button.window-button-close #[b ×]
#stream-info
diff --git a/web/kvm/window-switch.pug b/web/kvm/window-switch.pug
index 793b39aa..8a04ffa2 100644
--- a/web/kvm/window-switch.pug
+++ b/web/kvm/window-switch.pug
@@ -15,10 +15,12 @@ mixin color_slider_tr(name, title)
td #[button(id=`switch-color-${name}-default-button` class="small" title="Reset default") ↻]
-.window#switch-window(style="width: min-content")
+.window#switch-window(data-show-centered style="width: min-content")
.window-header
.window-grab Switch settings
- button.window-button-close #[b ×]
+ .window-buttons
+ button.window-button-original •
+ button.window-button-close #[b ×]
.tabs-box
+switch_tab("edid", "EDIDs collection", true)
diff --git a/web/kvm/window-webterm.pug b/web/kvm/window-webterm.pug
index 95565e54..274c5e78 100644
--- a/web/kvm/window-webterm.pug
+++ b/web/kvm/window-webterm.pug
@@ -1,9 +1,11 @@
-.window.window-resizable#webterm-window(style="width: 720px; height: 480px")
+.window.window-resizable#webterm-window(data-show-centered style="display: flex; min-width: 720px; min-height: 480px")
.window-header
.window-grab Terminal
- button.window-button-close #[b ×]
- button.window-button-maximize ☐
- // Терминал глючит из-за зажимаемой клавиши ESC для выхода
- // button(class="window-button-full-screen") ⤢
+ .window-buttons
+ button.window-button-original •
+ button.window-button-maximize ☐
+ button.window-button-close #[b ×]
+ // Терминал глючит из-за зажимаемой клавиши ESC для выхода
+ // button(class="window-button-full-screen") ⤢
- iframe#webterm-iframe(src="" style="width: 100%; height: 100%")
+ iframe#webterm-iframe(src="" style="width: 100%; flex: 1")
diff --git a/web/share/css/kvm/x-mobile.css b/web/share/css/kvm/x-mobile.css
index caad69f1..dc5ee3d9 100644
--- a/web/share/css/kvm/x-mobile.css
+++ b/web/share/css/kvm/x-mobile.css
@@ -34,6 +34,11 @@ div#stream-window {
width: 100% !important;
-webkit-transform: translateX(-50%) !important;
transform: translateX(-50%) !important;
+
+ /* Ignore stream's resize_hook() */
+ aspect-ratio: unset !important;
+ max-width: unset !important;
+ max-height: unset !important;
}
div#stream-window::after {
diff --git a/web/share/css/vars.css b/web/share/css/vars.css
index e7aded4d..289c9dd2 100644
--- a/web/share/css/vars.css
+++ b/web/share/css/vars.css
@@ -45,6 +45,7 @@
--cs-window-header-grabbed-bg: #436a8a;
--cs-window-header-grabbed-fg: white;
--cs-window-closer-default-fg: #6c7481;
+ --cs-window-button-special-fg: #009b48;
--cs-code-default-bg: #17191d;
--cs-code-default-fg: #aaaaaa;
diff --git a/web/share/css/window.css b/web/share/css/window.css
index 1dba21c0..2ac3ae36 100644
--- a/web/share/css/window.css
+++ b/web/share/css/window.css
@@ -40,7 +40,7 @@ div.window-resizable {
div.window-active {
border: var(--border-window-active-2px) !important;
}
-div.window-resizable.window-active::after {
+div.window-resizable.window-active:not(.window-full-tab)::after {
content: "";
width: 0;
height: 0;
@@ -61,6 +61,11 @@ div.window:fullscreen {
width: 100% !important;
height: 100% !important;
padding: 0px !important;
+
+ /* Ignore stream's resize_hook() */
+ aspect-ratio: unset !important;
+ max-width: unset !important;
+ max-height: unset !important;
}
div.window:fullscreen::after {
display: none;
@@ -75,6 +80,11 @@ div.window:-webkit-full-screen {
width: 100% !important;
height: 100% !important;
padding: 0px !important;
+
+ /* Ignore stream's resize_hook() */
+ aspect-ratio: unset !important;
+ max-width: unset !important;
+ max-height: unset !important;
}
div.window:-webkit-full-screen::after {
display: none;
@@ -88,6 +98,11 @@ div.window.window-full-tab {
width: 100% !important;
height: 100% !important;
padding: 0px !important;
+
+ /* Ignore stream's resize_hook() */
+ aspect-ratio: unset !important;
+ max-width: unset !important;
+ max-height: unset !important;
}
div.window div.window-header {
@@ -126,36 +141,35 @@ div.window div.window-header-grabbed {
border-bottom: var(--border-intensive-thin);
}
-div.window div.window-header button.window-button-full-screen,
-div.window div.window-header button.window-button-enter-full-tab,
-div.window div.window-header button.window-button-original,
-div.window div.window-header button.window-button-maximize,
-div.window div.window-header button.window-button-close {
- line-height: 1px;
- border: none;
+div.window div.window-header div.window-buttons {
position: absolute;
top: -2px;
+ right: 0;
+ font-size: 0px;
+ background-color: var(--cs-window-default-bg);
+}
+
+div.window div.window-header div.window-buttons button.window-button-full-screen,
+div.window div.window-header div.window-buttons button.window-button-enter-full-tab,
+div.window div.window-header div.window-buttons button.window-button-original,
+div.window div.window-header div.window-buttons button.window-button-maximize,
+div.window div.window-header div.window-buttons button.window-button-close {
+ line-height: 1px;
+ border: none;
+ border-radius: 0px;
width: 44px;
height: 24px;
padding-left: 0;
padding-right: 0;
+ margin-left: 1px;
color: var(--cs-window-closer-default-fg);
display: inline-block;
}
-div.window div.window-header button.window-button-full-screen {
- right: 180px;
+div.window[data-centered] div.window-header div.window-buttons button.window-button-original {
+ color: var(--cs-window-button-special-fg);
}
-div.window div.window-header button.window-button-enter-full-tab {
- right: 135px;
-}
-div.window div.window-header button.window-button-original {
- right: 90px;
-}
-div.window div.window-header button.window-button-maximize {
- right: 45px;
-}
-div.window div.window-header button.window-button-close {
- right: 0px;
+div.window[data-maximized] div.window-header div.window-buttons button.window-button-maximize {
+ color: var(--cs-window-button-special-fg);
}
div.window button.window-button-exit-full-tab {
diff --git a/web/share/js/kvm/stream.js b/web/share/js/kvm/stream.js
index 14622c5b..eba7ffdd 100644
--- a/web/share/js/kvm/stream.js
+++ b/web/share/js/kvm/stream.js
@@ -43,7 +43,7 @@ export function Streamer() {
var __res = {"width": 640, "height": 480};
var __init__ = function() {
- __streamer = new MjpegStreamer(__setActive, __setInactive, __setInfo);
+ __streamer = new MjpegStreamer(__setActive, __setInactive, __setInfo, __organizeHook);
$("stream-led").title = "Stream inactive";
@@ -110,6 +110,7 @@ export function Streamer() {
$("stream-window").show_hook = () => __applyState(__state);
$("stream-window").close_hook = () => __applyState(null);
+ $("stream-window").organize_hook = __organizeHook;
};
/************************************************************************/
@@ -294,6 +295,11 @@ export function Streamer() {
el_grab.innerText = el_info.innerText = title;
};
+ var __organizeHook = function() {
+ let geo = self.getGeometry();
+ wm.setAspectRatio($("stream-window"), geo.width, geo.height);
+ };
+
var __resetStream = function(mode=null) {
if (mode === null) {
mode = __streamer.getMode();
@@ -303,16 +309,16 @@ export function Streamer() {
if (mode === "janus") {
let allow_audio = !$("stream-video").muted;
let allow_mic = $("stream-mic-switch").checked;
- __streamer = new JanusStreamer(__setActive, __setInactive, __setInfo, orient, allow_audio, allow_mic);
+ __streamer = new JanusStreamer(__setActive, __setInactive, __setInfo, __organizeHook, orient, allow_audio, allow_mic);
// Firefox doesn't support RTP orientation:
// - https://bugzilla.mozilla.org/show_bug.cgi?id=1316448
tools.feature.setEnabled($("stream-orient"), !tools.browser.is_firefox);
} else {
if (mode === "media") {
- __streamer = new MediaStreamer(__setActive, __setInactive, __setInfo, orient);
+ __streamer = new MediaStreamer(__setActive, __setInactive, __setInfo, __organizeHook, orient);
tools.feature.setEnabled($("stream-orient"), true);
} else { // mjpeg
- __streamer = new MjpegStreamer(__setActive, __setInactive, __setInfo);
+ __streamer = new MjpegStreamer(__setActive, __setInactive, __setInfo, __organizeHook);
tools.feature.setEnabled($("stream-orient"), false);
}
tools.feature.setEnabled($("stream-audio"), false); // Enabling in stream_janus.js
diff --git a/web/share/js/kvm/stream_janus.js b/web/share/js/kvm/stream_janus.js
index a7c93ee9..721d5fde 100644
--- a/web/share/js/kvm/stream_janus.js
+++ b/web/share/js/kvm/stream_janus.js
@@ -29,7 +29,7 @@ import {tools, $} from "../tools.js";
var _Janus = null;
-export function JanusStreamer(__setActive, __setInactive, __setInfo, __orient, __allow_audio, __allow_mic) {
+export function JanusStreamer(__setActive, __setInactive, __setInfo, __organizeHook, __orient, __allow_audio, __allow_mic) {
var self = this;
/************************************************************************/
@@ -48,6 +48,8 @@ export function JanusStreamer(__setActive, __setInactive, __setInfo, __orient, _
var __state = null;
var __frames = 0;
+ var __res = {"width": -1, "height": -1};
+ var __resize_listener_installed = false;
var __ice = null;
@@ -84,11 +86,28 @@ export function JanusStreamer(__setActive, __setInactive, __setInfo, __orient, _
__state = state;
__stop = false;
__ensureJanus(false);
+ if (!__resize_listener_installed) {
+ $("stream-video").addEventListener("resize", __videoResizeHandler);
+ __resize_listener_installed = true;
+ }
};
self.stopStream = function() {
__stop = true;
__destroyJanus();
+ if (__resize_listener_installed) {
+ $("stream-video").removeEventListener("resize", __videoResizeHandler);
+ __resize_listener_installed = false;
+ }
+ };
+
+ var __videoResizeHandler = function(ev) {
+ let el = ev.target;
+ if (__res.width !== el.videoWidth || __res.height !== el.videoHeight) {
+ __res.width = el.videoWidth;
+ __res.height = el.videoHeight;
+ __organizeHook();
+ }
};
var __ensureJanus = function(internal) {
diff --git a/web/share/js/kvm/stream_media.js b/web/share/js/kvm/stream_media.js
index 33cc7e94..9809cc90 100644
--- a/web/share/js/kvm/stream_media.js
+++ b/web/share/js/kvm/stream_media.js
@@ -26,7 +26,7 @@
import {tools, $} from "../tools.js";
-export function MediaStreamer(__setActive, __setInactive, __setInfo, __orient) {
+export function MediaStreamer(__setActive, __setInactive, __setInfo, __organizeHook, __orient) {
var self = this;
/************************************************************************/
@@ -282,6 +282,7 @@ export function MediaStreamer(__setActive, __setInactive, __setInfo, __orient) {
if (__canvas.width !== width || __canvas.height !== height) {
__canvas.width = width;
__canvas.height = height;
+ __organizeHook();
}
if (__orient === 0) {
diff --git a/web/share/js/kvm/stream_mjpeg.js b/web/share/js/kvm/stream_mjpeg.js
index 46f3827b..6656549a 100644
--- a/web/share/js/kvm/stream_mjpeg.js
+++ b/web/share/js/kvm/stream_mjpeg.js
@@ -27,7 +27,7 @@ import {ROOT_PREFIX} from "../vars.js";
import {tools, $} from "../tools.js";
-export function MjpegStreamer(__setActive, __setInactive, __setInfo) {
+export function MjpegStreamer(__setActive, __setInactive, __setInfo, __organizeHook) {
var self = this;
/************************************************************************/
@@ -62,6 +62,7 @@ export function MjpegStreamer(__setActive, __setInactive, __setInfo) {
if (__id.length > 0 && __id in __state.stream.clients_stat) {
__setStreamActive();
__stopChecking();
+ __organizeHook();
} else {
__ensureChecking();
}
diff --git a/web/share/js/wm.js b/web/share/js/wm.js
index fe923609..59e942bc 100644
--- a/web/share/js/wm.js
+++ b/web/share/js/wm.js
@@ -60,21 +60,59 @@ function __WindowManager() {
__windows.push(el_win);
if (el_win.classList.contains("window-resizable") && window.ResizeObserver) {
+ el_win.__observer_timer = null;
new ResizeObserver(function() {
- // При переполнении рабочей области сократить размер окна по высоте.
- // По ширине оно настраивается само в CSS.
- let view = self.getViewGeometry();
- let rect = el_win.getBoundingClientRect();
- if ((rect.bottom - rect.top) > (view.bottom - view.top)) {
- let ratio = (rect.bottom - rect.top) / (view.bottom - view.top);
- el_win.style.height = view.bottom - view.top + "px";
- el_win.style.width = Math.round((rect.right - rect.left) / ratio) + "px";
- }
-
- if (el_win.hasAttribute("data-centered")) {
- __centerWindow(el_win);
+ // Таймер нужен чтобы остановить дребезг ресайза: observer вызывает
+ // __organizeWindow(), который сам по себе триггерит observer.
+ if (el_win.__observer_timer === null || el_win.__manual_resizing) {
+ __organizeWindow(el_win, !el_win.__manual_resizing);
+ if (el_win.__observer_timer !== null) {
+ clearTimeout(el_win.__observer_timer);
+ }
+ el_win.__observer_timer = setTimeout(function() {
+ el_win.__observer_timer = null;
+ }, 100);
}
}).observe(el_win);
+ el_win.addEventListener("pointerrawupdate", function(ev) {
+ // События pointerdown и touchdown не генерируются при ресайзе за уголок,
+ // поэтому отлавливаем pointerrawupdate для тач-событий.
+ let events = ev.getCoalescedEvents();
+ for (ev of events) {
+ if (
+ ev.target === el_win && ev.pointerType === "touch" && ev.buttons
+ && Math.abs(el_win.clientWidth - ev.offsetX) < 20
+ && Math.abs(el_win.clientHeight - ev.offsetY) < 20
+ ) {
+ __setWindowMca(el_win, false, null, true);
+ break;
+ }
+ }
+ });
+ el_win.addEventListener("mousedown", function(ev) {
+ if (
+ ev.target === el_win
+ && Math.abs(el_win.clientWidth - ev.offsetX) < 20
+ && Math.abs(el_win.clientHeight - ev.offsetY) < 20
+ ) {
+ el_win.__manual_resizing = true;
+ }
+ });
+ document.addEventListener("mouseup", function() {
+ if (el_win.__manual_resizing) {
+ __organizeWindow(el_win);
+ }
+ el_win.__manual_resizing = false;
+ });
+ document.addEventListener("mousemove", function(ev) {
+ if (el_win.__manual_resizing) {
+ __setWindowMca(el_win, false, null, true);
+ if (!ev.buttons) {
+ __organizeWindow(el_win);
+ el_win.__manual_resizing = false;
+ }
+ }
+ });
}
{
@@ -90,8 +128,9 @@ function __WindowManager() {
if (el) {
el.title = "Maximize window";
tools.el.setOnClick(el, function() {
- __maximizeWindow(el_win);
- __activateLastWindow(el_win);
+ __setWindowMca(el_win, true, false, false);
+ __organizeWindow(el_win);
+ __activateWindow(el_win);
});
}
}
@@ -101,10 +140,11 @@ function __WindowManager() {
if (el) {
el.title = "Reduce window to its original size and center it";
tools.el.setOnClick(el, function() {
+ __setWindowMca(el_win, false, true, false);
el_win.style.width = "";
el_win.style.height = "";
- __centerWindow(el_win);
- __activateLastWindow(el_win);
+ __organizeWindow(el_win);
+ __activateWindow(el_win);
});
}
}
@@ -125,7 +165,7 @@ function __WindowManager() {
el.title = "Go to full-screen mode";
tools.el.setOnClick(el, function() {
__setFullScreenWindow(el_win);
- __activateLastWindow(el_win);
+ __activateWindow(el_win);
});
}
}
@@ -301,20 +341,46 @@ function __WindowManager() {
return promise;
};
+ var __setWindowMca = function(el_win, maximized, centered, adjusted) {
+ if (maximized !== null) {
+ el_win.toggleAttribute("data-maximized", maximized);
+ if (maximized) {
+ el_win.removeAttribute("data-centered");
+ }
+ }
+ if (centered !== null) {
+ el_win.toggleAttribute("data-centered", centered);
+ if (centered) {
+ el_win.removeAttribute("data-maximized");
+ }
+ }
+ if (adjusted !== null) {
+ el_win.toggleAttribute("data-adjusted", adjusted);
+ if (adjusted) {
+ el_win.removeAttribute("data-maximized");
+ }
+ }
+ };
+
self.showWindow = function(el_win) {
- let center = false;
let showed = false;
if (!self.isWindowVisible(el_win)) {
- center = true;
showed = true;
}
- __organizeWindow(el_win, center);
+
+ if (!el_win.hasAttribute("data-adjusted")) {
+ if (el_win.hasAttribute("data-show-maximized") && !el_win.hasAttribute("data-centered")) {
+ __setWindowMca(el_win, true, false, false);
+ } else if (el_win.hasAttribute("data-show-centered") && !el_win.hasAttribute("data-maximized")) {
+ __setWindowMca(el_win, false, true, false);
+ }
+ }
+ __organizeWindow(el_win);
+
el_win.style.visibility = "visible";
__activateWindow(el_win);
- if (el_win.show_hook) {
- if (showed) {
- el_win.show_hook();
- }
+ if (showed && el_win.show_hook) {
+ el_win.show_hook();
}
};
@@ -346,6 +412,18 @@ function __WindowManager() {
setTimeout(() => __activateWindow(el_win), 100);
};
+ self.setAspectRatio = function(el_win, width, height) {
+ // XXX: Values from CSS
+ width += 9 + 9 + 2 + 2;
+ height += 30 + 9 + 2 + 2;
+ el_win.__aspect_ratio_width = width;
+ el_win.__aspect_ratio_height = height;
+ el_win.style.maxWidth = "fit-content";
+ el_win.style.maxHeight = "fit-content";
+ el_win.style.aspectRatio = `${width} / ${height}`;
+ __organizeWindow(el_win, true, false);
+ };
+
var __closeWindow = function(el_win) {
el_win.focus();
el_win.blur();
@@ -438,23 +516,20 @@ function __WindowManager() {
var __organizeWindowsOnBrowserResize = function() {
for (let el_win of $$("window")) {
if (el_win.style.visibility === "visible") {
- if (tools.browser.is_mobile && el_win.classList.contains("window-resizable")) {
- // FIXME: При смене ориентации на мобильном браузере надо сбрасывать
- // настройки окна стрима, поэтому тут стоит вот этот костыль
- el_win.style.width = "";
- el_win.style.height = "";
- }
__organizeWindow(el_win);
}
}
};
- var __organizeWindow = function(el_win, center=false) {
- let view = self.getViewGeometry();
- let rect = el_win.getBoundingClientRect();
+ var __organizeWindow = function(el_win, auto_shrink=true, organize_hook=true) {
+ if (organize_hook && el_win.organize_hook) {
+ el_win.organize_hook();
+ }
- if (el_win.classList.contains("window-resizable")) {
+ if (auto_shrink && el_win.classList.contains("window-resizable")) {
// При переполнении рабочей области сократить размер окна
+ let view = self.getViewGeometry();
+ let rect = el_win.getBoundingClientRect();
if ((rect.bottom - rect.top) > (view.bottom - view.top)) {
let ratio = (rect.bottom - rect.top) / (view.bottom - view.top);
el_win.style.height = view.bottom - view.top + "px";
@@ -463,32 +538,65 @@ function __WindowManager() {
if ((rect.right - rect.left) > (view.right - view.left)) {
el_win.style.width = view.right - view.left + "px";
}
- rect = el_win.getBoundingClientRect();
}
- if (el_win.hasAttribute("data-centered") || center) {
- __centerWindow(el_win);
+ if (el_win.hasAttribute("data-maximized")) {
+ __organizeMaximizeWindow(el_win);
+ } else if (el_win.hasAttribute("data-centered")) {
+ __organizeCenterWindow(el_win);
} else {
- if (rect.top <= view.top) {
- el_win.style.top = view.top + "px";
- } else if (rect.bottom > view.bottom) {
- el_win.style.top = view.bottom - rect.height + "px";
- }
-
- if (rect.left <= view.left) {
- el_win.style.left = view.left + "px";
- } else if (rect.right > view.right) {
- el_win.style.left = view.right - rect.width + "px";
- }
+ __organizeFitWindow(el_win);
}
};
- var __centerWindow = function(el_win) {
+ var __organizeCenterWindow = function(el_win) {
let view = self.getViewGeometry();
let rect = el_win.getBoundingClientRect();
el_win.style.top = Math.max(view.top, Math.round((view.bottom - rect.height) / 2)) + "px";
el_win.style.left = Math.round((view.right - rect.width) / 2) + "px";
- el_win.setAttribute("data-centered", "");
+ };
+
+ var __organizeMaximizeWindow = function(el_win) {
+ let view = self.getViewGeometry();
+ el_win.style.top = view.top + "px";
+
+ let aw = el_win.__aspect_ratio_width;
+ let ah = el_win.__aspect_ratio_height;
+ let gw = view.right - view.left;
+ let gh = view.bottom - view.top;
+ if (aw && ah) {
+ if (aw / gw < ah / gh) {
+ el_win.style.width = "";
+ el_win.style.height = gh + "px";
+ } else {
+ el_win.style.left = "";
+ el_win.style.height = "";
+ el_win.style.width = gw + "px";
+ }
+ }/* else {
+ el_win.style.width = gw + "px";
+ el_win.style.height = gh + "px";
+ }*/
+
+ let rect = el_win.getBoundingClientRect();
+ el_win.style.left = Math.round((view.right - rect.width) / 2) + "px";
+ };
+
+ var __organizeFitWindow = function(el_win) {
+ let view = self.getViewGeometry();
+ let rect = el_win.getBoundingClientRect();
+
+ if (rect.top <= view.top) {
+ el_win.style.top = view.top + "px";
+ } else if (rect.bottom > view.bottom) {
+ el_win.style.top = view.bottom - rect.height + "px";
+ }
+
+ if (rect.left <= view.left) {
+ el_win.style.left = view.left + "px";
+ } else if (rect.right > view.right) {
+ el_win.style.left = view.right - rect.width + "px";
+ }
};
var __activateLastWindow = function(el_except_win=null) {
@@ -584,7 +692,7 @@ function __WindowManager() {
return;
}
- el_win.removeAttribute("data-centered");
+ __setWindowMca(el_win, false, false, true);
ev = (ev || window.ev);
ev.preventDefault();
@@ -612,8 +720,6 @@ function __WindowManager() {
}
}
- el_win.setAttribute("data-centered", "");
-
document.addEventListener("mousemove", doMoving);
document.addEventListener("mouseup", stopMoving);
@@ -659,14 +765,5 @@ function __WindowManager() {
el_win.focus(el_win); // Почему-то теряется фокус
};
- var __maximizeWindow = function(el_win) {
- let el_navbar = $("navbar");
- let vertical_offset = (el_navbar ? el_navbar.offsetHeight : 0);
- el_win.style.left = "0px";
- el_win.style.top = vertical_offset + "px";
- el_win.style.width = window.innerWidth + "px";
- el_win.style.height = window.innerHeight - vertical_offset + "px";
- };
-
__init__();
}