Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions po/de.po
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,22 @@ msgstr "Paketverlustverhältnis:"
msgid "Lossy Encodings Settings"
msgstr "Einstellungen für verlustbehaftete VNC-Kodierungen"

#: ../src/gui/MyFrameMain.cpp
msgid "Multi-Sync Input\tCtrl-M"
msgstr "Multi-Sync Eingabe\tCtrl-M"

#: ../src/gui/MyFrameMain.cpp
msgid "Multi-Sync Input disabled."
msgstr "Multi-Sync Eingabe deaktiviert."

#: ../src/gui/MyFrameMain.cpp
msgid "Multi-Sync Input enabled: input is replicated to all connections."
msgstr "Multi-Sync Eingabe aktiviert: Eingaben werden an alle Verbindungen gesendet."

#: ../src/gui/MyFrameMain.cpp
msgid "Replicate mouse and keyboard input to all connections."
msgstr "Maus- und Tastatureingaben an alle Verbindungen senden."

#: ../src/gui/FrameMain.cpp:24
msgid "MultiVNC"
msgstr "MultiVNC"
Expand Down
16 changes: 16 additions & 0 deletions po/es.po
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,22 @@ msgstr "Ratio de pérdidas:"
msgid "Lossy Encodings Settings"
msgstr "Ajustes de codificación con pérdidas"

#: ../src/gui/MyFrameMain.cpp
msgid "Multi-Sync Input\tCtrl-M"
msgstr ""

#: ../src/gui/MyFrameMain.cpp
msgid "Multi-Sync Input disabled."
msgstr ""

#: ../src/gui/MyFrameMain.cpp
msgid "Multi-Sync Input enabled: input is replicated to all connections."
msgstr ""

#: ../src/gui/MyFrameMain.cpp
msgid "Replicate mouse and keyboard input to all connections."
msgstr ""

#: ../src/gui/FrameMain.cpp:24
msgid "MultiVNC"
msgstr "MultiVNC"
Expand Down
16 changes: 16 additions & 0 deletions po/sv.po
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,22 @@ msgstr "Förlustkvot:"
msgid "Lossy Encodings Settings"
msgstr "Inställningar för förstörande kodningar"

#: ../src/gui/MyFrameMain.cpp
msgid "Multi-Sync Input\tCtrl-M"
msgstr ""

#: ../src/gui/MyFrameMain.cpp
msgid "Multi-Sync Input disabled."
msgstr ""

#: ../src/gui/MyFrameMain.cpp
msgid "Multi-Sync Input enabled: input is replicated to all connections."
msgstr ""

#: ../src/gui/MyFrameMain.cpp
msgid "Replicate mouse and keyboard input to all connections."
msgstr ""

#: ../src/gui/FrameMain.cpp:24
msgid "MultiVNC"
msgstr "MultiVNC"
Expand Down
84 changes: 84 additions & 0 deletions src/gui/MyFrameMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,16 @@ MyFrameMain::MyFrameMain(wxWindow* parent, int id, const wxString& title,
// record/replay
frame_main_menubar->Enable(ID_INPUT_RECORD, false);
frame_main_menubar->Enable(ID_INPUT_REPLAY, false);
// multi-sync input
multi_sync_enabled = false;
{
wxMenu* machineMenu = frame_main_menubar->GetMenu(0);
machineMenu->InsertCheckItem(9, ID_MULTISYNC,
_("Multi-Sync Input\tCtrl-M"),
_("Replicate mouse and keyboard input to all connections."));
Bind(wxEVT_MENU, &MyFrameMain::machine_multisync, this, ID_MULTISYNC);
frame_main_menubar->Enable(ID_MULTISYNC, false);
}
// bookmarks
frame_main_menubar->Enable(wxID_ADD, false);
// window sharing
Expand Down Expand Up @@ -1274,6 +1284,12 @@ void MyFrameMain::conn_setup(VNCConn *c) {
GetToolBar()->EnableTool(ID_INPUT_RECORD, true);
}

// multi-sync: enable when 2+ connections, update targets if already active
if (connections.size() >= 2)
frame_main_menubar->Enable(ID_MULTISYNC, true);
if (multi_sync_enabled)
updateMultiSyncTargets();

}


