Skip to content

Commit dd21a1b

Browse files
authored
Merge pull request #3 from hackmdio/custom-title-bar
Custom title bar for Linux & Windows close #2
2 parents 7fa597a + fa2dc18 commit dd21a1b

16 files changed

+2866
-106
lines changed

app.css

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
html,
2+
body {
3+
margin: 0;
4+
height: 100%;
5+
background-color: #f8f8f8;
6+
overflow: hidden;
7+
font-family: Arial, Helvetica, sans-serif;
8+
}
9+
10+
body {
11+
display: flex;
12+
flex-direction: column;
13+
}
14+
15+
webview {
16+
flex: 1;
17+
}
18+
19+
navbar {
20+
height: 23px;
21+
align-items: center;
22+
width: 100%;
23+
display: flex;
24+
-webkit-app-region: drag;
25+
background-color: #f8f8f8;
26+
color: #484848;
27+
transition: color 0.5s, background-color 0.5s;
28+
}
29+
30+
#navbar-container {
31+
font-size: 0.9em;
32+
font-family: "Courier New", Courier, monospace;
33+
display: flex;
34+
flex: 1;
35+
justify-content: space-between;
36+
-webkit-user-select: none;
37+
user-select: none;
38+
padding: 0 2px;
39+
}
40+
41+
navbar.dark {
42+
background-color: #333333;
43+
color: white;
44+
}
45+
46+
navbar.dark .control-buttons>*:hover {
47+
color: white;
48+
}
49+
50+
#navbar-container .control-buttons {
51+
display: flex;
52+
}
53+
54+
#navbar-container .control-buttons:nth-child(2) {
55+
padding-left: 2em;
56+
flex: 1;
57+
}
58+
59+
#navbar-container .control-buttons:nth-child(3) {
60+
font-size: 1.3em;
61+
}
62+
63+
#navbar-container .control-buttons>* {
64+
margin: 0 .3em;
65+
cursor: pointer;
66+
-webkit-user-select: none;
67+
-webkit-app-region: no-drag;
68+
height: 23px;
69+
display: flex;
70+
align-items: center;
71+
}
72+
73+
#navbar-container .control-buttons>*:hover {
74+
color: #c1c1c1;
75+
}

index.html

Lines changed: 9 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -4,74 +4,8 @@
44
<title>HackMD</title>
55
<meta charset="UTF-8">
66
<meta name="viewport" content="width=device-width, initial-scale=1">
7-
<style>
8-
html, body {
9-
margin: 0;
10-
height: 100%;
11-
background-color: #f8f8f8;
12-
overflow: hidden;
13-
font-family: Arial, Helvetica, sans-serif;
14-
}
15-
16-
body {
17-
display: flex;
18-
flex-direction: column;
19-
}
20-
21-
webview {
22-
flex: 1;
23-
}
24-
25-
navbar {
26-
height: 23px;
27-
align-items: center;
28-
width: 100%;
29-
display: flex;
30-
-webkit-app-region: drag;
31-
padding-left: 75px;
32-
background-color: #f8f8f8;
33-
color: #484848;
34-
35-
transition: color 0.5s, background-color 0.5s;
36-
}
37-
38-
#navbar-container {
39-
font-size: 0.9em;
40-
font-family: "Courier New", Courier, monospace;
41-
display: flex;
42-
flex: 1;
43-
justify-content: space-between;
44-
-webkit-user-select: none;
45-
user-select: none;
46-
}
47-
48-
navbar.dark {
49-
background-color: #333333;
50-
color: white;
51-
}
52-
53-
navbar.dark .control-buttons > *:hover {
54-
color: white;
55-
}
56-
57-
#navbar-container .control-buttons {
58-
flex: 1;
59-
display: flex;
60-
}
61-
62-
#navbar-container .control-buttons > * {
63-
margin: 0 .3em;
64-
cursor: pointer;
65-
-webkit-user-select: none;
66-
height: 23px;
67-
display: flex;
68-
align-items: center;
69-
}
70-
71-
#navbar-container .control-buttons > *:hover {
72-
color: #c1c1c1;
73-
}
74-
</style>
7+
<link rel="stylesheet" type="text/css" href="vendor/font-awesome.min.css">
8+
<link rel="stylesheet" type="text/css" href="./app.css">
759
</head>
7610
<body>
7711
<navbar>
@@ -81,10 +15,16 @@
8115
<div class="refresh">REFRESH</div>
8216
<div class="navigate-back" style="margin: 0 1em;">&#x3C;</div>
8317
<div class="navigate-foward">&#x3E;</div>
18+
<div class="more-menu">...</div>
8419
</div>
85-
<div class="control-buttons" style="flex: 2">
20+
<div class="control-buttons">
8621
<div class="title"></div>
8722
</div>
23+
<div class="control-buttons">
24+
<div class="minimize-window">-</div>
25+
<div class="toggle-window">+</div>
26+
<div class="close-window">x</div>
27+
</div>
8828
</div>
8929
</navbar>
9030
<script src="renderer.js"></script>

