2026-10-06 15:58:02 +02:00
|
|
|
# A host's Kokkoja
|
|
|
|
|
|
|
|
|
|
The host starts a session, invites the guests and drives the session:
|
|
|
|
|
puts images on the page, starts new pages, loads pages from a notebook,
|
|
|
|
|
and decides which guests may do the same. In a lesson, the teacher is
|
|
|
|
|
the host. Everything in [A guest's Kokkoja](guest.md) applies to the host
|
2026-10-11 16:59:03 +02:00
|
|
|
too; this part describes what is added.
|
|
|
|
|
|
|
|
|
|
## Hosting from the web site, or with the Kokkoja program
|
|
|
|
|
|
|
|
|
|
A host, like a guest, can use Kokkoja with nothing installed: open
|
|
|
|
|
`https://kokkoja.andykopra.com/` in a browser, enter a name, press
|
|
|
|
|
**Start a session**, and the invitation is ready in the Session window.
|
|
|
|
|
Your notebooks are then kept inside that browser, as a guest's are (see
|
|
|
|
|
"Your notebook" in the guest's part): they belong to that browser on
|
|
|
|
|
that computer, and a page leaves it by **Keep** or **Export**, which
|
|
|
|
|
download it. "Image" asks for the file with the browser's own chooser.
|
|
|
|
|
|
|
|
|
|
If you would rather have your notebooks as ordinary directories of
|
|
|
|
|
files, where you can open, copy, back up and send them, run the Kokkoja
|
|
|
|
|
program on your own computer. It is a small Python program with two
|
|
|
|
|
jobs: it shows Kokkoja in your web browser, and it reads and writes
|
|
|
|
|
your notebooks as directories and files. It listens only to your own
|
|
|
|
|
computer and talks to nothing else but the relay you name. Your
|
|
|
|
|
identity, too, then belongs to your computer rather than to one
|
|
|
|
|
browser, so your writing from an earlier lesson is yours from any
|
|
|
|
|
browser there. A teacher who keeps notebooks of exercises and a
|
|
|
|
|
notebook per student will want the program; for a first session the
|
|
|
|
|
web site is enough.
|
2026-10-06 15:58:02 +02:00
|
|
|
|
|
|
|
|
## Installing the Kokkoja program
|
|
|
|
|
|
|
|
|
|
You need:
|
|
|
|
|
|
|
|
|
|
* **Linux or macOS.** Windows has not been tried yet.
|
|
|
|
|
* **Python 3.** Linux has it. On macOS, open Terminal and type
|
|
|
|
|
`python3 --version`; if Python is not installed, macOS offers to
|
|
|
|
|
install the command line developer tools, which include it. Any Python
|
|
|
|
|
from 3.9 on will do.
|
2026-10-10 19:01:20 +02:00
|
|
|
* **A web browser.** Firefox, Brave or Chrome, or Safari on a Mac;
|
|
|
|
|
other browsers built on the same engines very probably work.
|
2026-10-06 15:58:02 +02:00
|
|
|
* **A pen tablet**, if you want to write by hand. A mouse works for
|
|
|
|
|
pointing and for rough marks.
|
|
|
|
|
|
2026-10-10 19:01:20 +02:00
|
|
|
Get Kokkoja from its repository: download
|
|
|
|
|
|
|
|
|
|
https://git.andykopra.com/ack/kokkoja-rel/archive/main.zip
|
|
|
|
|
|
|
|
|
|
and unpack it, or, if you have git,
|
2026-10-06 15:58:02 +02:00
|
|
|
|
|
|
|
|
git clone https://git.andykopra.com/ack/kokkoja-rel.git kokkoja
|
|
|
|
|
|
|
|
|
|
Nothing else is installed and nothing is changed on your system. To
|
2026-10-10 19:01:20 +02:00
|
|
|
update later, download again or run `git pull` in that directory.
|
|
|
|
|
Kokkoja is free software under the GNU General Public License; the
|
|
|
|
|
`LICENSE.md` file in the directory is the license. To
|
2026-10-06 15:58:02 +02:00
|
|
|
remove Kokkoja, delete the directory; your notebooks are elsewhere and
|
|
|
|
|
stay.
|
|
|
|
|
|
2026-10-10 19:01:20 +02:00
|
|
|
### On a Mac
|
|
|
|
|
|
|
|
|
|
The same steps, with four things to know:
|
|
|
|
|
|
|
|
|
|
* Terminal is in Applications → Utilities. The first `python3` or
|
|
|
|
|
`git` command may make macOS offer to install the command line
|
|
|
|
|
developer tools; accept, and run the command again when it has
|
|
|
|
|
finished.
|
|
|
|
|
* The first time the program writes a notebook, macOS asks whether
|
|
|
|
|
Terminal may reach your Documents folder. Allow it, once; the
|
|
|
|
|
notebooks are there. The answer can be changed later under System
|
|
|
|
|
Settings → Privacy & Security → Files and Folders.
|
|
|
|
|
* The program opens Kokkoja in your default browser, Safari included.
|
|
|
|
|
To use another, start the program with `--no-browser` and open the
|
|
|
|
|
address it prints in the browser you prefer.
|
|
|
|
|
* Wherever this documentation says Ctrl for zooming, use Command on a
|
|
|
|
|
Mac. Both work, so a hand used to Ctrl is not punished.
|
|
|
|
|
|
2026-10-06 15:58:02 +02:00
|
|
|
## Starting Kokkoja
|
|
|
|
|
|
|
|
|
|
Open a terminal in the Kokkoja directory and run
|
|
|
|
|
|
|
|
|
|
python3 kokkoja.py --relay wss://kokkoja.andykopra.com/relay
|
|
|
|
|
|
|
|
|
|
The program prints an address beginning `http://localhost:8760/` and
|
|
|
|
|
opens your browser there. Leave the terminal open: the program must run
|
|
|
|
|
as long as you are in a session. Ctrl-C stops it.
|
|
|
|
|
|
|
|
|
|
The address the program prints contains a secret token. Your browser
|
|
|
|
|
remembers it, so afterwards `http://localhost:8760/` alone brings Kokkoja
|
|
|
|
|
back; but if the browser ever says that the notebooks are locked, open
|
|
|
|
|
the full address the program printed. The token is what stops any other
|
|
|
|
|
web page you might have open from reading your notebooks.
|
|
|
|
|
|
|
|
|
|
The relay address names the *Kokkoja server* you use. A server does two
|
|
|
|
|
things: it passes the participants' messages, encrypted so that it
|
|
|
|
|
cannot read them, and it serves the web site that your guests join from.
|
|
|
|
|
The address above is Andy's server; whoever runs a server for you gives
|
2026-10-10 19:01:20 +02:00
|
|
|
you its address. The program remembers it, so from the second time on
|
|
|
|
|
|
|
|
|
|
python3 kokkoja.py
|
|
|
|
|
|
|
|
|
|
is enough, and the program says which relay it is using. Give the
|
|
|
|
|
option again only to change servers. Started for the first time with no
|
|
|
|
|
relay, it stops and asks for one.
|
2026-10-06 15:58:02 +02:00
|
|
|
|
|
|
|
|
Other options, all optional:
|
|
|
|
|
|
|
|
|
|
* `--notebooks DIRECTORY` keeps the notebooks somewhere other than
|
|
|
|
|
`Kokkoja` in your Documents directory.
|
|
|
|
|
* `--port NUMBER` uses another port than 8760, if that one is taken.
|
|
|
|
|
* `--no-browser` does not open a browser; open the printed address
|
|
|
|
|
yourself.
|
|
|
|
|
* `--site ADDRESS` names the web site that invitations link to. You
|
|
|
|
|
need it only if your server's web site is not at the relay's host.
|
2026-10-11 16:59:03 +02:00
|
|
|
* `--trash DIRECTORY` is where deleted notebooks and pages are moved,
|
|
|
|
|
instead of your system's Trash; `--trash none` deletes them outright.
|
2026-10-06 15:58:02 +02:00
|
|
|
|
|
|
|
|
## Starting a session
|
|
|
|
|
|
|
|
|
|
On the start screen, enter your name and the notebook for this session,
|
2026-10-10 19:01:20 +02:00
|
|
|
and press **Start a session**. You are on page 1, a blank sheet, and
|
|
|
|
|
**Session** in the toolbar shows the invitation.
|
2026-10-06 15:58:02 +02:00
|
|
|
|
|
|
|
|
### The notebook
|
|
|
|
|
|
2026-10-10 19:01:20 +02:00
|
|
|
A notebook is a directory under `Kokkoja` in your Documents directory.
|
|
|
|
|
The start screen lists the notebooks you have; until you make one, there
|
|
|
|
|
is *General*, the notebook for whatever has no notebook of its own. The
|
|
|
|
|
last entry of the list, **New notebook…**, asks for a name and makes a
|
|
|
|
|
notebook of that name, which exists from the moment a page is written
|
|
|
|
|
into it. For teaching, a notebook per student works well: everything a
|
|
|
|
|
student is given, with everything they and you wrote on it, gathers in
|
|
|
|
|
that student's notebook, and the next lesson with that student starts
|
|
|
|
|
by choosing it again. Your library of exercises can live in notebooks
|
|
|
|
|
of its own, such as *Exercises A1*, filled by keeping pages in a session
|
|
|
|
|
of your own with nobody else present.
|
|
|
|
|
|
|
|
|
|
The notebook can be changed during a session, in the notebook list in
|
|
|
|
|
the toolbar. The page you are on then continues in the notebook chosen.
|
2026-10-06 15:58:02 +02:00
|
|
|
|
|
|
|
|
### The invitation
|
|
|
|
|
|
2026-10-10 19:01:20 +02:00
|
|
|
**Session** in the toolbar opens a window; **Invitation** there shows a
|
|
|
|
|
link. **Copy** copies it; send it to
|
2026-10-06 15:58:02 +02:00
|
|
|
your guests by email, in a chat message, or however you reach them. A
|
2026-10-10 19:01:20 +02:00
|
|
|
guest opens it, enters a name and is in. Below the link the same
|
|
|
|
|
invitation stands as a QR code: a guest with a phone or a tablet points
|
|
|
|
|
its camera at your screen, and the link opens there. A guest with the Kokkoja
|
2026-10-06 15:58:02 +02:00
|
|
|
program installed may paste it into their own program instead. The link
|
|
|
|
|
carries the secret that protects the session, so send it only to those
|
|
|
|
|
who should be there; anyone with the link can join and read the page.
|
|
|
|
|
Each session you start has a new invitation.
|
|
|
|
|
|
|
|
|
|
An invitation is good as long as you keep the session open. A guest can
|
|
|
|
|
join at any time, see everything written so far, and leave and return.
|
|
|
|
|
|
|
|
|
|
## Driving the session
|
|
|
|
|
|
|
|
|
|
Three buttons at the right of the toolbar are the host's.
|
|
|
|
|
|
|
|
|
|
**New** starts a new blank page for everyone. Pages are numbered from 1
|
|
|
|
|
through the session. The page being left is kept in every participant's
|
|
|
|
|
notebook, by itself, under a dated name; nobody has to remember to save.
|
|
|
|
|
|
|
|
|
|
**Image** puts an image file on the page for everyone. Kokkoja's own
|
|
|
|
|
file chooser opens, beginning where your notebooks are and remembering
|
|
|
|
|
where you last chose from; a directory path can also be typed into it.
|
|
|
|
|
It shows small pictures of the image files it finds. Choose one and it
|
2026-10-10 19:01:20 +02:00
|
|
|
is placed on the page in one way always: 5 mm below the lowest image
|
|
|
|
|
there, or at the top of the page if there is none, centred across the
|
|
|
|
|
page's width, at its natural size, in front of the images already
|
|
|
|
|
there. Natural size is the size the file records: a scan arrives at
|
|
|
|
|
the size of the paper it came from. A photo from a phone or camera
|
|
|
|
|
records no useful size and arrives at a tenth of a millimetre per
|
|
|
|
|
pixel. An image wider than the page widens the page on both sides to
|
|
|
|
|
hold it. From there you move and scale it by hand, as described next;
|
|
|
|
|
there is no other setting to choose. PNG and JPEG files are shared as
|
|
|
|
|
they are unless very large; other formats, and images over 2400 pixels
|
|
|
|
|
on a side or 1.5 MB, are converted to JPEG and reduced first, which
|
|
|
|
|
does not change the size they arrive at. A page holds up to 12 images.
|
|
|
|
|
|
|
|
|
|
To move an image, rest the pen on it, without moving, for a little over
|
|
|
|
|
half a second: a green outline appears, and the image follows the pen
|
|
|
|
|
until you lift it. It comes to the front of the other images, which a
|
|
|
|
|
hold without moving also does. To scale an image, rest the pen near one
|
|
|
|
|
of its corners: a green square marks the corner, and dragging it scales
|
|
|
|
|
the image along its diagonal, the opposite corner staying put and the
|
|
|
|
|
shape kept. This works with every tool: a dot the pen may have drawn
|
|
|
|
|
while resting is removed, and the eraser erases nothing while it rests.
|
|
|
|
|
Writing is not attached to images: an image moved from under writing
|
|
|
|
|
leaves the writing where it was, so compose the images first and write
|
|
|
|
|
afterwards. Only you and co-hosts can move images.
|
2026-10-06 15:58:02 +02:00
|
|
|
|
|
|
|
|
For a page that begins with an image, press **New** and then **Image**.
|
|
|
|
|
For a series of exercises, keep pressing **Image** on the same page: the
|
|
|
|
|
sheet grows downward and everyone scrolls through them. A new image does
|
|
|
|
|
not change anyone's zoom; it appears below, to be scrolled to.
|
|
|
|
|
|
2026-10-10 19:01:20 +02:00
|
|
|
A tap of the eraser on an image removes it, whoever added it and
|
|
|
|
|
whenever. Writing on it stays where it was, so remove an image before
|
|
|
|
|
anyone writes on it unless the writing is meant to stay. The page keeps
|
|
|
|
|
the size the image gave it; **Shrink** trims it. A guest who added an
|
|
|
|
|
image may remove it, even after they have stopped being a co-host.
|
|
|
|
|
|
|
|
|
|
**Fit** and **A4**, pressed by you, act on every participant's screen,
|
|
|
|
|
each in their own window: the way to bring everyone back to the whole
|
|
|
|
|
page. A guest's Fit and A4 change only that guest's screen.
|
|
|
|
|
|
|
|
|
|
**Hide**, the tool beside the Eraser, covers part of the page for
|
|
|
|
|
everyone: drag open a rectangle, and whatever lies under it, writing of
|
|
|
|
|
anyone included, is covered in white, marked by blue corners that tell
|
|
|
|
|
the students something is there. Use it to cover a solution until the
|
|
|
|
|
student has tried, or a part of the exercise for later. Rest the pen on
|
|
|
|
|
it to move it, near a corner to resize it; a tap of the eraser removes
|
2026-10-11 13:17:22 +02:00
|
|
|
it and shows what was covered, and **Undo** takes back any of these as
|
|
|
|
|
it does your writing. Nothing under a Hide is lost, and a
|
2026-10-10 19:01:20 +02:00
|
|
|
student cannot uncover it by hiding your writing on their screen: a Hide
|
|
|
|
|
belongs to the page, not to your writing. A Hide is white in an
|
|
|
|
|
exported picture and in the page file as other programs see it.
|
|
|
|
|
|
|
|
|
|
With the Text tool, a rectangle dragged open is a *text rectangle*: a
|
|
|
|
|
red box with a white ground, which covers the image beneath it and no
|
|
|
|
|
writing, in which text wraps and which grows downward as it fills. It
|
|
|
|
|
is the "write your answer here" box of a worksheet: draw it on the scan
|
|
|
|
|
where the answer belongs, and the student types into their own box or
|
|
|
|
|
beside yours. Only its owner can type in a box, as with any text.
|
|
|
|
|
|
|
|
|
|
**Widen**, among the view buttons, makes the page wider for everyone,
|
|
|
|
|
until it fills your window at your present zoom: the quickest way to
|
|
|
|
|
more room for writing beside an exercise. The sheet grows equally on
|
|
|
|
|
both sides, so nothing on the page moves. The page keeps the new width
|
|
|
|
|
in everyone's notebook. **Shrink** is its opposite: the page becomes
|
|
|
|
|
just large enough for everything on it, images and writing, with the
|
|
|
|
|
margin of 5 mm around, which trims a page down to its exercise before you keep
|
|
|
|
|
or export it. A blank page cannot shrink.
|
2026-10-06 15:58:02 +02:00
|
|
|
|
2026-10-11 16:59:03 +02:00
|
|
|
**Notebooks** starts a new page for everyone from a page kept in one of
|
2026-10-06 15:58:02 +02:00
|
|
|
your notebooks, with everything that was written on it. A chooser shows
|
|
|
|
|
your notebooks on the left and small pictures of the chosen notebook's
|
|
|
|
|
kept pages on the right. The loaded page is a copy: the kept page is
|
|
|
|
|
not changed by anything that happens next. Each layer on it still
|
|
|
|
|
belongs to the participant who wrote it, so a student's answers from an
|
|
|
|
|
earlier lesson are still theirs, and your corrections still yours.
|
|
|
|
|
|
|
|
|
|
This is also how you return to an earlier page of the session: the page
|
2026-10-11 16:59:03 +02:00
|
|
|
was kept when you left it, and **Notebooks** brings it back as a new page.
|
2026-10-06 15:58:02 +02:00
|
|
|
A lesson might go: **New**, **Image** for the exercise, work, **New**
|
2026-10-11 16:59:03 +02:00
|
|
|
for a point of grammar, work, **Notebooks** to return to the exercise.
|
|
|
|
|
|
|
|
|
|
The same chooser deletes. Every page card and every notebook in the
|
2026-10-11 17:04:08 +02:00
|
|
|
list carries a small dot at its left; a tap marks it with a tick, a second tap unmarks it,
|
2026-10-11 16:59:03 +02:00
|
|
|
and a marked notebook goes with every page in it. As soon as something
|
|
|
|
|
is marked, a **Delete** button in the chooser's header says how much:
|
|
|
|
|
"Delete 3 pages?", "Delete 1 notebook and 3 pages?". The first press
|
|
|
|
|
says what will happen, "Press again to move 3 pages to the Trash";
|
|
|
|
|
the second does it. With the Kokkoja program, deleted notebooks and
|
|
|
|
|
pages are moved to your system's Trash, where the
|
|
|
|
|
file manager can put them back; the program's `--trash` option
|
|
|
|
|
names another directory, or `none` to delete outright. In the browser
|
|
|
|
|
there is no Trash, and the button says "for good". The notebook
|
|
|
|
|
you are writing in cannot be deleted while you are: choose another
|
|
|
|
|
notebook in the toolbar first.
|
2026-10-06 15:58:02 +02:00
|
|
|
|
2026-10-10 19:01:20 +02:00
|
|
|
## Co-hosts
|
2026-10-06 15:58:02 +02:00
|
|
|
|
2026-10-10 19:01:20 +02:00
|
|
|
In the **Participants** list of the Session window, each guest's name
|
|
|
|
|
has a box **Co-host** beside it. Ticking it makes that guest a
|
|
|
|
|
co-host: they may then start new pages, put images on the page and
|
|
|
|
|
arrange them, load pages from their notebook, widen, shrink and hide,
|
|
|
|
|
exactly as you can, and the buttons for it appear on their toolbar.
|
|
|
|
|
Unticking it takes it back; otherwise it lasts until the session
|
|
|
|
|
ends. What stays yours alone: making co-hosts, and bringing everyone's
|
|
|
|
|
view to the page with Fit or A4. Guests, co-hosts or not, can never
|
|
|
|
|
erase or change anyone's writing but their own; that needs no setting.
|
2026-10-06 15:58:02 +02:00
|
|
|
|
|
|
|
|
## Hiding writing
|
|
|
|
|
|
|
|
|
|
The box in front of each participant's name shows or hides that
|
|
|
|
|
participant's writing on your screen only. Hide a student's answers to
|
|
|
|
|
see the exercise clean, hide your own corrections to see what the
|
|
|
|
|
student sees, show them again; the others notice nothing. **Export**
|
|
|
|
|
leaves hidden writing out of the picture it makes, which is how to make a
|
|
|
|
|
picture of the exercise with the corrections alone.
|
|
|
|
|
|
|
|
|
|
## Keeping and exporting
|
|
|
|
|
|
|
|
|
|
The page you are on is written continuously to `Current.svg` in the
|
|
|
|
|
current notebook, and copied to a dated file whenever the session moves
|
2026-10-10 19:01:20 +02:00
|
|
|
on. **Keep** makes such a copy now, named for the day and a serial
|
2026-10-06 15:58:02 +02:00
|
|
|
number, such as `2026_10_06_02.svg`; pressing it again before anything
|
2026-10-11 16:59:03 +02:00
|
|
|
has changed makes no second copy, and neither does moving on from a
|
|
|
|
|
page that is already kept, such as one loaded from the notebook and left
|
|
|
|
|
as it was. Any mark counts as a change, even a
|
2026-10-10 19:01:20 +02:00
|
|
|
dot from a stray touch of the pen. Use it to mark a state worth keeping
|
2026-10-06 15:58:02 +02:00
|
|
|
on its own, or to add a finished page to a notebook of exercises.
|
|
|
|
|
|
|
|
|
|
**Export** saves a picture of the page as you see it, as a PNG file at
|
|
|
|
|
200 dots per inch, in a directory and under a name you choose in
|
|
|
|
|
Kokkoja's file chooser. Replacing an existing file takes a second press
|
|
|
|
|
of the button, so a slip does not overwrite anything.
|
|
|
|
|
|
|
|
|
|
The notebooks are ordinary directories, and a page is an ordinary SVG
|
|
|
|
|
file. Open one in a browser or in Inkscape, attach it to an email, keep
|
|
|
|
|
it with your other documents. Only Kokkoja can load it as a live page
|
|
|
|
|
again, with each person's writing still theirs.
|
|
|
|
|
|
|
|
|
|
## Ending a session
|
|
|
|
|
|
|
|
|
|
Close the browser tab, or stop the program with Ctrl-C in its terminal.
|
|
|
|
|
There is nothing to save: the page is already in your notebook, and in
|
|
|
|
|
each guest's. Guests who are still connected can go on writing on the
|
|
|
|
|
page among themselves, but no new page can be started without you or a
|
2026-10-10 19:01:20 +02:00
|
|
|
co-host, and a guest who arrives after everyone
|
2026-10-06 15:58:02 +02:00
|
|
|
has left finds an empty session. The next lesson is a new session with a
|
|
|
|
|
new invitation; load the pages you need from the student's notebook.
|
|
|
|
|
|
|
|
|
|
## When something goes wrong
|
|
|
|
|
|
|
|
|
|
* **The browser says the notebooks are locked.** Open Kokkoja from the
|
|
|
|
|
full address the program printed when it started, the one with the
|
|
|
|
|
token.
|
2026-10-10 19:01:20 +02:00
|
|
|
* **"Not connected" above the page.** Kokkoja reconnects by itself as
|
2026-10-06 15:58:02 +02:00
|
|
|
soon as the relay can be reached, and sends what was written meanwhile.
|
|
|
|
|
If it does not come back, check your connection; the page is safe in
|
|
|
|
|
your notebook either way.
|
|
|
|
|
* **A guest sees "Waiting for the host's page".** You have not started
|
|
|
|
|
a page yet, or your connection is down. The first page is started when
|
|
|
|
|
you start the session, so this usually means the latter.
|
2026-10-10 19:01:20 +02:00
|
|
|
* **Pressure does not work.** The browser's console (F12) logs what
|
|
|
|
|
the browser receives from your pen at your first stroke. If it says
|
|
|
|
|
*mouse*, the browser is not seeing the pen as a pen; try the other
|
|
|
|
|
browser.
|
|
|
|
|
* **"Address already in use" when starting the program.** A copy of
|
|
|
|
|
the program is already running, usually in another terminal window.
|
|
|
|
|
Only one can run at a time; use it, or stop it there with Ctrl-C and
|
|
|
|
|
start again.
|
|
|
|
|
* **Guests cannot connect.** Look at the line `Relay: ...` the program
|
|
|
|
|
printed when it started: it names the relay the session goes through.
|
|
|
|
|
If it is not your server's address, stop the program and start it
|
|
|
|
|
again with `--relay` and the right address.
|