Expand Down Expand Up @@ -1340,6 +1356,15 @@ void MyFrameMain::conn_terminate(int which)
// erase the ConnBlob
connections.erase(connections.begin() + which);

// multi-sync: auto-disable if fewer than 2 connections remain
if (multi_sync_enabled && connections.size() < 2) {
multi_sync_enabled = false;
frame_main_menubar->Check(ID_MULTISYNC, false);
}
updateMultiSyncTargets();
if (connections.size() < 2)
frame_main_menubar->Enable(ID_MULTISYNC, false);

if(connections.size() == 0) // nothing to end
{
// "end connection"
Expand Down Expand Up @@ -1951,6 +1976,61 @@ void MyFrameMain::machine_input_replay(wxCommandEvent &event)
}


void MyFrameMain::machine_multisync(wxCommandEvent &event)
{
multi_sync_enabled = event.IsChecked();
updateMultiSyncTargets();

if (multi_sync_enabled)
wxLogStatus(_("Multi-Sync Input enabled: input is replicated to all connections."));
else
wxLogStatus(_("Multi-Sync Input disabled."));
}


void MyFrameMain::updateMultiSyncTargets()
{
const wxString syncPrefix = "[Sync] ";

if (!multi_sync_enabled || connections.size() < 2) {
// clear all sync targets and restore tab titles
for (size_t i = 0; i < connections.size(); ++i) {
connections[i].viewerwindow->setSyncTargets({});
wxString label = notebook_connections->GetPageText(i);
if (label.StartsWith(syncPrefix))
notebook_connections->SetPageText(i, label.Mid(syncPrefix.length()));
}
return;
}

int sel = notebook_connections->GetSelection();
if (sel == wxNOT_FOUND)
return;

// build target list: all connections except the active one
std::vector<VNCConn*> targets;
for (size_t i = 0; i < connections.size(); ++i) {
if ((int)i != sel)
targets.push_back(connections[i].conn);
}

// only the active tab's ViewerWindow gets sync targets
for (size_t i = 0; i < connections.size(); ++i) {
wxString label = notebook_connections->GetPageText(i);
if ((int)i == sel) {
connections[i].viewerwindow->setSyncTargets(targets);
// master tab: strip prefix if present
if (label.StartsWith(syncPrefix))
notebook_connections->SetPageText(i, label.Mid(syncPrefix.length()));
} else {
connections[i].viewerwindow->setSyncTargets({});
// slave tab: add prefix if not present
if (!label.StartsWith(syncPrefix))
notebook_connections->SetPageText(i, syncPrefix + label);
}
}
}


void MyFrameMain::machine_exit(wxCommandEvent &event)
{
Expand Down Expand Up @@ -2673,6 +2753,10 @@ void MyFrameMain::notebook_connections_pagechanged(wxNotebookEvent &event)
}
else // no object, i.e. disabled
frame_main_menubar->Check(ID_SEAMLESS_DISABLED, true);

// update multi-sync targets when active tab changes
if (multi_sync_enabled)
updateMultiSyncTargets();
}


Expand Down
7 changes: 6 additions & 1 deletion src/gui/MyFrameMain.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,11 @@ class MyFrameMain: public FrameMain

bool saveStats(VNCConn* c, int conn_index, const wxArrayString& stats, wxString desc, bool autosave);


// multi-sync input
bool multi_sync_enabled;
void updateMultiSyncTargets();


protected:
DECLARE_EVENT_TABLE();

Expand Down Expand Up @@ -141,6 +145,7 @@ class MyFrameMain: public FrameMain
void machine_save_stats(wxCommandEvent &event);
void machine_input_record(wxCommandEvent &event);
void machine_input_replay(wxCommandEvent &event);
void machine_multisync(wxCommandEvent &event);
void machine_exit(wxCommandEvent &event);

void view_toggletoolbar(wxCommandEvent &event);
Expand Down
50 changes: 49 additions & 1 deletion src/gui/ViewerWindow.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@