ipc/client.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const { ipcRenderer } = require('electron');
2+
3+
module.exports = function(commandId, args) {
4+
ipcRenderer.send('main:command', { commandId, args });
5+
}

ipc/consumer.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const {app, Menu, BrowserWindow, shell} = require('electron');
2+
const path = require('path');
3+
4+
const { createWindow } = require('../window');
5+
6+
module.exports = function(commandId, args={}) {
7+
switch(commandId) {
8+
case 'createWindow':
9+
createWindow(args);
10+
break;
11+
case 'refreshWindow':
12+
const win = BrowserWindow.getFocusedWindow();
13+
win.webContents.send('web:refresh');
14+
break;
15+
case 'learnMore':
16+
shell.openExternal('https://hackmd.io');
17+
break;
18+
default:
19+
break;
20+
}
21+
}

ipc/server.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
const { ipcMain } = require('electron');
2+
const consumer = require('./consumer');
3+
4+
ipcMain.on('main:command', (event, { commandId, args }) => {
5+
consumer(commandId, args);
6+
});

main.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ const path = require('path');
55
const menu = require('./menu');
66
const { createWindow } = require('./window');
77

8+
require('./ipc/server');
9+
810
let mainWin;
911

1012
function initializeApp () {

menu.js

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
1-
const {app, Menu, BrowserWindow} = require('electron');
2-
const path = require('path');
3-
const { createWindow } = require('./window');
1+
const { ipcMain, ipcRenderer } = require('electron');
2+
const consumer = require('./ipc/consumer');
3+
4+
const Menu = require('electron').Menu || require('electron').remote.Menu;
5+
const app = require('electron').app || require('electron').remote.app;
6+
const path = require('path') || require('electron').remote.require('path');
7+
const os = require('os') || require('electron').remote.require('os');
8+
9+
const isMainProcess = typeof ipcMain !== 'undefined';
10+
11+
function exec(commandId, args={}) {
12+
if (isMainProcess) {
13+
consumer(commandId, args);
14+
} else {
15+
ipcRenderer.send('main:command', { commandId, args });
16+
}
17+
}
418

519
const template = [
620
{
@@ -10,18 +24,15 @@ const template = [
1024
label: 'New File',
1125
accelerator: 'CmdOrCtrl+N',
1226
click () {
13-
createWindow({url: `file://${path.join(__dirname, 'index.html?target=https://hackmd.io/new')}`});
27+
exec('createWindow', {url: `file://${path.join(__dirname, 'index.html?target=https://hackmd.io/new')}`})
1428
}
1529
},
1630
{
1731
label: 'New Window',
1832
accelerator: 'CmdOrCtrl+Shift+N',
1933
click () {
20-
createWindow({url: `file://${path.join(__dirname, 'index.html')}`});
34+
exec('createWindow', {url: `file://${path.join(__dirname, 'index.html')}`})
2135
}
22-
},
23-
{
24-
type: 'separator'
2536
}
2637
]
2738
},
@@ -70,8 +81,7 @@ const template = [
7081
label: 'Refresh',
7182
accelerator: 'CmdOrCtrl+R',
7283
click () {
73-
const win = BrowserWindow.getFocusedWindow();
74-
win.webContents.send('web:refresh');
84+
exec('refreshWindow');
7585
}
7686
},
7787
{
@@ -90,13 +100,15 @@ const template = [
90100
submenu: [
91101
{
92102
label: 'Learn More',
93-
click () { require('electron').shell.openExternal('https://hackmd.io') }
103+
click () {
104+
exec('learnMore');
105+
}
94106
}
95107
]
96108
}
97109
]
98110

99-
if (process.platform === 'darwin') {
111+
if (os.platform() === 'darwin') {
100112
template.unshift({
101113
label: app.getName(),
102114
submenu: [

renderer.js

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
1-
const fs = require('electron').remote.require('fs');
2-
const os = require('electron').remote.require('os');
3-
const path = require('electron').remote.require('path');
4-
const {ipcRenderer} = require('electron');
5-
const {BrowserWindow} = require('electron').remote;
6-
const {clipboard} = require('electron');
1+
const { ipcRenderer, remote, clipboard } = require('electron');
2+
const { BrowserWindow } = remote;
73

8-
const SERVER_URL = 'https://hackmd.io';
4+
const fs = remote.require('fs');
5+
const os = remote.require('os');
6+
const path = remote.require('path');
97

10-
const isDarwin = os.platform() === 'darwin';
8+
const ipcClient = require('./ipc/client');
119

12-
const winOption = {
13-
width: 1024,
14-
height: 768
15-
}
10+
const menu = require('./menu');
11+
12+
const SERVER_URL = 'https://hackmd.io';
13+
14+
const isMac = os.platform() === 'darwin';
1615

1716
onload = () => {
17+
/* inject mac specific styles */
18+
if (isMac) {
19+
document.querySelector('navbar').style.paddingLeft = '75px';
20+
document.querySelector('#navbar-container .control-buttons:nth-child(3)').style.display = 'none';
21+
document.querySelector('#navbar-container .more-menu').style.display = 'none';
22+
}
23+
1824
if (window.location.search !== '') {
1925
targetURL = window.location.search.match(/\?target=([^?]+)/)[1];
2026
} else {
@@ -63,6 +69,29 @@ onload = () => {
6369
new Notification('URL copied', { title: 'URL copied', body: webview.getURL() });
6470
}
6571

72+
document.querySelector('#navbar-container .more-menu').onclick = () => {
73+
menu.popup(require('electron').remote.getCurrentWindow());
74+
}
75+
76+
document.querySelector('#navbar-container .minimize-window').onclick = () => {
77+
const win = BrowserWindow.getFocusedWindow();
78+
win.minimize();
79+
}
80+
81+
document.querySelector('#navbar-container .toggle-window').onclick = () => {
82+
const win = BrowserWindow.getFocusedWindow();
83+
if (win.isMaximized()) {
84+
win.unmaximize();
85+
} else {
86+
win.maximize();
87+
}
88+
}
89+
90+
document.querySelector('#navbar-container .close-window').onclick = () => {
91+
const win = BrowserWindow.getFocusedWindow();
92+
win.close();
93+
}
94+
6695
// webview.openDevTools();
6796
});
6897

@@ -73,10 +102,6 @@ onload = () => {
73102

74103
/* handle _target=blank pages */
75104
webview.addEventListener('new-window', (event) => {
76-
new BrowserWindow(
77-
(isDarwin
78-
? Object.assign({}, winOption, {titleBarStyle: 'hidden'})
79-
: winOption)
80-
).loadURL(`file://${path.join(__dirname, `index.html?target=${event.url}`)}`);
105+
ipcClient('createWindow', { url: `file://${path.join(__dirname, `index.html?target=${event.url}`)}` });
81106
});
82107
}

vendor/font-awesome.min.css

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/fonts/FontAwesome.otf

132 KB
Binary file not shown.

0 commit comments

Comments
 (0)