#include <vector>
#include <wx/gdicmn.h>
#include <wx/log.h>
#include <wx/math.h>
Expand Down Expand Up @@ -63,6 +64,7 @@ class VNCCanvas: public wxPanel
wxRegion updated_area;
double scale_factor = 1.0;
bool do_keyboard_grab;
std::vector<VNCConn*> sync_targets;
};


Expand Down Expand Up @@ -309,24 +311,49 @@ void VNCCanvas::onMouseAction(wxMouseEvent &event)
event.m_y = std::round(event.m_y / scale_factor);

conn->sendPointerEvent(event);

// multi-sync: replicate to other connections
for (VNCConn* target : sync_targets) {
int tw = target->getFrameBufferWidth();
int th = target->getFrameBufferHeight();
if (tw <= 0 || th <= 0)
continue;
wxMouseEvent sync_event(event);
int sw = conn->getFrameBufferWidth();
int sh = conn->getFrameBufferHeight();
if (sw > 0 && sh > 0) {
sync_event.m_x = std::round(event.m_x * (double)tw / sw);
sync_event.m_y = std::round(event.m_y * (double)th / sh);
}
target->sendPointerEvent(sync_event);
}
}


void VNCCanvas::onKeyDown(wxKeyEvent &event)
{
conn->sendKeyEvent(event, true, false);

for (VNCConn* target : sync_targets)
target->sendKeyEvent(event, true, false);
}


void VNCCanvas::onKeyUp(wxKeyEvent &event)
{
conn->sendKeyEvent(event, false, false);

for (VNCConn* target : sync_targets)
target->sendKeyEvent(event, false, false);
}


void VNCCanvas::onChar(wxKeyEvent &event)
{
conn->sendKeyEvent(event, true, true);

for (VNCConn* target : sync_targets)
target->sendKeyEvent(event, true, true);
}


Expand All @@ -339,7 +366,7 @@ void VNCCanvas::onFocusGain(wxFocusEvent &event)
void VNCCanvas::onFocusLoss(wxFocusEvent &event)
{
wxLogDebug(wxT("VNCCanvas %p: lost focus, upping key modifiers"), this);

wxKeyEvent key_event;

key_event.m_keyCode = WXK_SHIFT;
Expand All @@ -348,6 +375,16 @@ void VNCCanvas::onFocusLoss(wxFocusEvent &event)
conn->sendKeyEvent(key_event, false, false);
key_event.m_keyCode = WXK_CONTROL;
conn->sendKeyEvent(key_event, false, false);

for (VNCConn* target : sync_targets) {
wxKeyEvent sync_key;
sync_key.m_keyCode = WXK_SHIFT;
target->sendKeyEvent(sync_key, false, false);
sync_key.m_keyCode = WXK_ALT;
target->sendKeyEvent(sync_key, false, false);
sync_key.m_keyCode = WXK_CONTROL;
target->sendKeyEvent(sync_key, false, false);
}
}


Expand Down Expand Up @@ -663,3 +700,14 @@ void ViewerWindow::grabKeyboard(bool grabit)
// grab later on enter/leave
canvas->do_keyboard_grab = grabit;
}

void ViewerWindow::setSyncTargets(const std::vector<VNCConn*>& targets)
{
if(canvas)
canvas->sync_targets = targets;
}

VNCConn* ViewerWindow::getConn() const
{
return canvas ? canvas->conn : nullptr;
}
3 changes: 3 additions & 0 deletions src/gui/ViewerWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#ifndef VIEWERWINDOW_H
#define VIEWERWINDOW_H

#include <vector>
#include <wx/wx.h>
#include <wx/scrolwin.h>
#include <wx/log.h>
Expand All @@ -27,6 +28,8 @@ class ViewerWindow: public wxPanel
void showOneToOne(bool show_1to1);
void grabKeyboard(bool yesno);

void setSyncTargets(const std::vector<VNCConn*>& targets);
VNCConn* getConn() const;

protected:
wxStaticText* label_updrawbytes;
Expand Down
1 change: 1 addition & 0 deletions src/gui/evtids.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ enum
ID_INPUT_RECORD,
ID_INPUT_REPLAY,
ID_ISSUE_LIST,
ID_MULTISYNC,
};


Expand Down
Loading